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#

  1. 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)

  2. Use quote reply or edit to see how I made a relative path to a location within the repo in this issue.

  3. 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#

  1. 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

  2. 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 the git 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#

  1. 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.

  2. 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 and git 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