12. Why did we learn the plubming commands?#
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
While 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.
Important
My goal is that you get good at quickly finding correct answers.
12.1. When is the blob created?#
First lets add some content to revise a file in our github inclass repos
echo "a sentence" >> about.md
and then use git status to check the repo
git status
On branch main
Your branch is up to date with 'origin/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: about.md
no changes added to commit (use "git add" and/or "git commit -a")
at this point file is changed, but it has only been changed in the working directory.
git does not run in the background automatically.
We can use find
to inspect as we have, with wc -l
to count the objects.
find .git/objects/ -type f | wc -l
36
we start with 36
Now we add the file to the staging area
git add .
and count the objects again
find .git/objects/ -type f | wc -l
37
and we see it increased. So the blob object is created when we stage the file.
This is how we can have a file that is both staged for commit and not staged for commit.
Right now we have a version of the file that has been previously hashed and committed at various times, and the version that is both edited locally and hashed and stored for a future commit.
Next we will edit the file again.
echo "a sentence agian" >> about.md
and check the status again
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)
modified: about.md
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
Now there are 3 versions of this file encountered by git status
(active, there are actually more in past commits):
the version in the last commit
the version staged for commit
the version in the working directory
12.2. How does git track file names?#
Let’s trace it out? First we will look at our recent commits
git log
commit 042a42eb47c33ee43d793feb4d891a93e7460527 (HEAD -> main, origin/main, origin/HEAD)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Sep 21 13:26:59 2023 -0400
begin organizing
commit d76bc523443bda5a5daae2fe7fcfbf6fba71ae6d
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Sep 21 12:53:14 2023 -0400
start organizng for real
commit bc281792d6ab62b153d7bf44f7985ec7cfc3b850
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Thu Sep 21 12:51:22 2023 -0400
start organizing
commit 756c4879c0447db20980f73a26bc2ba072e08a6d (origin/fun_fact, fun_fact)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Tue Sep 19 13:26:20 2023 -0400
second fun fact
Now we can use the first four characters (the minimum) or more if needed to be unique to look at that commit object.
git cat-file -p 042a
tree 11d53c24bb5d2bf2e3f645ef188f8bc75fa9c911
parent d76bc523443bda5a5daae2fe7fcfbf6fba71ae6d
author Sarah M Brown <brownsarahm@uri.edu> 1695317219 -0400
committer Sarah M Brown <brownsarahm@uri.edu> 1695317219 -0400
begin organizing
Here, in the commit, we see that there are no file names. So we can keep tracing, we will look at the tree object from this commit.
git cat-file -p 11d5
040000 tree 95b60ce8cdec1bc4e1df1416e0c0e6ecbd3e7a8c .github
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 API.md
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 CONTRIBUTING.md
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 LICENSE.md
100644 blob 8c7cefb877c62a46a3b71c68a858c24075b379fe README.md
100644 blob b62d570421c3096d8c80c7df56357cdd3203fd3a about.md
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 abstract_base_class.py
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 alternative_classes.py
040000 tree 9896f7a7000a7b9d2fdb12047a141524358286c3 docs
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 helper_functions.py
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 important_classes.py
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 setup.py
040000 tree 45fcb1dd311e5e45af759cb3627dca5f47f58f04 tests
Here in the tree we see that each line includes the name from the working directory of the file that the blob came from or the folder that is represented by that additional tree.
Let’s check a blob object for completeness.
git cat-file -p b62d
Sarah Brown
2027
- i skied competitively in high school
- i started at URI in 2020
- I went to Northeastern
Note here that there is no mention of the file name, the file name is only in the tree.
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)
modified: about.md
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
12.3. What is the index?#
The staging area/index
cat .git/index
fk#.github/workflows/create_issues.ymle.??.m?0e.??.m?0??d????⛲??CK?)?wZ???S?API.mde.??.Me.??.M??e????⛲??CK?)?wZ???S?CONTRIBUTING.mde.??.?A?e.??.?A???f????⛲??CK?)?wZ???S?
LICENSE.mde.??.?t?e.??.?t???g?????|?w?*F??h?X?@u?y? README.mde1[?5??e1[?5??o?8????0f?DTj0|????,?tabout.mde.??.?1?e.??.?1???h????⛲??CK?)?wZ???S?abstract_base_class.pye.??.?e.??.???i????⛲??CK?)?wZ???S?alternative_classes.pye.??.?N?e.??.?N???k????⛲??CK?)?wZ???S?docs/_config.ymle.??.?Ye.??.?Y??l????⛲?docs/_toc.ymle.??.?C?e.??.?C???m????⛲??CK?)?wZ???S?docs/overview.mde.??.?3?e.??.?3???n????⛲??CK?)?wZ???S?helper_functions.pye.??.?/?e.??.?/???o????⛲??CK?)?wZ???S?important_classes.pye.??.?e.??.???p????⛲??CK?)?wZ???Ssetup.pye.??.?'ee.??.?'e??r????⛲??CK?)?wZ???S?tests/test_abc.pye.??.?n?e.??.?n???s????⛲??CK?)?wZ???S?tests/test_alt.pye.??.?O?e.??.?O???t????⛲??CK?)?wZ???S?tests/test_help.pye.??.?@?e.??.?@???u????⛲??CK?)?wZ???S?tests/test_imp.pyTREE?-1 3
docs3 0
????
{?/?z$5???tests4 0
E???1^E?u??b}?_G??.github1 1
??
?????????>z?workflows1 0
nm?```
```{code-cell} bash
:tags: ["skip-execution"]
git cat-file -p .git/index
fatal: Not a valid object name .git/index
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)
modified: about.md
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
12.4. Why does it show the help#
Important
This was a real question from class and is a good question!
Most command line tools are designed to show you the help, not only an error when you use it incorrectly.
git stats
git: 'stats' is not a git command. See 'git --help'.
The most similar command is
status
12.5. Git References#
Note
I have commented out for now where the inspection of git tags did not go as expected. I hope to fill this in with the answer and notify you later.
12.6. Making a git tag#
We will work in the github-inclass repo for this.
cd ../github-inclass-fa23-brownsarahm/
The git tag
command works a lot like git branch
. With no parameters it lists the current tags. With options it can also create or manage them.
git tag
If we provide a name for it, we can create a lightweight tag
git tag v1
A lightweight tag is just a pointer to a commit.
git tag
v1
We can see the tag is added to the annotation on the commits with git log.
git log --pretty=oneline
042a42eb47c33ee43d793feb4d891a93e7460527 (HEAD -> main, tag: v1, origin/main, origin/HEAD) begin organizing
d76bc523443bda5a5daae2fe7fcfbf6fba71ae6d start organizng for real
bc281792d6ab62b153d7bf44f7985ec7cfc3b850 start organizing
756c4879c0447db20980f73a26bc2ba072e08a6d (origin/fun_fact, fun_fact) second fun fact
768dec80c5e0734476d476ae83376c9c786b6450 Update about.md
6d4dbd33860fceb9c87bd3c4509deff8cecb3f45 add fun fact
5c8aaa9f2a129d551b8cb2cb294676f63c4af410 Merge pull request #5 from introcompsys/add-name
65e9e39935be8400ef12cc9003592f12244b50da (origin/add-name) closes #2
caeacb503cf4776f075b848f0faff535671f2887 Merge pull request #4 from introcompsys/1-create-an-about-file
693a2b5b9ad4c27eb3b50571b3c93dde353320a1 (origin/1-create-an-about-file, 1-create-an-about-file) create and complete about file closes #1
6a12db0035e7c73772f7b2348b80dd0bfb3a2a2e Add online IDE url
cfe32e5066921ad876d8a2c74b1fcb00c99b1cc7 Initial commit
git tag --help
We can also add tags at past commits by passing a commit hash.
git tag v0 65e9
and see it the same way.
git log --pretty=oneline
042a42eb47c33ee43d793feb4d891a93e7460527 (HEAD -> main, tag: v1, origin/main, origin/HEAD) begin organizing
d76bc523443bda5a5daae2fe7fcfbf6fba71ae6d start organizng for real
bc281792d6ab62b153d7bf44f7985ec7cfc3b850 start organizing
756c4879c0447db20980f73a26bc2ba072e08a6d (origin/fun_fact, fun_fact) second fun fact
768dec80c5e0734476d476ae83376c9c786b6450 Update about.md
6d4dbd33860fceb9c87bd3c4509deff8cecb3f45 add fun fact
5c8aaa9f2a129d551b8cb2cb294676f63c4af410 Merge pull request #5 from introcompsys/add-name
65e9e39935be8400ef12cc9003592f12244b50da (tag: v0, origin/add-name) closes #2
caeacb503cf4776f075b848f0faff535671f2887 Merge pull request #4 from introcompsys/1-create-an-about-file
693a2b5b9ad4c27eb3b50571b3c93dde353320a1 (origin/1-create-an-about-file, 1-create-an-about-file) create and complete about file closes #1
6a12db0035e7c73772f7b2348b80dd0bfb3a2a2e Add online IDE url
cfe32e5066921ad876d8a2c74b1fcb00c99b1cc7 Initial commit
These create files in the .git direcotry with the hash in them
ls .git/refs/tags/
v0 v1
cat .git/refs/tags/v0
65e9e39935be8400ef12cc9003592f12244b50da
Tags can be used with other git commands like git log
to show only a subset of the commits.
git log --pretty=oneline v0..v1
042a42eb47c33ee43d793feb4d891a93e7460527 (HEAD -> main, tag: v1, origin/main, origin/HEAD) begin organizing
d76bc523443bda5a5daae2fe7fcfbf6fba71ae6d start organizng for real
bc281792d6ab62b153d7bf44f7985ec7cfc3b850 start organizing
756c4879c0447db20980f73a26bc2ba072e08a6d (origin/fun_fact, fun_fact) second fun fact
768dec80c5e0734476d476ae83376c9c786b6450 Update about.md
6d4dbd33860fceb9c87bd3c4509deff8cecb3f45 add fun fact
5c8aaa9f2a129d551b8cb2cb294676f63c4af410 Merge pull request #5 from introcompsys/add-name
Note
I used that to generate a list of changes in the class 11 release
12.7. What if I have changes I do not want to lose or commit yet#
We want to pusht the tag, but we cannot push right now:
git push
To https://github.com/introcompsys/github-inclass-fa23-brownsarahm.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://github.com/introcompsys/github-inclass-fa23-brownsarahm.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
because we have our local and remote main branches out of sync
git pull
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 3), reused 6 (delta 3), pack-reused 0
Unpacking objects: 100% (6/6), 745 bytes | 82.00 KiB/s, done.
From https://github.com/introcompsys/github-inclass-fa23-brownsarahm
042a42e..4202c16 main -> origin/main
Updating 042a42e..4202c16
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
Pulling did not work either.
However, technically the tags can be pushed anyway, even without pushing the rest of our files.
git push --tags
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/introcompsys/github-inclass-fa23-brownsarahm.git
* [new tag] v0 -> v0
* [new tag] v1 -> v1
We can then see them in the browser:
gh repo view --web
Opening github.com/introcompsys/github-inclass-fa23-brownsarahm in your browser.
12.8. Using git to debug#
Note
I am going to revise this later, to understand for now, refer to the git book chapter
If you find a bug in your code and you do not know when it was introduced git bisect
can help you perform a binary search over your commits to find the first commit that introduced the bug.
git bisect start
status: waiting for both good and bad commits
It takes 2 inputs as separate calles after you start it a known bad commit and a known good commit.
We will say that we know our current commit is bad.
git bisect bad
status: waiting for good commit(s), bad commit known
And that v0
tag was good.
Note
This is a good use of tags!
git bisect good v0
Bisecting: 3 revisions left to test after this (roughly 2 steps)
error: Your local changes to the following files would be overwritten by checkout:
about.md
Please commit your changes or stash them before you switch branches.
Aborting
Now that working directory update that we made comes back to get in the way.
We have the option to commit or stash.
12.9. What if I want to keep changes, but not commit them yet?#
Stash creates git objects of content that you can recover later. It works like a first-in-first-out queue by default and is a conceptually separate set of content from the commit history (though it is still stored in the .git/
directory)
git stash
Saved working directory and index state WIP on main: 042a42e begin organizing
once we stash it, our working directory is clean and we can go back to debugging
12.10. Binary searchiing with bisect#
Now we can tell it the good commit again
git bisect good v0
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[768dec80c5e0734476d476ae83376c9c786b6450] Update about.md
What git does here is checks out the commit in the middle of the commits we labeled good and bad, this allows us to check whatever we were looking for and then we have to label each commit it checks out for us as good or bad.
git bisect good
Bisecting: 1 revision left to test after this (roughly 1 step)
[bc281792d6ab62b153d7bf44f7985ec7cfc3b850] start organizing
If we say it is good, it takes the next commit to be halfway between this commit and the one labeled bad.
git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[756c4879c0447db20980f73a26bc2ba072e08a6d] second fun fact
When we label a commit bad, it checks out the commit between the current commit and the closest one labeled good
Here we do whatever we need to do to figure out if the currently checked out version is good or bad.
And label this comit
git bisect bad
756c4879c0447db20980f73a26bc2ba072e08a6d is the first bad commit
commit 756c4879c0447db20980f73a26bc2ba072e08a6d
Author: Sarah M Brown <brownsarahm@uri.edu>
Date: Tue Sep 19 13:26:20 2023 -0400
second fun fact
about.md | 2 ++
1 file changed, 2 insertions(+)
In this case, once we label it bad, now git has enough informtion to tell us what commit was the first bad one and what changes were made in this commit.
This wil help us decide how to fix it.
git status
HEAD detached at 756c487
You are currently bisecting, started from branch 'main'.
(use "git bisect reset" to get back to the original branch)
nothing to commit, working tree clean
“detatched” HEAD means that the head pointer is set to a specific commit rather than a branch.
When we are done, we can use reset to to back to main and then apply our fix.
git bisect reset
Previous HEAD position was 756c487 second fun fact
Switched to branch 'main'
Your branch is behind 'origin/main' by 2 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
12.11. What about the stashed content#
Now that we are on main with a clean working directory it is a good time to pull the remote changes.
git pull
Updating 042a42e..4202c16
Fast-forward
README.md | 37 +++++++++++++++++++------------------
about.md => docs/about.md | 0
2 files changed, 19 insertions(+), 18 deletions(-)
rename about.md => docs/about.md (100%)
We can use list
on git stash
to see the stashed changes
git stash list
stash@{0}: WIP on main: 042a42e begin organizing
and then apply
to apply them
git stash apply
On branch main
Your branch is up to date with 'origin/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: docs/about.md
no changes added to commit (use "git add" and/or "git commit -a")
it updates the working directory but not the index by default.
If we re stage the file
git add .
and and make more edits
echo "another edit" >> docs/about.md
so that we have both staged and unstaged changes again
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)
modified: docs/about.md
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: docs/about.md
and stash this status
git stash
Saved working directory and index state WIP on main: 4202c16 fix readme to remove >
git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
we now have 2 stashes
git stash list
stash@{0}: WIP on main: 4202c16 fix readme to remove >
stash@{1}: WIP on main: 042a42e begin organizing
we can apply the on in 0 to both the workign directory and the staging area with the --index
option.
git stash apply --index
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: docs/about.md
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: docs/about.md
12.12. Prepare for Next Class#
If you have not already or right before class, review the GitHub Action files in your KWL repo and make note of what if any syntax in there is unfamilar. (note that link may not work on the rendered website, but will work on issues)
Use quote reply or edit to see how I made a relative path to a location within the repo in this issue.
Check out the github action marketplace to see other actions that are available and try to get a casual level of understanding of the types of things that people use actions for.
12.13. Review today’s class#
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
Create tagtypeexplore.md with the template below. Determine how many of the tags in the course website are annotated vs lightweight using
git cat-file
to inspect the tags and thegit tag
help to determine which tags are of each type.
# 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:
12.14. More Practice#
Use your github-inclass repo to create a scenario where you can fix a problem using a git command from the patching or debugging section of the docs. Create a log of what you did using the history or git log into a file gitstory.md. If you have a project in another class or another badge in this class that causes you to use one in a real scenario, that can count. If not, for example, you could create a “bug” and then use bisect to find it.
Create tagtypes.md with the template below. Include an experiment that shows which if either type of tag creates a new git object. There are two types, try creating one of each a lightwight tag (provide only the tag name- what we did in class) and an annotated (provide a name and a message with
-m
). Determine many of the tags in the course website are annotated vs lightweight using what you learned about how tags are represented andgit cat-file
to see which is which.
# 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:
12.15. Experience Report Evidence#
save your command history to 2023-10-19-log.txt
and put that file in your KWL repo
12.16. Questions After Today’s Class#
Note
due to scheduling issues this will be late today