Git 4: Correcting Mistakes

Photo by CHUTTERSNAP on Unsplash

Photo by CHUTTERSNAP on Unsplash

Correcting Mistakes

Note: I’m doing this in Ubuntu 18.04.

A useful Git tool to have in your back pocket is git stash. Let’s start by making a clean repository as follows:

mkdir my_cool_app
cd my_cool_app
git init
Initialized empty Git repository in ~/my_cool_app/.git/

Open a file a called killer_app.py in your favorite editor and type:

print("My killer app")

then save the file. Then stage and commit by:

git add killer_app.py
git commit -m "Initial commit"

which yields:

[master (root-commit) 4c62075] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 killer_app.py

Pro Tip: you must have at least one commit to stash.

Now add a line to your killer_app.py script:

print("Isn't it cool?")

Next close your editor (this is important later). Then enter the following at the shell prompt:

git stash push -m "Saving work"

which should yield:

Saved working directory and index state On master: Saving work

This has pushed the working directory onto a data structure called a stack. Don’t believe me? Try entering:

git stash list

at the prompt. It should result in something like:

stash@{0}: On master: Saving work
(END)

being output to the terminal. When you are done type ‘q’ to get back to your shell. Now reopen your editor and you should see the last line has been removed. Close your editor one more time, then enter:

git stash pop

which results in:

On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: killer_app.py

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (f8c6f24796935e696f5aa51148b85a86be52820b)

What’s just happened is that Git has popped the last entry off of the stash stack. Reopen your editor and you will see the last line has reappeared.

Amending, Unstaging, and Unmodifying

Photo by Brett Jordan on Unsplash

These come from the Git book.

Amending

You can also amend a commit, meaning you can undo a mistake one commit back. As an example, if you commit and then realize you forgot to stage the changes in a file you wanted to add to this commit, you can do something like this:

git commit -m 'Initial commit'
git add forgotten_file
git commit --amend

You end up with a single commit — the second commit replaces the results of the first.

Only amend commits that are still local and have not been pushed somewhere! Amending previously pushed commits and force pushing the branch will cause problems for your collaborators. For more on what happens when you do this and how to recover if you’re on the receiving end read The Perils of Rebasing.

Unstaging

The next two sections demonstrate how to work with your staging area and working directory changes. The nice part is that the command you use to determine the state of those two areas also reminds you how to undo changes to them. For example, let’s say you’ve changed two files and want to commit them as two separate changes, but you accidentally type git add * and stage them both. How can you unstage one of the two? The git status command reminds you:

git add *
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

renamed: README.md -> README
modified: CONTRIBUTING.md

Right below the “Changes to be committed” text, it says use git reset HEAD <file>... to unstage. So, let’s use that advice to unstage the CONTRIBUTING.md file:

git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md

git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

renamed: README.md -> README

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

modified: CONTRIBUTING.md

The command is a bit strange, but it works. The CONTRIBUTING.md file is modified but once again unstaged.

For now this magic invocation is all you need to know about the git reset command. We’ll go into much more detail about what reset does and how to master it to do really interesting things in Reset Demystified.

Unmodifying

What if you realize that you don’t want to keep your changes to the CONTRIBUTING.md file? How can you easily unmodify it — revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)? Luckily, git status tells you how to do that, too. In the last example output, the unstaged area looks like this:

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

modified: CONTRIBUTING.md

It tells you pretty explicitly how to discard the changes you’ve made. Let’s do what it says:

git checkout -- CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

renamed: README.md -> README

You can see that the changes have been reverted.

Important! It’s important to understand that

git checkout -- <file>

is a dangerous command! Any local changes you made to that file are gone — Git just replaced that file with the most recently-committed version. Don’t ever use this command unless you absolutely know that you don’t want those unsaved local changes!

Git Restore

Git restore is relatively new and I haven’t used it much. It is covered here.

Git Diff & Git Difftool

There is a diff tool provided in Git. Others have documented it. There is a Git difftool as well.

git mv and Git Rm

Also provided out of the box with Git are git mv and git rm. Be very careful with git rm and be sure you actually are deleting what you think you are deleting!

Next:

Next time we’ll get into the weeds a bit and explore some of how Git works under the hood.

If you are not interested in getting in to the details as much, I suggest you skip to this page.

Credits

https://linuxfromanoobie.wordpress.com/2018/04/21/git-undoing/

https://www.freecodecamp.org/news/useful-tricks-you-might-not-know-about-git-stash-e8a9490f0a1a/

https://stackoverflow.com/questions/10725729/see-whats-in-a-stash-without-applying-it

https://www.git-tower.com/learn/git/ebook/en/command-line/advanced-topics/diffs/#start

https://www.toolsqa.com/git/git-diff/

https://stackoverflow.com/questions/255202/how-do-i-view-git-diff-output-with-my-preferred-diff-tool-viewer

Previous
Previous

Git 5: Blobs and Trees

Next
Next

Git 3: Collaboration on GitHub