Git – Rollback to a Specific Point

I woke up to a rude shock today… got an email from an acquaintance I am working with on a certain project –part of the grand requirement towards my MSc research. We are working on a digital collection and it turns out there were a couple of anomalies with the repository version I provided them two months ago (August, 2011). The issue though is that two months down the line and I have made so many changes to my code and the collection in general and he wanted the same exact format of the collection I provided to them. The good thing though is that I started using a version control tool —Git [1]– in June, 2011 and so rolling back to that specific point in time was rather trivial for me to accomplish. I keep wondering what I would have had to go through had I not been using any sort of version control.

The Git distributed workflow I use is best depicted in the diagram in this article I wrote a couple of weeks ago, but in a nutshell, I commit -> push -> pull/fetch&merge using a distributed network of three repositories.

I didn’t want to mess up the current version on the collection and so what I did, to get started with the rollback process, was to clone the entire repository to a different location on my machine.

phiri@phrlig001:~/Documents/projects/bl$ git clone ../../csc5002w/msc v2
Cloning into v2...
done.
phiri@phrlig001:~/Documents/projects/bl$

phiri@phrlig001:~/Documents/projects/bl$ du -hs
13G .
phiri@phrlig001:~/Documents/projects/bl$ ls
v2
phiri@phrlig001:~/Documents/projects/bl$

To make sure I had everything in resulting clone, I did a quick check of my resulting clone.

Checking remote links

phiri@phrlig001:~/Documents/projects/bl/v2$ git remote -v
origin /home/phiri/Documents/projects/bl/../../csc5002w/msc/ (fetch)
origin /home/phiri/Documents/projects/bl/../../csc5002w/msc/ (push)
phiri@phrlig001:~/Documents/projects/bl/v2$ git branch -a
* master
 remotes/origin/HEAD -> origin/master
 remotes/origin/master
phiri@phrlig001:~/Documents/projects/bl/v2$

Checking resulting directory structure of clone

phiri@phrlig001:~/Documents/projects/bl$ tree v2/ -L 2
v2/
├── code
│   └── collections
├── docs
│   ├── etc
│   ├── pubs
│   └── thesis
├── theory
│   └── simplyCT
└── tmp
    └── cscwebsite

10 directories, 0 files
phiri@phrlig001:~/Documents/projects/bl$

Figuring out which commit I was interested in was not that difficult, all I did was scan through my mail bag to check for date when I sent them emails relating to version #2 –turned out I sent that email on August 23, 2011.

Checking last commit on or before August 23, 2011

phiri@phrlig001:~/Documents/projects/bl/v2$ git log --until=2011-08-23
commit 131fc22a606b79a7910fb7a7a5cbafafa5aba0a3
Author: Lighton Phiri <xxxxxxx.xxxxx@gmail.com>
Date: Thu Aug 11 09:16:23 2011 +0200

 daily update@ homepc.

 daily update@ homepc. August 11, 2011.

commit 98afc1e56e7265b5bb56d25b6db9f479cd094416
Author: Lighton Phiri <xxxxxxx.xxxxx@gmail.com>
Date: Wed Aug 10 18:33:59 2011 +0200

 daily update@ labpc.

 daily update@ labpc August 10, 2011.

commit d4dff35f4ff321593a92b3dc271adb92dc79be28
Author: Lighton Phiri <xxxxxxx.xxxxx@gmail.com>
Date: Wed Aug 10 13:19:55 2011 +0200

 daily update@ labpc.

Check out commit’s SHA1 [2] hash of interest.

Hit a snug 🙁 turns out I needed to commit changes I made before checking out.

phiri@phrlig001:~/Documents/projects/bl/v2$ git checkout 131fc22a606b79a7910fb7a7a5cbafafa5aba0a3
error: Your local changes to the following files would be overwritten by checkout:
 .gitignore
 code/collections/bl/src/folder_recursion_pseudocode
 code/collections/bl/src/scripts/simplyct_bl.py

There we go…

phiri@phrlig001:~/Documents/projects/bl/v2$ git checkout 131fc22a606b79a7910fb7a7a5cbafafa5aba0a3
Checking out files: 100% (74723/74723), done.
Note: checking out '131fc22a606b79a7910fb7a7a5cbafafa5aba0a3'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

 git checkout -b new_branch_name

HEAD is now at 131fc22... daily update@ homepc.
phiri@phrlig001:~/Documents/projects/bl/v2$

Checking specific details of my “detached HEAD”

phiri@phrlig001:~/Documents/projects/bl/v2$ git branch
* (no branch)
 master
phiri@phrlig001:~/Documents/projects/bl/v2$

phiri@phrlig001:~/Documents/projects/bl/v2$ git branch -v
* (no branch) 131fc22 daily update@ homepc.
 master e302701 daily update@ labpc October 19, 2011
phiri@phrlig001:~/Documents/projects/bl/v2$

Confirming that I have checked out the right commit

phiri@phrlig001:~/Documents/projects/bl/v2$ git log
commit 131fc22a606b79a7910fb7a7a5cbafafa5aba0a3
Author: Lighton Phiri <xxxxxxx.xxxxx@gmail.com>
Date: Thu Aug 11 09:16:23 2011 +0200

 daily update@ homepc.

 daily update@ homepc. August 11, 2011.

commit 98afc1e56e7265b5bb56d25b6db9f479cd094416
Author: Lighton Phiri <xxxxxxx.xxxxx@gmail.com>
Date: Wed Aug 10 18:33:59 2011 +0200

Seeing that I would have to make changes to this particular version, I decided to create new branch and checked it out, effectively making it my master branch for version #2.

phiri@phrlig001:~/Documents/projects/bl/v2$ git checkout -b version2
Switched to a new branch 'version2'
phiri@phrlig001:~/Documents/projects/bl/v2$ git branch
 master
* version2
phiri@phrlig001:~/Documents/projects/bl/v2$ clear

I just realised that creating tags for each specific “version” I come up with will be particulary helpful in the near future.

References

[1] Git – Fast Version Control System, (N.D.), Retrieved October 20, 2011, from git-scm: http://git-scm.com/
[2] SHA-1, October 7, 2011, Retrieved October 20, 2011, from Wikipedia: http://en.wikipedia.org/wiki/SHA-1