Stash, Tags and Exploring History: log, show and blame

Git and GitHub Essentials: Version Control for Beginners · Tools and Next Steps · 6 min read · Updated

Put work aside and look back

  1. You have unfinished work that is not ready for a commit, but you need to do something else.
  2. git stash puts those changes on a hidden shelf.
  3. Your folder is clean again, so you can switch branches, pull or fix a quick bug.
  4. git stash pop brings your unfinished work back and removes it from the shelf.

As your projects grow, you will want to answer questions such as: *What did I change last week? Who changed this line, and why? How do I put my half-finished work aside and fix a quick bug?* Git has tools for all of these. This lesson shows the most useful ones, with a real session, and gives careful guidance about the two commands that can cause trouble, cherry-pick and rebase.

$ git stash
Saved working directory and index state WIP on main: 210368e Add line two
$ git status -s
$ git stash list
stash@{0}: WIP on main: 210368e Add line two
$ git stash pop
On 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:   notes.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (f3e0c547c2b5f9d7b8ee38c028ceeb1c3957d9a2)
$ git restore notes.txt
$ git tag -a v1.0 -m "First release"
$ git tag
v1.0
$ git log --oneline --decorate
210368e (HEAD -> main, tag: v1.0) Add line two
3aaeccc Start notes
$ git show --stat HEAD
commit 210368e1de2cb7bf263b971168aa3b67aa55cd5c
Author: Asha Verma <asha@example.com>
Date:   Fri Nov 17 17:13:20 2023 +0000

    Add line two

 notes.txt | 1 +
 1 file changed, 1 insertion(+)
$ git blame notes.txt
^3aaeccc (Asha Verma 2023-11-17 16:13:20 +0000 1) line one
210368e1 (Asha Verma 2023-11-17 17:13:20 +0000 2) line two
$ git log --oneline -- notes.txt
210368e Add line two
3aaeccc Start notes

Stash: put work aside

In the session, we had a half-done idea in notes.txt, and needed a clean folder, for example to switch branches or pull. git stash saved the uncommitted changes in a hidden shelf and returned the files to the last commit. git status -s printed nothing, so the folder was clean. git stash list shows what is on the shelf, and git stash pop puts the work back and removes it from the shelf. If you stash several times, the newest is stash@{0}.

  • Stash only keeps changes to files that Git tracks. Add -u to include new untracked files.
  • Give a stash a name so you can find it later: git stash push -m "half-done idea".
  • A stash lives on your computer only. It is not pushed to GitHub, so do not use it as a backup. For a lasting save, commit on a branch.
  • git stash drop deletes a stash, so use it carefully.

Tags: name an important moment

A tag is a permanent label on a commit, typically used for releases such as v1.0. git tag -a v1.0 -m "First release" created an annotated tag, which stores a message, the date and your name. git tag lists tags, and git log --oneline --decorate shows them next to the commits. Tags are not pushed automatically. Send one with git push origin v1.0, or all of them with git push --tags.

Exploring history

  • git log --oneline is the short list. Add --graph --all to see branches. git log -5 shows only the last five commits.
  • git log -- notes.txt lists only the commits that changed that file. git log -p also shows the changes.
  • git log --author="Asha" and git log --since="2 weeks ago" filter by person and time.
  • git show HEAD shows the latest commit with its changes. git show --stat HEAD adds a summary of the files, as in the session. You can also show an older commit by its code.
  • git diff main feature-branch compares two branches. git diff HEAD~1 compares your folder to the commit before the last one.
  • git blame notes.txt shows who changed each line, in which commit and when. The name sounds harsh, but it is meant to help you find the commit that explains a line, and then to read its message. It is not for blaming people.

Searching

git log -S"password" finds commits that added or removed that text, which is useful for tracking down when something appeared. git grep "TODO" searches the current files of the project quickly. When a bug has appeared and you do not know which commit caused it, git bisect helps you find it by binary search. You mark one good commit and one bad one, and Git checks out the middle commits for you to test. It is advanced, but it is worth knowing that it exists.

cherry-pick: take one commit

git cherry-pick <commit> copies a single commit from another branch onto your current branch. It is useful for taking one bug fix to a release branch without merging everything else. The copy gets a new commit code. If you use it often, ask whether a merge would be simpler. We do not show a session for it here because the idea is small: one commit, copied.

rebase: handle with care

git rebase main, when you are on your feature branch, moves your commits so that they start from the newest main, as if you had begun your work just now. It gives a straight, tidy history. But rebase rewrites commits, which means that they get new codes. The rule is simple: never rebase commits that you have already pushed and that others may use. Rebase your own local, unshared branch if you want, and until you are comfortable, a normal merge is perfectly fine. Many professional teams use merges only.

Tips to feel at home

  • Run git status and git log --oneline --graph --all often. They show you where you are.
  • A graphical tool, such as the Git panel in VS Code, GitHub Desktop or the history view on GitHub itself, helps you see the same things as pictures.
  • git help <command> and git <command> --help open the manual, which is clear once you know the words.
  • If you are afraid to try a command, copy the whole project folder first, and experiment on the copy.

Your task

  1. In a practice repository, make an uncommitted change, stash it, check that the folder is clean, and pop it back.
  2. Create a tag v1.0, list tags and look at git log --oneline --decorate.
  3. Use git log -- file, git show --stat HEAD and git blame file on your own repo, and explain each output.
  4. Write in your own words when you should *not* use rebase.

How to check it worked

  • After git stash, git status shows a clean folder, and after pop your change is back.
  • git log --oneline --decorate shows the tag next to the right commit.
  • You can explain why rewriting pushed history causes problems for others.

Frequently asked questions

Is git stash safe as a backup?

No. A stash stays only on your computer and is easy to drop by mistake. For a lasting save, commit your work on a branch and push it.

What does git blame do?

It shows who last changed each line of a file, and in which commit. Use it to find the commit message that explains why a line is there.