8 Getting out of trouble
Teaching: 15 min Exercises: 10 min
8.1 Questions
- I messed up the commit message or files committed, how can I edit a commit?
- I realised I introduced a problem, how can I revert a file to an earlier version?
- Something is not right, how can I restore an earlier version of the whole repository?
8.2 Objectives
- Understand how to solve some common problems in arising in git.
8.3 Helping yourself with git
In this lesson we’ll cover just a few of the ways you can get yourself out of trouble with git. The key new you commands we’ll discuss are:
checkout
which will allow us to restore files to previous versions.
There are other great resources on this topic, see:
8.4 Fixing a previous commit
In this scenario you’ve made a commit and then you realise you missed a file or made an error with the commit message.
You an call the git commit
command with the --amend
flag and any staged
files will be added to the previous commit and you will be given a chance to
rewrite the commit message.
8.4.1 Your first amendment
Using the ‘git_workshop’ repository from previous lessons:
- Open 00_analysis.Rmd in Atom and insert a new line: “part one”
- On the terminal, Save, stage, and commit the file with commit messge “added part one”
- In Atom, add a new line in 00_analysis.Rmd: “part two”
- Save and stage the file.
- Amend the commit as described above.
- Push the commit.
- Check the history on GitHub and confirm “part one” and “part two” were added as part of the same commit.
8.5 Restoring a file to an earlier version
Let’s say you’ve identified a problem with a specific file and would like to restore it to an earlier version. You have two options:
- You can look through the history, say on GitHub, and find the hash of a commit from when things were fine. You restore the file to the version it was when that commit was made.
- You can’t find a commit or oh god please there’s not much time. You can restore the file to the version it was some time ago
After you have restored the file, you can stage, commit, and push it to make it the current version.
8.5.1 Restoring to a hash
You don’t need the complete hash, just enough letters to ensure a unique match. 6 or so will usually do. The format of the command is
$ git checkout <patial hash> <file path>
The hashes in your repository are unique so I can’t give an example that will
work for you. But this would restore 00_analysis.Rmd
to its a blank
state in my repository:
$ git checkout 3ff91b 00_analysis.Rmd
8.5.2 Restoring to a time period ago
Let’s say it’s Monday morning and you realise you made some bad changes to a file on Friday afternoon, but you’re not sure when, and you just need to fix it in a hurry before your meeting with your supervisor. You could do:
$ git checkout "@{3 days ago}" <file path>
To restore the file to as it was on Friday morning. You can use decimal numbers
and any time unit. @{20 minutes ago}
might be good for those last minute
presentation ‘tweaks’.
8.5.3 Restoring to most recent version
If you decide you would like to return a file you restored with checkout
to
it’s most recent version, remember that HEAD is a reference to the latest
commit. So you can again use checkout
:
$ git checkout HEAD <file path>
8.5.4 Restoration resuce
Using the ‘git_workshop’ repository:
- Using
git checkout
, Restore ‘analysis.Rmd’ to the working directory. This is what ‘00_analysis.Rmd’ was called before we changed its name.
8.6 Restoring the entire repository to an earlier version
You have a few options here depending on the outcome you want. Here I assume you want to temporarily roll back to check an analysis result with an old version, but you do not want to permanently reset the repository and its history to an earlier time point.
If you call git checkout
with no <file path>
argument the entire repository will
be rolled back to the commit hash or time you specified. For example:
git checkout "@{1 day ago}"
However be warned if you make commits in this state, they will work but they will not be added to the history - You can’t just insert stuff into the middle of history(!). You can add these orphan commits to a branch, but this is beyond the scope of this lesson.
This state of git purgatory is called ‘detached HEAD’ as the head reference no longer points to a commit on the branch’s timeline.
We can’t use git checkout HEAD
as before to return to present because HEAD is no longer on any timeline. So we need to put HEAD back on a timeline using:
git checkout master
Where HEAD will be pointing to the latest commit by default.
Permanently resetting the repository and its history to an earlier time point is
possible but can lead to permanent loss of work. You will need to look into
advanced usage of git reset --hard
.
8.7 When all else fails
This is also called ‘burning it down’.
8.8 Summary
You learned git commands that are useful for updating commits, restoring files, and jumping back to previous repository versions.
- git commit –amend
- git checkout 123abc file.ext
- git checkout 123abc
- git checkout “@{4 days ago}”