1From: Junio C Hamano <junkio@cox.net> 2To: git@vger.kernel.org 3Subject: [HOWTO] Reverting an existing commit 4Abstract: In this article, JC gives a small real-life example of using 5 'git revert' command, and using a temporary branch and tag for safety 6 and easier sanity checking. 7Date: Mon, 29 Aug 2005 21:39:02 -0700 8Content-type: text/asciidoc 9Message-ID: <7voe7g3uop.fsf@assigned-by-dhcp.cox.net> 10 11Reverting an existing commit 12============================ 13 14One of the changes I pulled into the 'master' branch turns out to 15break building GIT with GCC 2.95. While they were well intentioned 16portability fixes, keeping things working with gcc-2.95 was also 17important. Here is what I did to revert the change in the 'master' 18branch and to adjust the 'pu' branch, using core GIT tools and 19barebone Porcelain. 20 21First, prepare a throw-away branch in case I screw things up. 22 23------------------------------------------------ 24$ git checkout -b revert-c99 master 25------------------------------------------------ 26 27Now I am on the 'revert-c99' branch. Let's figure out which commit to 28revert. I happen to know that the top of the 'master' branch is a 29merge, and its second parent (i.e. foreign commit I merged from) has 30the change I would want to undo. Further I happen to know that that 31merge introduced 5 commits or so: 32 33------------------------------------------------ 34$ git show-branch --more=4 master master^2 | head 35* [master] Merge refs/heads/portable from http://www.cs.berkeley.... 36 ! [master^2] Replace C99 array initializers with code. 37-- 38- [master] Merge refs/heads/portable from http://www.cs.berkeley.... 39*+ [master^2] Replace C99 array initializers with code. 40*+ [master^2~1] Replace unsetenv() and setenv() with older putenv(). 41*+ [master^2~2] Include sys/time.h in daemon.c. 42*+ [master^2~3] Fix ?: statements. 43*+ [master^2~4] Replace zero-length array decls with []. 44* [master~1] tutorial note about git branch 45------------------------------------------------ 46 47The '--more=4' above means "after we reach the merge base of refs, 48show until we display four more common commits". That last commit 49would have been where the "portable" branch was forked from the main 50git.git repository, so this would show everything on both branches 51since then. I just limited the output to the first handful using 52'head'. 53 54Now I know 'master^2~4' (pronounce it as "find the second parent of 55the 'master', and then go four generations back following the first 56parent") is the one I would want to revert. Since I also want to say 57why I am reverting it, the '-n' flag is given to 'git revert'. This 58prevents it from actually making a commit, and instead 'git revert' 59leaves the commit log message it wanted to use in '.msg' file: 60 61------------------------------------------------ 62$ git revert -n master^2~4 63$ cat .msg 64Revert "Replace zero-length array decls with []." 65 66This reverts 6c5f9baa3bc0d63e141e0afc23110205379905a4 commit. 67$ git diff HEAD ;# to make sure what we are reverting makes sense. 68$ make CC=gcc-2.95 clean test ;# make sure it fixed the breakage. 69$ make clean test ;# make sure it did not cause other breakage. 70------------------------------------------------ 71 72The reverted change makes sense (from reading the 'diff' output), does 73fix the problem (from 'make CC=gcc-2.95' test), and does not cause new 74breakage (from the last 'make test'). I'm ready to commit: 75 76------------------------------------------------ 77$ git commit -a -s ;# read .msg into the log, 78 # and explain why I am reverting. 79------------------------------------------------ 80 81I could have screwed up in any of the above steps, but in the worst 82case I could just have done 'git checkout master' to start over. 83Fortunately I did not have to; what I have in the current branch 84'revert-c99' is what I want. So merge that back into 'master': 85 86------------------------------------------------ 87$ git checkout master 88$ git merge revert-c99 ;# this should be a fast forward 89Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c... 90 cache.h | 8 ++++---- 91 commit.c | 2 +- 92 ls-files.c | 2 +- 93 receive-pack.c | 2 +- 94 server-info.c | 2 +- 95 5 files changed, 8 insertions(+), 8 deletions(-) 96------------------------------------------------ 97 98There is no need to redo the test at this point. We fast forwarded 99and we know 'master' matches 'revert-c99' exactly. In fact: 100 101------------------------------------------------ 102$ git diff master..revert-c99 103------------------------------------------------ 104 105says nothing. 106 107Then we rebase the 'pu' branch as usual. 108 109------------------------------------------------ 110$ git checkout pu 111$ git tag pu-anchor pu 112$ git rebase master 113* Applying: Redo "revert" using three-way merge machinery. 114First trying simple merge strategy to cherry-pick. 115Finished one cherry-pick. 116* Applying: Remove git-apply-patch-script. 117First trying simple merge strategy to cherry-pick. 118Simple cherry-pick fails; trying Automatic cherry-pick. 119Removing Documentation/git-apply-patch-script.txt 120Removing git-apply-patch-script 121Finished one cherry-pick. 122* Applying: Document "git cherry-pick" and "git revert" 123First trying simple merge strategy to cherry-pick. 124Finished one cherry-pick. 125* Applying: mailinfo and applymbox updates 126First trying simple merge strategy to cherry-pick. 127Finished one cherry-pick. 128* Applying: Show commits in topo order and name all commits. 129First trying simple merge strategy to cherry-pick. 130Finished one cherry-pick. 131* Applying: More documentation updates. 132First trying simple merge strategy to cherry-pick. 133Finished one cherry-pick. 134------------------------------------------------ 135 136The temporary tag 'pu-anchor' is me just being careful, in case 'git 137rebase' screws up. After this, I can do these for sanity check: 138 139------------------------------------------------ 140$ git diff pu-anchor..pu ;# make sure we got the master fix. 141$ make CC=gcc-2.95 clean test ;# make sure it fixed the breakage. 142$ make clean test ;# make sure it did not cause other breakage. 143------------------------------------------------ 144 145Everything is in the good order. I do not need the temporary branch 146nor tag anymore, so remove them: 147 148------------------------------------------------ 149$ rm -f .git/refs/tags/pu-anchor 150$ git branch -d revert-c99 151------------------------------------------------ 152 153It was an emergency fix, so we might as well merge it into the 154'release candidate' branch, although I expect the next release would 155be some days off: 156 157------------------------------------------------ 158$ git checkout rc 159$ git pull . master 160Packing 0 objects 161Unpacking 0 objects 162 163* committish: e3a693c... refs/heads/master from . 164Trying to merge e3a693c... into 8c1f5f0... using 10d781b... 165Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f 166 cache.h | 8 ++++---- 167 commit.c | 2 +- 168 ls-files.c | 2 +- 169 receive-pack.c | 2 +- 170 server-info.c | 2 +- 171 5 files changed, 8 insertions(+), 8 deletions(-) 172------------------------------------------------ 173 174And the final repository status looks like this: 175 176------------------------------------------------ 177$ git show-branch --more=1 master pu rc 178! [master] Revert "Replace zero-length array decls with []." 179 ! [pu] git-repack: Add option to repack all objects. 180 * [rc] Merge refs/heads/master from . 181--- 182 + [pu] git-repack: Add option to repack all objects. 183 + [pu~1] More documentation updates. 184 + [pu~2] Show commits in topo order and name all commits. 185 + [pu~3] mailinfo and applymbox updates 186 + [pu~4] Document "git cherry-pick" and "git revert" 187 + [pu~5] Remove git-apply-patch-script. 188 + [pu~6] Redo "revert" using three-way merge machinery. 189 - [rc] Merge refs/heads/master from . 190++* [master] Revert "Replace zero-length array decls with []." 191 - [rc~1] Merge refs/heads/master from . 192... [master~1] Merge refs/heads/portable from http://www.cs.berkeley.... 193------------------------------------------------