Reverting a Single File – Git

We’ve made some number of commits, five of which changed a given file, and we want to revert the file to one of the previous versions. Git doesn’t keep version numbers for individual files. It just tracks content; so, we have to know which commit has the version of the file we want. Once we know that, we’ll need to make a new commit reverting the file to that state. (We can’t just play around with history, because we’ve already pushed the content, and editing history messes with everyone else.)

So let’s start with finding the right commit. You can see the commits which have made modifications to given file(s) very easily:

git log path/to/file

If your commit messages aren’t good enough, and you need to see what was done to the file in each commit, use the -p/--patch option:

git log -p path/to/file

Or, if you prefer the graphical view of gitk

gitk path/to/file

You can also do this once you’ve started gitk through the view menu; one of the options for a view is a list of paths to include.

Either way, you’ll be able to find the SHA1 (hash) of the commit with the version of the file you want. Now, all you have to do is this:

# get the version of the file from the given commit
git checkout <commit> path/to/file
# and commit this modification
git commit

(The checkout command first reads the file into the index, then copies it into the work tree, so there’s no need to use git add to add it to the index in preparation for committing.)

Git Remote Branches

Useful Commands

First, you create your branch locally:

git checkout -b your_branch

The remote branch is automatically created when you push it to the remote server. So when you feel ready for it, you can just do:

git push <remote-name> <branch-name>

Where <remote-name> is typically origin, the name which git gives to the remote you cloned from. Your colleagues would then just pull that branch, and it’s automatically created locally.

Note however that formally, the format is:

git push <remote-name> <local-branch-name>:<remote-branch-name>

But when you omit one, it assumes both branch names are the same. Having said this, as a word of caution, do not make the critical mistake of specifying only :<remote-branch-name> (with the colon), or the remote branch will be deleted!

So that a subsequent git pull will know what to do, you might instead want to use:

git push -u <remote-name> <branch-name>

As described below, the -u option sets up an upstream branch:

For every branch that is up to date or
successfully pushed, add upstream
(tracking) reference, used by
argument-less git-pull(1) and other
commands.