Git checkout

Git for file recovery

tech

As you learned in the previous article What is Git? and how to use it, Git is a version control system, meaning that its primary job is to keep track of the many different versions of a file. This means that when you make an ill-advised edit to a file, you can roll back to a previous good version.

To activate stuff in Git, you use the git checkout command. You already used it once to switch from master to your personal work branch, but you can also check out a file. There are (at least) 3 methods to recover an old version of a file in Git.

Git branch

The first method is to work on a different branch. Branches are like isolation tanks. They're safe spaces you can work in, make bad decisions, and destroy stuff, and none of it affects any other branch. If you followed along with the demonstration, you can try this out.


$ git branch sandbox
$ git checkout sandbox
$ cat ~/unices/linux.list
slackware
fedora
debian
gentoo
$ echo "all your bases are belong to us" > ~/unices/linux.list
$ cat ~/unices/linux.list
all your bases are belong to us
$ git add ~/unices/linux.list
$ git commit --message 'I regret nothing'

You have successfully rendered your list of Linuxes useless. But only in your sandbox branch. You can recover all of your work by checking out a good branch.


$ git checkout seth
$ cat ~/unices/linux.list
slackware
fedora
debian
gentoo

If you use branches frequently, then you're free to experiment, secure in the knowledge that you last known good version is safe in your other branch.

If you produce something that you end up wanting to keep, you can merge your work back into your usual branch so that all of you "good" work all lives in one place.


$ git checkout seth
$ git merge sandbox

If you're finished with the sandbox branch for now, you can delete it.


$ git branch -d sandbox  

Git checkout before a commit

If you don't want to bother creating a new branch, you can always revert to a previous version of a file before you commit it, because until you commit a file, none of your changes have been made official, at least from Git's perspective.

Here's a demonstration.


$ echo "windows" > linux.list
$ echo "os x" >> linux.list
$ cat linux.list
windows
os x

Restore the old version of your file with Git checkout.


$ git checkout linux.list

$ cat linux.list
slackware
fedora
debian
gentoo

The file has been restored to its state as of your latest commit.

Git checkout after a commit

Sometimes, you might commit a bad version of a file and decide later that you'd prefer to restore some earlier version.


$ echo "windows" > linux.list
$ echo "osx" >> linux.list

$ cat linux.list
windows
osx

$ git add linux.list

$ git commit -m 'bad commit'

Now, from this point, if you do a checkout, you'd be stuck at the latest version of the file, which is the bad version. What you really want is a Git check out of the file as it existed two commits ago.

To go "back in time" this way, you need reference points. Those exist in your Git log, in the form of "hashes". A hash, in this context, is a sort of fingerprint of a specific commit. It's the reference number of a particular snapshot.

To get the hash of a previous commit, look at a log of all the commits you have made to identify which version of the file you want to resurrect. This example looks at the most recent 5 commits, a handy trick if you have a very extensive log.


$ git log --oneline | head -n 5
07eed25 bad commit
1903a56 my very first commit

The string of letters and numbers (the letters are actually numbers, too, written in the hexadecimal system) is the hash, or the unique identifier, for each commit. You can yank the old version of a file from any previous commit.


$ git checkout 1903a56 linux.list
$ cat linux.list
slackware
fedora
debian
gentoo

You have restored your file to its state during your first commit. If you're happy with that version of the file, then use Git add and Git commit to get it back into your log.


$ git add linux.list
$ git commit --message 'recovered linux.list'
$ git log --oneline | cat
0f1af31 recovered linux.list
07eed25 bad commit
1903a56 my very first commit

Making it official

So far, you've been using your own branch, or possible branches, for all of your work. That's a common technique, but ultimately most people and most Git hosts (like Gitlab or Github) expect your "final" work to end up on master.


$ git checkout master
$ git merge seth

Why you might want to do this is another topic, however, for a future article. For now, you have everything you need to use Git to track your work on your local machine.

Previous Post Next Post