Please open notebook rsepython-s1r3.ipynb
We’re still in our git working directory:
import os
top_dir = os.getcwd()
git_dir = os.path.join(top_dir, 'learning_git')
working_dir = os.path.join(git_dir, 'git_example')
os.chdir(working_dir)
working_dir
‘/Users/uclrits/rsd-python/sec1git/learning_git/git_example’
The commit we want to revert to is the one before the latest.
HEAD
refers to the latest commit. That is, we want to go back to the change before the current HEAD
.
We could have use the hash code (e.g. e.g. 73fbeaf) to reference this, but you can also refer to the commit before the HEAD
as HEAD^
, the one before that as HEAD^^
, the one before that as HEAD~3
.
Ok, so now we’d like to undo the nasty commit with the lie about Mount Fictional.
%%bash
git revert HEAD^
[master f3d6553] Revert “Add a lie about a mountain”
1 file changed, 1 insertion(+), 3 deletions(-)
An editor may pop up, with some default text which you can accept and save.
You may, depending on the changes you’ve tried to make, get an error message here.
If this happens, it is because git could not automagically decide how to combine the change you made after the change you want to revert, with the attempt to revert the change: this could happen, for example, if they both touch the same line.
If that happens, you need to manually edit the file to fix the problem. Skip ahead to the section on resolving conflicts.
The file should now contain the change to the title, but not the extra line with the lie.
Note the log:
%%bash
git log --date=short
[34m2016-09-08[m [33mf3d6553[32m (HEAD -> master)[m [34mRevert “Add a lie about a mountain” [35m [UCL RITS Example][m
[34m2016-09-08[m [33m03a0fc0[32m[m [34mChange title [35m [UCL RITS Example][m
[34m2016-09-08[m [33m61f238a[32m[m [34mAdd a lie about a mountain [35m [UCL RITS Example][m
[34m2016-09-08[m [33me9f76f5[32m[m [34mFirst commit of discourse on UK topography [35m [UCL RITS Example][m
Notice how the mistake has stayed in the history.
There is a new commit which undoes the change: this is colloquially called an “antipatch”.
This is nice: you have a record of the full story, including the mistake and its correction.
It is possible, in git, to remove the most recent change altogether, “rewriting history”. Let’s make another bad change, and see how to do this.
We can add a new change:
%%writefile index.md
Mountains and Hills in the UK
===================
Engerland is not very mountainous.
But has some tall hills, and maybe a
mountain or two depending on your definition.
Overwriting index.md
And review those changes:
%%bash
cat index.md
Mountains and Hills in the UK
===================
Engerland is not very mountainous.
But has some tall hills, and maybe a
mountain or two depending on your definition.
%%bash
git diff
diff –git i/index.md w/index.md
index bb12a24..6f211e7 100644
— i/index.md
+++ w/index.md
@@ -1,4 +1,5 @@
Mountains and Hills in the UK
===================
-England is not very mountainous.
-But has some tall hills, and maybe a mountain or two depending on your definition.
/\ No newline at end of file
+Engerland is not very mountainous.
+But has some tall hills, and maybe a
+mountain or two depending on your definition.
/\ No newline at end of file
We will now commit the change:
%%bash
git commit -am "Add a silly spelling"
[master b27f174] Add a silly spelling
1 file changed, 3 insertions(+), 2 deletions(-)
The latest change is now recorded in the log:
%%bash
git log --date=short
[34m2016-09-08[m [33mb27f174[32m (HEAD -> master)[m [34mAdd a silly spelling [35m [UCL RITS Example][m
[34m2016-09-08[m [33mf3d6553[32m[m [34mRevert “Add a lie about a mountain” [35m [UCL RITS Example][m
[34m2016-09-08[m [33m03a0fc0[32m[m [34mChange title [35m [UCL RITS Example][m
[34m2016-09-08[m [33m61f238a[32m[m [34mAdd a lie about a mountain [35m [UCL RITS Example][m
[34m2016-09-08[m [33me9f76f5[32m[m [34mFirst commit of discourse on UK topography [35m [Jane Hetherington][m
We can use reset
to revoke the spelling mistake change:
%%bash
git reset HEAD^
Unstaged changes after reset: M index.md
What do you notice when we look at the log?
%%bash
git log --date=short
[34m2016-09-08[m [33mf3d6553[32m (HEAD -> master)[m [34mRevert “Add a lie about a mountain” [35m [UCL RITS Example][m
[34m2016-09-08[m [33m03a0fc0[32m[m [34mChange title [35m [UCL RITS Example][m
[34m2016-09-08[m [33m61f238a[32m[m [34mAdd a lie about a mountain [35m [UCL RITS Example][m
[34m2016-09-08[m [33me9f76f5[32m[m [34mFirst commit of discourse on UK topography [35m [UCL RITS Example][m
The silly spelling is no longer in the log. This approach to fixing mistakes, “rewriting history” with reset
, instead of adding an antipatch with revert
is dangerous, and we don’t recommend it.
But you may want to do it for small silly mistakes, such as to correct a commit message.
When git reset removes commits, it leaves your working directory unchanged – so you can keep the work in the bad change if you want.
%%bash
cat index.md
Mountains and Hills in the UK
===================
Engerland is not very mountainous.
But has some tall hills, and maybe a
mountain or two depending on your definition.
If you want to lose the change from the working directory as well, you can do git reset --hard
.
I’m going to get rid of the silly spelling, and I didn’t do --hard
, so I’ll reset the file from the working directory to be the same as in the index:
%%bash
git checkout index.md
%%bash
cat index.md
Mountains and Hills in the UK
===================
But has some tall hills, and maybe a mountain or two depending on your definition.
We can add this to our diagram:
message="""
Working Directory -> Staging Area : git add
Staging Area -> Local Repository : git commit
Working Directory -> Local Repository : git commit -a
Staging Area -> Working Directory : git checkout
Local Repository -> Staging Area : git reset
Local Repository -> Working Directory: git reset --hard
"""
from wsd import wsd
%matplotlib inline
wsd(message)
We can add it to Jane’s story:
message="""
participant "Jane's repo" as R
participant "Jane's index" as I
participant Jane as J
note right of J: git revert HEAD^
J->R: Add new commit reversing change
R->I: update staging area to reverted version
I->J: update file to reverted version
note right of J: vim index.md
note right of J: git commit -am "Add another mistake"
J->I: Add mistake
I->R: Add mistake
note right of J: git reset HEAD^
J->R: Delete mistaken commit
R->I: Update staging area to reset commit
note right of J: git checkout index.md
I->J: Update file to reverted version
"""
wsd(message)
Next: Reading - Publishing