You will not typically use them on a day to day basis, but they are a good way to see what happens at the interim steps and make sure that you have the right understanding of what git does.
A correct understanding is essential for using more advanced features
I had an error in courseutils and did not get it fixed in time to use your action scripts.
Solution to Exercise 1
cspt getassignment --date 2025-10-07 --type review | gh issue create --title "Review 2025-10-07" --body-file - --label reviewcspt getassignment --date 2025-10-07 --type practice | gh issue create --title "Pracitce 2025-10-09" --body-file - --label practiceWhile there is of course some content that we want you to know after this course, my goal is also to teach you process, by modeling it.
No one will every know all of the things but you can be fast or slow at finding answers.
And you can find correct answers, incorrect answers, or looks-okay-but-you-will-regret-this-later answers.
you do not want to become the colleague that everyone regrets working with
Today’s Questions¶
What are references?
How can can I release and share my code?
How else can git help me?
What does git status do?¶
compares the working directory to the current state of the active branch
we cansee the working directory with:
lswe can see the active branch in the
HEADfilewhat is its status?
Recall that we:
created a blob objct directly
creataed a file
hashed the file, to create its blob object
added the file to the index
wrote the tree
created a commit
My goal is that you get good at quickly finding correct answers.
Large language models will not do that for you.
Tags¶
branches are not git objects, they are references.
We can see that by where they are stored.
cd test/find .git/objects -type f.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547
.git/objects/da/01135f2fb02e9b53c200708863df82f0daa50c
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30these 5 git objects refer to:
“test content”
version 1 of test.txt
version 2 of test.txt
the tree
the commit
there is no object for the branch we have, main
branches are only stored in the refs folder
ls .git/refs/heads tagsthe heads folder has only our one branch:
ls .git/refs/heads/mainwhich is a pointer to the commit via its hash
cat .git/refs/heads/mainda01135f2fb02e9b53c200708863df82f0daa50cand we see the hash from the main branch
The other type of git reference is called a tag. There are two types of tags:
a lightweight tag is like a branch that does not move
an annotated tag is a git object, like a commit almost.
View tags¶
The command git tag will list the current tags when used with no options or arguments.
git tagwe have none so far, they don’t get automatically created
we can also check manually
ls .git/refs/tags/Lightweight tags¶
Now, to make a tag we use git tag <name of tag> to create a lightweight tag
git tag v1and see what it did
git tagv1also manually how it implemented that
ls .git/refs/tags/v1and check if it made an object:
find .git/objects -type f.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547
.git/objects/da/01135f2fb02e9b53c200708863df82f0daa50c
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30it did not! same 5 as before
we can see the file
cat .git/refs/tags/v1da01135f2fb02e9b53c200708863df82f0daa50cthis hash is the same as we saw above for main
the lightweight tag is just like a branch, another pointer to the commit.
The difference is that this does not move when we create new commits, so this is like a shortcut to a specific commit.
Annotated tags¶
if we use the -a flag we get an annotated tag and we can add text to it with -m (like for a commit)
git tag -m 'annotated tag' -a v1.0.1again no output
let’s check the object database:
find .git/objects -type f1 2 3 4 5 6.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547 .git/objects/da/01135f2fb02e9b53c200708863df82f0daa50c .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 .git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 .git/objects/73/0b071fd22aab21ddd8445522d4c4d49b9a3cc2 .git/objects/83/baae61804e65cc73a7201a7252750c76066a30
another object! that 730b was not there before
let’s inspect this too.
it creates a file in the tags folder
cat .git/refs/tags/v1.0.1730b071fd22aab21ddd8445522d4c4d49b9a3cc2this has that new object hash we did not have before. So the lightweight tag only points to a commit, but this created its own object to point to.
we can inspect that too:
git cat-file -p 730bobject da01135f2fb02e9b53c200708863df82f0daa50c
type commit
tag v1.0.1
tagger Sarah M Brown <brownsarahm@uri.edu> 1760029591 -0400
annotated tagwe see that it points to the commit hash and has information about the type, the name of the tag, author and the message we set.
git cat-file -t 730btagWe can look at how tags are represented on github in another repository.
Tags enable releases, where are defined on github as:
Releases are deployable software iterations you can package and make available for a wider audience to download and use.
We can create a relese for the tag we made
Making a second manual commit¶
git statusOn branch main
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: test.txt
no changes added to commit (use "git add" and/or "git commit -a")we can confirm we have this file already a blob for the current version:
git cat-file -p 0c1eversion 1
version 2then we need the full hash to make the tree so lets output the object list
find .git/objects -type f.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547
.git/objects/da/01135f2fb02e9b53c200708863df82f0daa50c
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579
.git/objects/73/0b071fd22aab21ddd8445522d4c4d49b9a3cc2
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30again, we update the index
git update-index --add --cacheinfo 100644 \
> 0c1e7391ca4e59584f8b773ecdbbb9467eba1547error: option 'cacheinfo' expects <mode>,<sha1>,<path>The first time I forgot the file name so we get an error saying that --cacheinfo requires 3 inputs, but I had only provded two.
we try again with the file name:
git update-index --add --cacheinfo 100644 0c1e7391ca4e59584f8b773ecdbbb9467eba1547 test.txtthe
\lets us wrap onto a second line.this the plumbing command
git update-indexupdates (or in this case creates an index, the staging area of our repository)the
--addoption is because the file doesn’t yet exist in our staging area (we don’t even have a staging area set up yet)--cacheinfobecause the file we’re adding isn’t in your directory but is in the database.in this case, we’re specifying a mode of 100644, which means it’s a normal file.
then the hash object we want to add to the index (the content) in our case, we want the hash of the first version of the file, not the most recent one.
finally the file name of that content
we can confirm this worked with git status
git statusOn branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: test.txtNow we can write the tree, which we need since commits point to trees.
git write-tree258231c1cee8048eef3a8057cfbdab76261277c6For any commit that is not the first, we also need the parent hash. we have many ways we could find that, but we will use log this time.
git logcommit da01135f2fb02e9b53c200708863df82f0daa50c (HEAD -> main, tag: v1.0.1, tag: v1)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Tue Oct 7 13:15:48 2025 -0400
first commitalso note that the tags we made are visible here
Now we can make the commit, from that tree, with parent da01
echo "second commit" | git commit-tree 2582 -p da01You need to use your first commit hash, not mine
ae53600b5026c32ce0985fa9f31922db02fa2328We have not yet done all of the steps that git commit would do. What step is missing, can you do it?
where is the HEAD pointer currently?
We need to write the hash of the second commit to the main file to put that commit on the main brach or to another file to make a new branch (and then set HEAD to that branch)
Stashing¶
Imagine you have worked on something part way, but not finished it, so you do not want to make a commit yet, but you need to switch and work on something else.
let’s create such a scenario in our github inclass repo
cd ../gh-inclass-fa25-brownsarahm/git statusOn branch organization
Your branch is up to date with 'origin/organization'.
nothing to commit, working tree cleanWe will add some new work to the README
echo " document new features " >> README.mdgit statusOn branch organization
Your branch is up to date with 'origin/organization'.
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: README.md
no changes added to commit (use "git add" and/or "git commit -a")If we want to switch branches now,
git checkout mainerror: Your local changes to the following files would be overwritten by checkout:
README.md
Please commit your changes or stash them before you switch branches.
Abortingwe get an error
this is git protecting you
git checkout main would:
read the
.git/refs/heads/mainfileread the commit at that hash
use the tree for that commit and write files reading from the blob objects and to the file names in the tree
upate the HEAD pointer
this would include writing the README with the content as of our last commit on the main branch, and over writing the current version, so we would lose anything that has not been commited.
git stash
stores temporary changes without making a commit so that we can come back to them.
git stashSaved working directory and index state WIP on organization: e899a0e begin reorgwe can see what we have stashed:
git stash liststash@{0}: WIP on organization: e899a0e begin reorgnow we can switch
git checkout mainSwitched to branch 'main'
Your branch is up to date with 'origin/main'.and apply the changes
git stash applyAuto-merging README.md
CONFLICT (content): Merge conflict in README.md
On branch main
Your branch is up to date with 'origin/main'.
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: README.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
.secret
no changes added to commit (use "git add" and/or "git commit -a")we got a merge conflict, but that is okay
we can fix it
nano README.mdthen add and commit
git add README.mdgit commit -m 'doc new feats'[main ff9fb6c] doc new feats
1 file changed, 23 insertions(+)git statusOn branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
Untracked files:
(use "git add <file>..." to include in what will be committed)
.secret
nothing added to commit but untracked files present (use "git add" to track)Git can help with Debugging¶
blame tells us who and when each line of a file was last changed.
git blame README.md99f86bf7 (Sarah M Brown 2025-09-11 13:41:24 -0400 1) # GitHub practice
99f86bf7 (Sarah M Brown 2025-09-11 13:41:24 -0400 2)
99f86bf7 (Sarah M Brown 2025-09-11 13:41:24 -0400 3) test
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 4)
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 5) today is rainy
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 6) |file | contents |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 7) > | --| -- |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 8) > | abstract_base_class.py | core abstract classes for the project |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 9) > | helper_functions.py | utitly funtions that are called by many classes |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 10) > | important_classes.py | classes that inherit from the abc |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 11) > | alternative_classes.py | classes that inherit from the abc |
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 12) > | LICENSE.md | the info on how the code can be reused|
ff9fb6ce (Sarah M Brown 2025-10-09 13:24:28 -0400 13) > | CONTRIBUTING.md | instructions for how people can contribute to the project|we can also view this with annotation and visually in GitHub
git will help you do a binary search to find what commit introduced a bug.
we have to tell it to start, then tell it that the current commit is bad, then tell it the last good commit (or a reference to it)
git bisect start
git bisect bad
git biset good <ref>To do this we need to have to tell it what commit was good, this is one of the reasons that using tags can be helpful
there are multiple ways to refer to a point in the history
First let’s choose a point to use as our last good commit by scanning the previous commits.
git logcommit ff9fb6ce0be3e0291dc34978c9e119bb94f79269 (HEAD -> main)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Oct 9 13:24:28 2025 -0400
doc new feats
commit 11017a59088d4a0b880f770f15fab8c9e086a789 (origin/main, origin/HEAD, mybranchcheckedoutb, my_branch)
Merge: c8f4926 99f86bf
Author: Sarah Brown <brownsarahm@uri.edu>
Date: Tue Sep 16 19:51:36 2025 +0300
Merge pull request #2 from compsys-progtools/1-add-a-readme
create a readme closes #1
commit 99f86bf7112debc934e7fa4504232a48266d90e4 (origin/1-add-a-readme, 1-add-a-readme)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Sep 11 13:41:24 2025 -0400
create a readme closes #1
commit c8f4926313ba8f6c5bfad3857b7479a666328e6d
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date: Thu Sep 11 14:49:01 2025 +0000
Initial commitWe will start git bisect first, this is our search for the “bad commit”
git bisect startstatus: waiting for both good and bad commitsNow, lets tell it that the current commit is bad, this reprsents that we just rcevied the bug report.
git bisect badstatus: waiting for good commit(s), bad commit knownnow we get the updated status
next we tell it what was the last known, not necessarily the last, good commit. We’ll use the about branch commit. This would represent a case where maybe we switched to to that branch locally, ran a test for the the new bug and it passed.
git bisect good c8f4Bisecting: 0 revisions left to test after this (roughly 1 step)
[11017a59088d4a0b880f770f15fab8c9e086a789] Merge pull request #2 from compsys-progtools/1-add-a-readmeThen we check each commit it checkout for us and label it as good or bad by seeing if the budg exists there.
git bisect badBisecting: 0 revisions left to test after this (roughly 0 steps)
[99f86bf7112debc934e7fa4504232a48266d90e4] create a readme closes #1git bisect bad99f86bf7112debc934e7fa4504232a48266d90e4 is the first bad commit
commit 99f86bf7112debc934e7fa4504232a48266d90e4 (HEAD, origin/1-add-a-readme, 1-add-a-readme)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Sep 11 13:41:24 2025 -0400
create a readme closes #1
README.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 README.mdcd ../test/Prepare for Next Class¶
Take a few minutes to think what you know about hashing and numbers. Create hash_num_prep.md with two sections:
## Hashingwith a few bullet points summarzing key points about hashing, and## Numberswith what types of number representations you know.start commenting/expressing interest on build/explore ideas if you plan to do any
Badges¶
Review the notes from today
Create tagtypeexplore.md with the template below. Determine how many of the tags in the course website are annotated vs lightweight using. (You may need to use
git pull --tagsin your clone of the course website)
# Tags
<!-- short defintion/description in your own words of what a tag is and what it is for -->
## Inspecting tags
Course website tags by type:
- annoted:
- lightweight: Review the notes from today
Use git bisect to find the first bad commit in the toy bug repo, save the command history and the bad commit hash to git_debug.md
Determine how many of the tags in the course website are annotated vs lightweight using. (You may need to use
git pull --tagsin your clone of the course website)
# Tags
<!-- short defintion/description in your own words of what a tag is and what it is for -->
## Comparing tag types
<!-- include your experiment terminal history and interpretation -->
## Inspecting tags
Course website tags by type:
- annoted:
- lightweight:
<!-- include lists of tags for each type -->