Quick Links

Git is a powerful tool for tracking each version of your codebase, and it's often necessary to look back in time and recover old versions of files. Git can revert whole commits, or reset the entire repository, but it can also roll back changes to a single file or folder.

Reverting vs. Resetting

Usually, when you "revert" a commit, Git applies a new commit applying the opposite changes, effectively cancelling it out. This is useful if you make a mistake and need to "delete" that commit, though it's still recorded in the history.

Resetting the repository is a little different. You can only revert one commit at a time, but if you do a

        git reset
    

, Git will completely change the state of the repo back to when that commit was made. This is done for lots of reasons, usually to delete commits or fix branch history.

Both of these operations work on the entire repository, but you can also use similar commands to perform the same actions on individual files or folders. For example, using

        git reset
    

 on a single file will set that file back to how it was when the commit was made. This is useful if you just want to pick out an old version of the file from your Git history.

Looking at Old Versions in Git

The low-tech solution to setting a file back to how it used to be is pretty simple---Github and most other Git servers keep track of your file history, and you can simple click on a commit and click "Browse Files" to view a snapshot of your repository from back in time. You can then download the file, or copy the text over.

This is especially useful if you're working with a large code files, and want to look at old versions of functions you wrote. You probably don't want to revert the entire thing in that case, just the single function. You can copy the code from that function without touching the Git CLI.

Resetting a File to an Old Version in Git

In this test repository, we made a commit that edited the README and added a new file. We want to revert the changes made to the README, but we don't want to reset the entire repo back to the initial commit.

The solution is to reset just the README by checking out an old version of that file. Git's

        checkout
    

 command does a lot of things, like switching branches, but it's basically used for downloading files given a commit or branch ID.

To reset a file back to an old version, you'll need to find the commit ID from when you want to reset to. You can use

        git log
    

 for this, scoped to a single file to view only the changes done to that file:

git log README.md

Copy the ID for the commit, and then run git checkout with the ID and file path:

git checkout 22710694b25d7ce5297559851beb7d3e4de811bb README.md

This will change the file back, but it won't commit the changes just yet. You're free to edit it and commit when you're ready.

In this example, git checkout staged the changes for the next commit. If you don't want to commit them, you're free to discard the changes. This can be useful to download old versions of files temporarily without the use of Github.

Reverting Changes to Single Files

Similarly, if you want to revert the changes in a single commit, you can do so with git revert. There's no way to apply it to a single file however, but you can simply discard the changes if the commit affects other files.

Use the --no-commit flag to allow editing of the "revert commit" that Git automatically creates.

git revert de8564b131ca6a15a7e7c73f5ef156b119cc0b93

This will allow you to change the files before finalizing the revert. If there are unwanted changes staged, you can remove them through your client, or with an empty git checkout.

git checkout -- file