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