Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

How do git branches work?

Today we are going to work with branches offline to begin to understand them better.

Git cheatsheets

High quality, correct refrences are important to gaining an understanding and being able to use tools well.

We are going to work between the browser and locally in order to simulate scenarios that most often occur in collaboration, but can also occur working alone as well.

Back to the gh-inclass repo

Recall, We can move around and examine the computer’s file structure using shell commands.

Open a new terminal window and navigate to your folder for the course (the one that contains other folders)

cd Documents/inclass/systems/gh-inclass-sp26-brownsarahm/

To confirm our current working directory we print it with pwd

pwd
/Users/brownsarahm/Documents/inclass/systems/gh-inclass-sp26-brownsarahm

next, we check in with git

git status
On branch 2-create-an-about-file
Your branch is ahead of 'origin/2-create-an-about-file' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

First, we talked about this a bit in lab, but the last step we did not do in class last week was git push.

Fixing the fork

the gh CLI has some nice features, it gives you access to GitHub features (PR, Issues, etc) from the terminal. Including opening browser windows to a repo.

We can use it like :

gh repo view --web
X No default remote repository has been set. To learn more about the default repository, run: gh repo set-default --help

please run `gh repo set-default` to select a default remote repository.

However, the first time you use it in a repo that is a fork (all the ones from GitHub classroom are forks) it does not know what URL to go to

It did give us a hint, so we will follow that.

gh repo set-default compsys-progtools/gh-inclass-sp26-brownsarahm
✓ Set compsys-progtools/gh-inclass-sp26-brownsarahm as the default repository for the current directory

Now we try again to open in the browser

gh repo view --web
Opening https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm in your browser.

Git Branches do not sync automatically

Now again check with git. We have confirmed in browser we do not see the new file, this is what git status tells us too.

git status
On branch 2-create-an-about-file
Your branch is ahead of 'origin/2-create-an-about-file' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

we do have it locally, though

ls
about.md	README.md

To send to github, we use push

git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes | 314.00 KiB/s, done.
Total 3 (delta 0), reused 1 (delta 0), pack-reused 0 (from 0)
To https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm.git
   67010e3..a254c24  2-create-an-about-file -> 2-create-an-about-file

In browser, we added our names to the file

The cat comand concatenated or appends to the end the contents of a file to the std out (the terminal output).

cat about.md
git pull
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 957 bytes | 957.00 KiB/s, done.
From https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm
   a254c24..cfd464d  2-create-an-about-file -> origin/2-create-an-about-file
Updating a254c24..cfd464d
Fast-forward
 about.md | 1 +
 1 file changed, 1 insertion(+)

Now, after we did pull the content is there

cat about.md
# Sarah

We made a PR for the about branch and merged it in browser.

Then in the browser the about.md file exists on the main branch.

Back on our local computer, we will go back to the main branch, using git checkout

git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

now we look at the status of our repo:

ls
README.md

the file is missing. It said it was up to date with origin main, but that is the most recent time we checked github only. It’s up to date with our local record of what is on GitHub, not the current GitHub.

This manual control means that someone can break something in one place and you can fix it from another copy, it is an advantage but we have to do a bit of work.

Next, we will update locally, with git fetch

git fetch
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (1/1), 913 bytes | 913.00 KiB/s, done.
From https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm
   67010e3..f6886ba  main       -> origin/main

Here we see 2 sets of messages. Some lines start with “remote” and other lines do not. The “remote” lines are what git on the GitHub server said in response to our request and the other lines are what git on your local computer said.

So, here, it counted up the content, and then sent it on GitHub’s side. On the local side, it unpacked (remember git compressed the content before we sent it). It describes the changes that were made on the GitHub side, the main branch was moved from one commit to another. So it then updates the local main branch accordingly ("Updating 67010e3..f6886ba ").

We can see that if this updates the working directory too:

ls
README.md

no changes yet. fetch updates the .git directory so that git knows more, but does not update our local file system.

It tells us the the branch can be fast forwarded, this is one of the ways that branches can be updated from another branch.

Fast Forward

Before

After:

Fast forward can only happen where there are stictly more commits on the incoming branch. (here the remote branch that we have fetched)

Git Rebase

Rebase changes the base commit of a branch. It works by changing the parent of the first commit that is unique to the current branch and then making new versions of the previous commits on the branch.

Before
After

Git Merge

is one the third option for how to handle it, if we choose --no-rebase it will use merge. Merge instead adds as new commit that contains all of the changes to the new base branch

We can use the fast forward option, so we will with pull

git pull
Updating 67010e3..f6886ba
Fast-forward
 about.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 about.md

This tells us:

Solution to Exercise 1
  • using checkout with a nonexistant branch name causes an error

  • -b creates a branch

  • create is not a git command, so it throws an error

  • git branch creates a new branch, ; lets us run 2 commands at once, checkout switches

With no options or inputs, git branch will list the branches that exist.

git branch
  2-create-an-about-file
  main
* my_branch
  my_branch_checkedoutb

making a new branch locally

We’ve used git checkout to switch branches before. To also create a branch at the same time, we use the -b option.

git checkout -b fun_fact
Switched to a new branch 'fun_fact'

we can view the commit history with git log

git log

branches are like pointers, they point to a commit.

commit f6886babaa283a8238632930bf2cca9121fc274b (HEAD -> fun_fact, origin/main, origin/HEAD, my_branch_checkedoutb, my_branch, main)
Merge: 67010e3 cfd464d
Author: Sarah Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 19:57:53 2026 +0200

    Merge pull request #5 from compsys-progtools/2-create-an-about-file
    
    create empty about

commit cfd464dc22568fcff6aa302fbd6025e44b7262ac (origin/2-create-an-about-file, 2-create-an-about-file)
Author: Sarah Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 12:52:14 2026 -0500

    Update about.md

commit a254c24301bc02c9624726573e902c8ffe437a0b
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Thu Jan 29 13:37:03 2026 -0500

    create empty about

commit 67010e313ae6a25d88b4d704769d1c46e6680d35
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date:   Thu Jan 29 17:58:39 2026 +0000

    add online IDE url

commit 3990d7285e7ec3390d9069fda3f37e2231f78664
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date:   Thu Jan 29 17:58:35 2026 +0000

    Setting up GitHub Classroom Feedback

commit 05b77103b9878a3b14fb0a2ca58bee76fdf56732 (origin/feedback)
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date:   Thu Jan 29 17:58:35 2026 +0000

    GitHub Classroom Feedback

commit 9b61eadc429770d40b30f3a51af3ef69dc843e35
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date:   Thu Jan 29 17:15:07 2026 +0000

    Initial commit
git log
commit f6886babaa283a8238632930bf2cca9121fc274b (HEAD -> fun_fact, origin/main, origin/HEAD, my_branch_checkedoutb, my_branch, main)
Merge: 67010e3 cfd464d
Author: Sarah Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 19:57:53 2026 +0200

    Merge pull request #5 from compsys-progtools/2-create-an-about-file
    
    create empty about

commit cfd464dc22568fcff6aa302fbd6025e44b7262ac (origin/2-create-an-about-file, 2-create-an-about-file)
Author: Sarah Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 12:52:14 2026 -0500

    Update about.md

commit a254c24301bc02c9624726573e902c8ffe437a0b
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Thu Jan 29 13:37:03 2026 -0500

    create empty about

we can use the nano text editor. nano is simpler than other text editors that tend to be more popular among experts, vim and emacs. Getting comfortable with nano will get you used to the ideas, without putting as much burden on your memory. This will set you up to learn those later, if you need a more powerful terminal text editor.

nano about.md

this opens the nano program on the terminal. it displays reminders of the commands at the bottom of th screen and allows you to type into the file right away.

Add any fun fact on the line below your content. Then, write out (save), it will prompt the file name. Since we opened nano with a file name (about.md) specified, you will not need to type a new name, but to confirm it, by pressing enter/return.

cat about.md
# Sarah

I started at URI in 2020
git status
On branch fun_fact
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   about.md

no changes added to commit (use "git add" and/or "git commit -a")

This is very similar to when we checked after creating the file before, but, notice a few things are different.

We will add it to stage

git add .

then check the status again

git status
On branch fun_fact
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   about.md

we see that it is staged and git tells us how to undo this if we want

and commit

git commit -m "add first fun fact"
[fun_fact 21adcda] add first fun fact
 1 file changed, 2 insertions(+)

and then push

git push
fatal: The current branch fun_fact has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin fun_fact

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

It cannot push, because it does not know where to push, like we noted above that it did not comapre to origin, that was beecause it does not have an “upstream branch” or a corresponding branch on a remote server. It does not work at first because this branch does not have a remote.

To fix it, we do as git said.

git push --set-upstream origin fun_fact
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 295 bytes | 295.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote: 
remote: Create a pull request for 'fun_fact' on GitHub by visiting:
remote:      https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm/pull/new/fun_fact
remote: 
To https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm.git
 * [new branch]      fun_fact -> fun_fact
branch 'fun_fact' set up to track 'origin/fun_fact'.

This time the returned message from the remote includes the link to the page to make a PR. We are not goign to make the PR though

Merge conflicts

We are going to intentionally make a merge conflict here.

This means we are learning two things:

Merge conflicts are not always because someone did something wrong; it can be a conflict in the simplest term because two people did two types of work that were supposed to be independent, but turned out not to be.

Make conflicting edits

First, in your browser edit the about.md file on the fun_fact branch to have a second fun fact.

Then edit it locally to also have 2 fun facts.

nano about.md

Now, we can visually compare, the local content:

cat about.md
# Sarah

I started at URI in 2020
I won NSF CAREER in 2025

And on GitHub:

about.md
# Sarah

I started at URI in 2020
I skied competitively in HS

Git won’t let us lose work

now that we have edited in both places let’s pull.

git pull
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 1 (delta 1), pack-reused 2 (from 1)
Unpacking objects: 100% (3/3), 960 bytes | 960.00 KiB/s, done.
From https://github.com/compsys-progtools/gh-inclass-sp26-brownsarahm
   21adcda..7579d39  fun_fact   -> origin/fun_fact
Updating 21adcda..7579d39
error: Your local changes to the following files would be overwritten by merge:
	about.md
Please commit your changes or stash them before you merge.
Aborting

It does not work because we have not committed.

This is helpful beacause it prevents us from losing any work.

git status
On branch fun_fact
Your branch is behind 'origin/fun_fact' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   about.md

no changes added to commit (use "git add" and/or "git commit -a")

Now we will add it

git add .

and see the status

git status
On branch fun_fact
Your branch is behind 'origin/fun_fact' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   about.md

and commit:

we are going to do it without the -m on purpose here to learn how to fix it

git commit

What this is doing is adding a temporary file with the commit message that git can use to complete your commit.

then it will tell us we made a commit

[fun_fact 16d117e] add another fun fact
 1 file changed, 1 insertion(+)

Now we can look again at where our branch pointers are.

git log
commit 16d117e2688b8233db6d1d39a84bba02b698ce82 (HEAD -> fun_fact)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 13:34:41 2026 -0500

    add another fun fact

commit 21adcda986999bfedba045b1d9e4ecac3efe2a6a
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 13:26:33 2026 -0500

    add first fun fact

commit f6886babaa283a8238632930bf2cca9121fc274b (origin/main, origin/HEAD, my_branch_checkedoutb, my_branch, main)
Merge: 67010e3 cfd464d
Author: Sarah Brown <brownsarahm@uri.edu>
Date:   Tue Feb 3 19:57:53 2026 +0200

    Merge pull request #5 from compsys-progtools/2-create-an-about-file
    
    create empty about

Pull to combine

so we try again

git pull
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Now it cannot work because the branches have diverged. This illustrates the fact that our two versions of the branch fun_fact and origin/fun_fact are two separate things.

Solve divergent branches

git gave us some options, we will use rebase which will apply our local commits after the remote commits.

git pull --rebase
Auto-merging about.md
CONFLICT (content): Merge conflict in about.md
error: could not apply 16d117e... add another fun fact
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Could not apply 16d117e... # add another fun fact

Now it tells us there is a conflict.

We have to fix the conflict manually because there were 2 different edits to the same line of the same file, git cannot tell which one we want.

We will fix it next class, but let’s look at how it marks up the file for now.

cat about.md
# Sarah

<<<<<<< HEAD
I started at URI in 2020  
I skied competitively in HS
=======
I started at URI in 2020
I won NSF CAREER in 2025
>>>>>>> 16d117e (add another fun fact)

Prepare for Next Class

Examine an open source software project and fill in the template below in a file called software.md in your kwl repo on a branch that is linked to the prepare issue. You do not need to try to understand how the code works for this exercise, but instead focus on how the repo is set up, what additional information is in there beyond the code. You may pick any active mature open source project, meaning a project with recent commits, over 50 commits, active PRs and issues, multiple contributors. In class we will have a discussion and you will compare what you found with people who examined a different project. Coordinate with peers (eg using the class discussion or in lab time) to look at different projects in order to discuss together in class.

## Software Reflection

Project : <markdown link to repo>

## README

<!-- what is in the readme? how well does it help you  -->

## Contents 

<!-- denote here types of files (code, what languages, what other files) -->


## Automation

<!-- comment on what types of stuff is in the .github directory -->

## Documentation

<!-- what support for users? what for developers? code of conduct? citation? -->

## Hidden files and support
 <!-- What type of things are in the hidden files? who would need to see those files vs not? -->

Some open source projects if you do not have any you are familiar with:

Badges

Review
Practice
  1. Review the notes from today

  2. Read more details about git branches(you can also use other resources) add branches.md to your KWL repo and describe how branches work, in your own words. Include one question you have about branches or one scenario you think they could help you with.

Experience Report Evidence

You need to have a merge conflict in your gh-inclass repo

Questions After Today’s Class

What other usues does nano have?

It is a text editor, it edits plain text files. It has a other features for that, but bash programs tend to be single purpose. It’s considered good design. We’ll learn more about this and other parts of unix philosophy soon.

How do I use the git login by token in bash?

The PAT token can be used like a password. It is not very secure though, so not recommended.

See the docs for more details

How do we manage a merge conflict?

We will finish this up next class!

Can you finish a badge or issue entirely in the terminal, or is the github website needed for things?

For github, specifically, they have made the gh CLI (that we used to login) so you can do almost everything in the terminal. The main things that can only be done in the browser or with more verbose, less user friendly, API calls are managing settings and thigns.

Basically all regular day to day developer tasks can be done from the terminal. This allows skilled developers to work way faster (using a mouse is slow) and it enables thigns that need to happen alot to be reliably automated by scripting. It also enables development of LLM-agents that can do a lot of things. These agents that can access thing by scripting will be more reliable than “computer use” agents that have do to mouse-based tasks beacuse the tasks are more concrete, better suited to LLM strengths (text generation) and training data is easier to create(scripts people make for themselves can be used to train the agent instead of hiring low-skilled people or surveillance of people at work).