Setting up & using git

This session will cover:

Setting up git on your computer

MacOSX and Linux computers all come with git pre-installed, but it is not always directly usable. The best way to test if git is ready to use is at the command line:

git --version
# git version 2.39.3

It should return something like above. If you get an error, you will have to install git

Installing git

You can download and install git from here: https://git-scm.com/install/ and follow the instructions according to your Operating System.

Depending on your OS, you might have to follow different steps to install git on your computer:

You can keep the options to default during the installation, until you reach Configuring the terminal emulator to use with Git Bash -> be sure Use MinTTY is selected. This will install both git and a set of useful command-line tools using a trimmed down Bash shell.

Depending on the version, you might have to run a few commands from the terminal. Please refer to the README.txt that comes with the download regarding the exact steps to follow.

Setting up your git identity

Before you start using git on any computer, you should set your identity on your system, as every snapshot of files is associated with the user who implemented the modifications to the file(s).

Open the Terminal or git bash and then type the following commands.

Setup your profile

At the command line

If you are not sure if you have already set your git identity you can check this running this command:

git config --global --list

If your identity is not set yet, you need to provide your name and email (we recommend to use the same email as used when setting your GitHub account):

git config --global user.name "your Full Name"
git config --global user.email "your Email"

Edit your git config file directly in your text editor:

git config --global --edit

Set your default text editor (e.g. nano, notepad, code, etc.):

git config --global core.editor nano
TipText editor for Windows users

Outside of Git Bash, notepad is a good default:

git config --global core.editor notepad
CautionProblem with any of those steps?

Check out Jenny Brian Happy git trouble shooting section

Clone a repository

Tip

If you do not have your favorite-desserts GitHub repository, please follow those steps

Navigate to the folder (e.g cd ~/Documents) where you want to save your repository and run the following command (replace <your-github-username> with your actual GitHub username):

git clone https://github.com/<your-github-username>/favorite-desserts.git

You should have a new folder on your local machine named favorite-desserts after your repository :

ls

Go inside the repository:

cd favorite-desserts
ls -al
NoteIn PowerShell

In PowerShell you can run ls or dir to list the content of a directory, and cd to change directory. To replicate the ls -al command, you can run ls -Force or dir -Force to show all files, including hidden ones.

This should return the exact same content that is currently on GitHub!

Tracking your work

Let’s start tracking our work using git. For this exercise, we want to accomplish the following:

  1. Create a new Python script called desserts.py and add it to our repository.
  2. Copy and paste the code provided in the desserts.py file and save the change as a commit.
  3. Add a new dessert to the csv list and save the change as a commit.
  4. Edit the main function in the script to include a destination path for the csv file and save the change as a commit.

Adding a new file to the repository

From the command line, create a new empty file called desserts.py:

touch desserts.py
NoteIn PowerShell

touch is not available in PowerShell. Use New-Item instead:

New-Item desserts.py

Next, copy and paste the following code into the desserts.py file (use nano or any text editor you prefer):

import csv

def read_csv(file_path: str) -> list[dict]:
    with open(file_path, mode='r') as file:
        csv_reader = csv.DictReader(file)
        data = [row for row in csv_reader]
    return data

def add_dessert(data: list[dict], rank: int, dessert: str) -> list[dict]:
    if any(row['dessert'] == dessert for row in data):
        print(f"{dessert} is already in the list. No changes made.")
        return data

    for row in data:
        if int(row['rank']) >= rank:
            row['rank'] = str(int(row['rank']) + 1)

    data.append({'rank': str(rank), 'dessert': dessert})
    data.sort(key=lambda x: int(x['rank']))

    return data
    
def to_csv(data: list[dict], file_path: str) -> None:
    with open(file_path, mode='w', newline='') as file:
        fieldnames = ['rank', 'dessert']
        writer = csv.DictWriter(file, fieldnames=fieldnames,
                                lineterminator='\n')
        writer.writeheader()
        for item in data:
            writer.writerow(item)

def main(rank: int, dessert: str) -> None:
    """Read the iconic desserts CSV, 
    insert a dessert at the given rank, 
    and save the updated list.

    Args:
        rank (int): Rank at which to insert the dessert.
        dessert (str): Name of the dessert to add.
    """
    data = read_csv('iconic_desserts.csv')
    new_data = add_dessert(data, rank, dessert)
    to_csv(new_data, 'iconic_desserts.csv')
    print(f"Added {dessert} at rank {rank}.")

if __name__ == "__main__":
    # Add a new dessert to the list at rank 37
    main(37, 'Tiramisu')

The code defines a Python script that manages a list of desserts stored in a CSV file. It includes functions to read the CSV file, add a new dessert to the list while maintaining the correct ranking, and write the updated list back to the CSV file. The main function demonstrates how to use these functions by adding “Tiramisu” at rank 37 in the list of iconic desserts.

Check git workspace status

Next, we can use git to check the status of our repository by running the following command:

git status

The output should be similar to this:

On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    desserts.py

nothing added to commit but untracked files present (use "git add" to track)

Add the file to the staging area

The list of untracked files includes all the files that are in your repository but are not being tracked by git. To start tracking the desserts.py file, we need to add it to the staging area:

git add desserts.py

Now, if we check the status again, we should see that the desserts.py file is now being tracked:

git status

On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   desserts.py

Committing the changes

At this moment, git is tracking the desserts.py file, but the changes we made to the file are not “saved” in the git history yet. This is called a commit, which is a snapshot of the state of the file(s) at a given moment in time. To create a commit, we need to run the following command:

git commit -m "add desserts.py script"

This will create a new commit with the message “add desserts.py script”. The -m flag is used to specify the commit message. You can use any message you want, but it should be descriptive of the changes you made in that commit.

Tracking changes to data

The script we just created is designed to include a new dessert in the iconic_desserts.csv file. Running the script will result in a new dessert (Tiramisu) being added to the list at rank 37, and the ranks of the other desserts being updated accordingly. Let’s run the script to see how it works:

Before running the script, confirm which Python command works on your machine:

python --version

If you get an error, try:

python3 --version
py -3 --version

Use the command that returns a Python 3 version to run the script.

If none of the above commands work, you will need to install Python on your machine. You can download it from https://www.python.org/downloads/ and follow the instructions for your operating system.

python desserts.py

Some common issues that might arise when running the script and how to solve them:

  • command not found: python: Run python --version first; if needed use python3 desserts.py (macOS/Linux) or py -3 desserts.py (Windows).
  • FileNotFoundError: [Errno 2] No such file or directory: ‘iconic_desserts.csv’: Run the command from the folder that contains both files.

If the output shows the message Added Tiramisu at rank 37., then the script ran successfully.

We can use git to see what have changed in the iconic_desserts.csv file by using the diff command:

git diff iconic_desserts.csv

The resulting output shows the differences between the current and the previous version of the file. Lines that start with a - were removed, and those that start with a + were added. The output should look something like this:

diff --git a/iconic_desserts.csv b/iconic_desserts.csv
index 351fb57..b80e86b 100644
--- a/iconic_desserts.csv
+++ b/iconic_desserts.csv
@@ -35,8 +35,9 @@ rank,dessert
 34,Chess pie
 35,Sour cream pound cake
 36,Key lime pie
-37,Cherry pie
-38,Seven-layer bars
-39,Coconut cake
-40,Brownies
-41,Blondies
+37,Tiramisu
+38,Cherry pie
+39,Seven-layer bars
+40,Coconut cake
+41,Brownies
+42,Blondies
NoteCommit changes

Now is your turn to commit the changes made to the iconic_desserts.csv file. Follow the same steps as before and use the following commit message: “add Tiramisu to the list of iconic desserts”.

git add iconic_desserts.csv
git commit -m "add Tiramisu to the list of iconic desserts"

Control the repository history

So far, we have made changes incrementally by adding and committing new changes to the repository. However, we can also revert to a previous state of the repository. Let’s explore the current history of our repository first by using the log command:

git log

The output should look something like this:

commit a3a7278bc511ac1047d722bb9833773fd5636a90 (HEAD -> main)
Author: ...
Date:   Tue Apr 14 15:39:59 2026 -0700

    add Tiramisu to the list of iconic desserts

commit 227d6cba9fa442459bd4c22054fa640600db8cb4
Author: ...
Date:   Tue Apr 14 15:13:59 2026 -0700

    add desserts.py script

commit 14a46c09a8dde829ea44bfe5d02492e0b926b74d (origin/main, origin/HEAD)
Author: ...
Date:   Tue Apr 14 14:52:37 2026 -0700

    Add iconic_desserts.csv

commit 7107af1488152b062ef9c3e60bb54134a6320fe4
Author: ...
Date:   Tue Apr 14 14:50:23 2026 -0700

    Adding Your's favorite dessert

commit 8fe3ad4ca5c5ad7db4b1ba19e03177407a70bf51
Author: ...
Date:   Tue Apr 14 14:39:28 2026 -0700

    Initial commit
  • Each commit is identified by a unique hash (e.g., a3a7278bc511ac1047d722bb9833773fd5636a90).
  • The HEAD pointer indicates the current commit that your repository is on.
  • The Author and Date fields show who made the commit and when.
  • The commit message (e.g., “add Tiramisu to the list of iconic desserts”) describes the changes made in that commit.
  • The origin/main indicates that the commit is also present in the remote repository on GitHub.

To avoid having git log cover your entire terminal screen, you can limit the number of commits that Git lists by using -N, where N is the number of commits that you want to view. For example, if you only want information from the last commit you can use:

git log -1

---

commit a3a7278bc511ac1047d722bb9833773fd5636a90 (HEAD -> main)
Author: ...
Date:   Tue Apr 14 15:39:59 2026 -0700

    add Tiramisu to the list of iconic desserts

Another option to reduce the quantity of information is using the --oneline option:

git log --oneline

---

a3a7278 (HEAD -> main) add Tiramisu to the list of iconic desserts
227d6cb add desserts.py script
14a46c0 (origin/main, origin/HEAD) Add iconic_desserts.csv
7107af1 Adding Your's favorite dessert
8fe3ad4 Initial commit

Restore iconic_desserts.csv to the previous state

Our current workflow has an issue: we are altering the iconic_desserts.csv file directly, which means that if we make a mistake, we might lose the original content of the file. Let’s start by restoring the iconic_desserts.csv file to the previous state before we added Tiramisu.

To achieve this, we can use the checkout command to restore the file to the state it was in the previous commit:

git checkout HEAD~1 iconic_desserts.csv

---
# Success message should be similar to this:
Updated 1 path from a4090b9

Usually the way to revert changes depends if the file is staged, already commited, if is currently modified, etc. Depending the case, you might have to use different commands, such as git restore, git reset, git revert, etc. For more information on how to revert changes in different scenarios, check out the Git documentation, particularly the commands under the section “Basic Snapshotting” and “Patching”.

What we’re doing here is telling git to restore the iconic_desserts.csv file to the state it was in the previous commit (indicated by HEAD~1). After running this command, the iconic_desserts.csv file should be back to its original state before we added Tiramisu and moved to the staging area. Let’s commit this change to the repository:

git commit -m "restore iconic_desserts.csv to its original state"

Edit desserts.py

Open the desserts.py file and edit the main function so it looks like this:

def main(rank: int, dessert: str, destination_path: str) -> None:
    """Read the iconic desserts CSV, 
    insert a dessert at the given rank, 
    and save the updated list.

    Args:
        rank (int): Rank at which to insert the dessert.
        dessert (str): Name of the dessert to add.
        destination_path (str): Path to save the updated CSV file.
    """
    data = read_csv('iconic_desserts.csv')
    new_data = add_dessert(data, rank, dessert)
    to_csv(new_data, destination_path)
    print(f"Added {dessert} at rank {rank}.")

if __name__ == "__main__":
    # Add a new dessert to the list at rank 37
    main(37, 'Tiramisu', 'updated_iconic_desserts.csv')

Save the file and run git diff to see the changes you made:

git diff desserts.py

# The output should look something like this:
diff --git a/desserts.py b/desserts.py
index 792959f..a199a68 100644
--- a/desserts.py
+++ b/desserts.py
@@ -29,7 +29,7 @@ def to_csv(data: list[dict], file_path: str) -> None:
         for item in data:
             writer.writerow(item)
 
-def main(rank: int, dessert: str) -> None:
+def main(rank: int, dessert: str, destination_path: str) -> None:
     """Read the iconic desserts CSV, 
     insert a dessert at the given rank, 
     and save the updated list.
@@ -37,12 +37,13 @@ def main(rank: int, dessert: str) -> None:
     Args:
         rank (int): Rank at which to insert the dessert.
         dessert (str): Name of the dessert to add.
+       destination_path (str): Path to save the updated CSV file.
     """
     data = read_csv('iconic_desserts.csv')
     new_data = add_dessert(data, rank, dessert)
-    to_csv(new_data, 'iconic_desserts.csv')
+    to_csv(new_data, destination_path)
     print(f"Added {dessert} at rank {rank}.")
 
 if __name__ == "__main__":
     # Add a new dessert to the list at rank 37
-    main(37, 'Tiramisu')
+    main(37, 'Tiramisu', 'updated_iconic_desserts.csv')

Now, add the changes to the staging area and commit them to the repository:

git add desserts.py
git commit -m "edit main function to include destination path for csv file"

Wrapping up

  1. Run the desserts.py script again to add a new dessert to the list and save the updated list in a new file called updated_iconic_desserts.csv.
  2. Use git to track the changes to the updated_iconic_desserts.csv file and commit those changes to the repository with the message “add Tiramisu to the updated list of iconic desserts”.
python desserts.py
git add updated_iconic_desserts.csv
git commit -m "add Tiramisu to the updated list of iconic desserts"

At the end, the history of your repository should look something like this:

git log --oneline

---

cf47aa1 (HEAD -> main) add Tiramisu to the updated list of iconic desserts
6d7cbbf edit main function to include destination path for csv file
ab19fd9 restore iconic_desserts.csv to its original state
a3a7278 add Tiramisu to the list of iconic desserts
227d6cb add desserts.py script
14a46c0 (origin/main, origin/HEAD) Add iconic_desserts.csv
7107af1 Adding Your's favorite dessert
8fe3ad4 Initial commit


UCSB library logo

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License