Tag Archives: ammend

Undo in Git!

We have learned a lot during the course of this blog till now. I think its now important to know how to undo things in Git. This could come in handy if you have done something by mistake.

We are going to look into the following in this post:

  1. Undoing working directory changes
  2. Un-staging files
  3. Changing the last commit
  4. Reverting commits
  5. Reset command explained

1. Undoing working directory changes
Here lets say you have made some changes to a tracked file. So the file is in modified state.


~/learngitwithme/learngitwithme$ cat README-V3.txt
Learning cherry picking in Git
~/learngitwithme/learngitwithme$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
 (use 'git push' to publish your local commits)

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: README-V3.txt

Let say I want to revert back to whatever was there in the file that is in modified state. Git tell me exactly what I need to do, that is to run ‘git checkout — README-V3.txt’.


~/learngitwithme/learngitwithme$ git checkout -- README-V3.txt
~/learngitwithme/learngitwithme$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
 (use 'git push' to publish your local commits)

nothing to commit, working directory clean

2. Un-staging file
Assume that you made some changes and staged that file. Now you realized that those changes are not accurate and need to unstage the change for now. You can do so by running reset command.


~/learngitwithme/learngitwithme$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
 (use 'git push' to publish your local commits)

Changes to be committed:
 (use 'git reset HEAD <file>...' to unstage)

modified: README-V3.txt

Again, its very easy. Git tells me what needs to be done. That is to run ‘git reset HEAD README-V3.txt’. See it in action below:


~/learngitwithme/learngitwithme$ git reset HEAD README-V3.txt
Unstaged changes after reset:
M README-V3.txt
~/learngitwithme/learngitwithme$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
 (use 'git push' to publish your local commits)

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: README-V3.txt

no changes added to commit (use 'git add' and/or 'git commit -a')

3. Changing the last commit
Lets say you went ahead and made the commit. Again don’t freak out, since you have not yet pushed anything to remote repository yet 😉 To change the last commit, run ‘git commit -ammend’. By running this you can basically do anything and commit again. This involves adding/removing files from the last commit as well as change the commit message.


~/learngitwithme/learngitwithme$ git hist
* a55934b (HEAD, master, feature-2) Added rebasing text in README-V2.txt
* f138320 Adding README-V3.txt file
* 1547936 Adding the delete info in README-v2.txt
* 254f907 Removing README.txt
* 4dcb0d6 Fixed merge conflict
|\
| * 04ce90d (feature-1) Added some more description in README-V2.txt'
* | 418617b Adding some text in README-V2.txt
|/
* 1070675 Renamed AnotherREADME.txt to REAME-V2.txt
* fb0cec8 Removed newFile.txt
* dac68ff Added newFile.txt and new content to README.txt
* 8248e59 Adding .gitignore file
* d19ba22 Added new content to README.txt
* e8d69a8 (origin/master) Modified README.txt and added AnotherREADME.txt
* 3dca5ca Adding README.txt file

Let go ahead and amend the last commit by adding README-V3.txt also to the commit.


~/learngitwithme/learngitwithme$ git status
On branch master
Your branch is ahead of 'origin/master' by 12 commits.
 (use 'git push' to publish your local commits)

modified: README-V3.txt
~/learngitwithme/learngitwithme$ git add README-V3.txt

~/learngitwithme/learngitwithme$ git commit --amend -m 'Added text in both README-V2 and README-V3.txt'

Lets check the history now:


~/learngitwithme/learngitwithme$ git hist
* 5c0558a (HEAD, master) Added text in both README-V2 and README-V3.txt
| * a55934b (feature-2) Added rebasing text in README-V2.txt
|/
* f138320 Adding README-V3.txt file
* 1547936 Adding the delete info in README-v2.txt
* 254f907 Removing README.txt
* 4dcb0d6 Fixed merge conflict
|\
| * 04ce90d (feature-1) Added some more description in README-V2.txt'
* | 418617b Adding some text in README-V2.txt
|/
* 1070675 Renamed AnotherREADME.txt to REAME-V2.txt
* fb0cec8 Removed newFile.txt
* dac68ff Added newFile.txt and new content to README.txt
* 8248e59 Adding .gitignore file
* d19ba22 Added new content to README.txt

4. Reverting commits
Commits can be reverted in Git. However in Git language, that mean commit once again with reverting all the changes that were done by that commit.

13.1.jpg

Let us say you realize later that commit c2 needs to be reverted. To do that run:

  • Run ‘git log’ and find the hash code related to the commit you want to revert
  • Run ‘git revert HASHCODE (c2)’ to introduce another commit that reverts the changes made by C2.

13.2.jpg

I have denote !C2 to signify that this new commit undoes everything that C2 did.

If you have to undo the last n commit you could find the SHA for all the commit and run them in reverse order. There are other ways of doing this as well where you can provide a range.

5. Reset command explained
Reset command undoes commits by moving the HEAD pointer. There are three kinds of resets, depending upon how you want the files in the Working directory & staging area.

  1. Soft – moves the HEAD and keeps the files intact in WD and staging area
  2. mixed  – moves the HEAD and reverts changes in staging area
  3. hard – moves the HEAD and reverts changes in staging area and working directory

Note – Use Git reset command with caution. mixed and hard option will make you lose all the uncommitted changes that you may have.

The commands syntax is as follows:

  • git reset [–soft/mixed/hard] SHA-Commit

Note – If you do not pass any option, the default if mixed.

You can pass the hash of the commit you want the HEAD pointer to move to. You can also denote it with reference to HEAD pointer.Please find some example of this command below:

  • git reset –soft HEAD~1 (This will move HEAD to its parent)
  • git reset –soft HEAD~2 (This will move HEAD to its grandparent)
  • git reset –soft sd2323 (where sd2323 is SHA of a particular commit)

In the next post we will look into ‘cherry picking’ a commit.