##// END OF EJS Templates
unamend: allow unamending if allowunstable is set...
Martin von Zweigbergk -
r35451:f0110110 default
parent child Browse files
Show More
@@ -1,261 +1,257 b''
1 # uncommit - undo the actions of a commit
1 # uncommit - undo the actions of a commit
2 #
2 #
3 # Copyright 2011 Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
3 # Copyright 2011 Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
4 # Logilab SA <contact@logilab.fr>
4 # Logilab SA <contact@logilab.fr>
5 # Pierre-Yves David <pierre-yves.david@ens-lyon.org>
5 # Pierre-Yves David <pierre-yves.david@ens-lyon.org>
6 # Patrick Mezard <patrick@mezard.eu>
6 # Patrick Mezard <patrick@mezard.eu>
7 # Copyright 2016 Facebook, Inc.
7 # Copyright 2016 Facebook, Inc.
8 #
8 #
9 # This software may be used and distributed according to the terms of the
9 # This software may be used and distributed according to the terms of the
10 # GNU General Public License version 2 or any later version.
10 # GNU General Public License version 2 or any later version.
11
11
12 """uncommit part or all of a local changeset (EXPERIMENTAL)
12 """uncommit part or all of a local changeset (EXPERIMENTAL)
13
13
14 This command undoes the effect of a local commit, returning the affected
14 This command undoes the effect of a local commit, returning the affected
15 files to their uncommitted state. This means that files modified, added or
15 files to their uncommitted state. This means that files modified, added or
16 removed in the changeset will be left unchanged, and so will remain modified,
16 removed in the changeset will be left unchanged, and so will remain modified,
17 added and removed in the working directory.
17 added and removed in the working directory.
18 """
18 """
19
19
20 from __future__ import absolute_import
20 from __future__ import absolute_import
21
21
22 from mercurial.i18n import _
22 from mercurial.i18n import _
23
23
24 from mercurial import (
24 from mercurial import (
25 cmdutil,
25 cmdutil,
26 commands,
26 commands,
27 context,
27 context,
28 copies,
28 copies,
29 error,
29 error,
30 node,
30 node,
31 obsutil,
31 obsutil,
32 pycompat,
32 pycompat,
33 registrar,
33 registrar,
34 rewriteutil,
34 rewriteutil,
35 scmutil,
35 scmutil,
36 )
36 )
37
37
38 cmdtable = {}
38 cmdtable = {}
39 command = registrar.command(cmdtable)
39 command = registrar.command(cmdtable)
40
40
41 configtable = {}
41 configtable = {}
42 configitem = registrar.configitem(configtable)
42 configitem = registrar.configitem(configtable)
43
43
44 configitem('experimental', 'uncommitondirtywdir',
44 configitem('experimental', 'uncommitondirtywdir',
45 default=False,
45 default=False,
46 )
46 )
47
47
48 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
48 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
49 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
49 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
50 # be specifying the version(s) of Mercurial they are tested with, or
50 # be specifying the version(s) of Mercurial they are tested with, or
51 # leave the attribute unspecified.
51 # leave the attribute unspecified.
52 testedwith = 'ships-with-hg-core'
52 testedwith = 'ships-with-hg-core'
53
53
54 def _commitfiltered(repo, ctx, match, allowempty):
54 def _commitfiltered(repo, ctx, match, allowempty):
55 """Recommit ctx with changed files not in match. Return the new
55 """Recommit ctx with changed files not in match. Return the new
56 node identifier, or None if nothing changed.
56 node identifier, or None if nothing changed.
57 """
57 """
58 base = ctx.p1()
58 base = ctx.p1()
59 # ctx
59 # ctx
60 initialfiles = set(ctx.files())
60 initialfiles = set(ctx.files())
61 exclude = set(f for f in initialfiles if match(f))
61 exclude = set(f for f in initialfiles if match(f))
62
62
63 # No files matched commit, so nothing excluded
63 # No files matched commit, so nothing excluded
64 if not exclude:
64 if not exclude:
65 return None
65 return None
66
66
67 files = (initialfiles - exclude)
67 files = (initialfiles - exclude)
68 # return the p1 so that we don't create an obsmarker later
68 # return the p1 so that we don't create an obsmarker later
69 if not files and not allowempty:
69 if not files and not allowempty:
70 return ctx.parents()[0].node()
70 return ctx.parents()[0].node()
71
71
72 # Filter copies
72 # Filter copies
73 copied = copies.pathcopies(base, ctx)
73 copied = copies.pathcopies(base, ctx)
74 copied = dict((dst, src) for dst, src in copied.iteritems()
74 copied = dict((dst, src) for dst, src in copied.iteritems()
75 if dst in files)
75 if dst in files)
76 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
76 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
77 if path not in contentctx:
77 if path not in contentctx:
78 return None
78 return None
79 fctx = contentctx[path]
79 fctx = contentctx[path]
80 mctx = context.memfilectx(repo, memctx, fctx.path(), fctx.data(),
80 mctx = context.memfilectx(repo, memctx, fctx.path(), fctx.data(),
81 fctx.islink(),
81 fctx.islink(),
82 fctx.isexec(),
82 fctx.isexec(),
83 copied=copied.get(path))
83 copied=copied.get(path))
84 return mctx
84 return mctx
85
85
86 new = context.memctx(repo,
86 new = context.memctx(repo,
87 parents=[base.node(), node.nullid],
87 parents=[base.node(), node.nullid],
88 text=ctx.description(),
88 text=ctx.description(),
89 files=files,
89 files=files,
90 filectxfn=filectxfn,
90 filectxfn=filectxfn,
91 user=ctx.user(),
91 user=ctx.user(),
92 date=ctx.date(),
92 date=ctx.date(),
93 extra=ctx.extra())
93 extra=ctx.extra())
94 # phase handling
94 # phase handling
95 commitphase = ctx.phase()
95 commitphase = ctx.phase()
96 overrides = {('phases', 'new-commit'): commitphase}
96 overrides = {('phases', 'new-commit'): commitphase}
97 with repo.ui.configoverride(overrides, 'uncommit'):
97 with repo.ui.configoverride(overrides, 'uncommit'):
98 newid = repo.commitctx(new)
98 newid = repo.commitctx(new)
99 return newid
99 return newid
100
100
101 def _fixdirstate(repo, oldctx, newctx, status):
101 def _fixdirstate(repo, oldctx, newctx, status):
102 """ fix the dirstate after switching the working directory from oldctx to
102 """ fix the dirstate after switching the working directory from oldctx to
103 newctx which can be result of either unamend or uncommit.
103 newctx which can be result of either unamend or uncommit.
104 """
104 """
105 ds = repo.dirstate
105 ds = repo.dirstate
106 copies = dict(ds.copies())
106 copies = dict(ds.copies())
107 s = status
107 s = status
108 for f in s.modified:
108 for f in s.modified:
109 if ds[f] == 'r':
109 if ds[f] == 'r':
110 # modified + removed -> removed
110 # modified + removed -> removed
111 continue
111 continue
112 ds.normallookup(f)
112 ds.normallookup(f)
113
113
114 for f in s.added:
114 for f in s.added:
115 if ds[f] == 'r':
115 if ds[f] == 'r':
116 # added + removed -> unknown
116 # added + removed -> unknown
117 ds.drop(f)
117 ds.drop(f)
118 elif ds[f] != 'a':
118 elif ds[f] != 'a':
119 ds.add(f)
119 ds.add(f)
120
120
121 for f in s.removed:
121 for f in s.removed:
122 if ds[f] == 'a':
122 if ds[f] == 'a':
123 # removed + added -> normal
123 # removed + added -> normal
124 ds.normallookup(f)
124 ds.normallookup(f)
125 elif ds[f] != 'r':
125 elif ds[f] != 'r':
126 ds.remove(f)
126 ds.remove(f)
127
127
128 # Merge old parent and old working dir copies
128 # Merge old parent and old working dir copies
129 oldcopies = {}
129 oldcopies = {}
130 for f in (s.modified + s.added):
130 for f in (s.modified + s.added):
131 src = oldctx[f].renamed()
131 src = oldctx[f].renamed()
132 if src:
132 if src:
133 oldcopies[f] = src[0]
133 oldcopies[f] = src[0]
134 oldcopies.update(copies)
134 oldcopies.update(copies)
135 copies = dict((dst, oldcopies.get(src, src))
135 copies = dict((dst, oldcopies.get(src, src))
136 for dst, src in oldcopies.iteritems())
136 for dst, src in oldcopies.iteritems())
137 # Adjust the dirstate copies
137 # Adjust the dirstate copies
138 for dst, src in copies.iteritems():
138 for dst, src in copies.iteritems():
139 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
139 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
140 src = None
140 src = None
141 ds.copy(src, dst)
141 ds.copy(src, dst)
142
142
143 @command('uncommit',
143 @command('uncommit',
144 [('', 'keep', False, _('allow an empty commit after uncommiting')),
144 [('', 'keep', False, _('allow an empty commit after uncommiting')),
145 ] + commands.walkopts,
145 ] + commands.walkopts,
146 _('[OPTION]... [FILE]...'))
146 _('[OPTION]... [FILE]...'))
147 def uncommit(ui, repo, *pats, **opts):
147 def uncommit(ui, repo, *pats, **opts):
148 """uncommit part or all of a local changeset
148 """uncommit part or all of a local changeset
149
149
150 This command undoes the effect of a local commit, returning the affected
150 This command undoes the effect of a local commit, returning the affected
151 files to their uncommitted state. This means that files modified or
151 files to their uncommitted state. This means that files modified or
152 deleted in the changeset will be left unchanged, and so will remain
152 deleted in the changeset will be left unchanged, and so will remain
153 modified in the working directory.
153 modified in the working directory.
154 """
154 """
155 opts = pycompat.byteskwargs(opts)
155 opts = pycompat.byteskwargs(opts)
156
156
157 with repo.wlock(), repo.lock():
157 with repo.wlock(), repo.lock():
158
158
159 if not pats and not repo.ui.configbool('experimental',
159 if not pats and not repo.ui.configbool('experimental',
160 'uncommitondirtywdir'):
160 'uncommitondirtywdir'):
161 cmdutil.bailifchanged(repo)
161 cmdutil.bailifchanged(repo)
162 old = repo['.']
162 old = repo['.']
163 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
163 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
164 if len(old.parents()) > 1:
164 if len(old.parents()) > 1:
165 raise error.Abort(_("cannot uncommit merge changeset"))
165 raise error.Abort(_("cannot uncommit merge changeset"))
166
166
167 with repo.transaction('uncommit'):
167 with repo.transaction('uncommit'):
168 match = scmutil.match(old, pats, opts)
168 match = scmutil.match(old, pats, opts)
169 newid = _commitfiltered(repo, old, match, opts.get('keep'))
169 newid = _commitfiltered(repo, old, match, opts.get('keep'))
170 if newid is None:
170 if newid is None:
171 ui.status(_("nothing to uncommit\n"))
171 ui.status(_("nothing to uncommit\n"))
172 return 1
172 return 1
173
173
174 mapping = {}
174 mapping = {}
175 if newid != old.p1().node():
175 if newid != old.p1().node():
176 # Move local changes on filtered changeset
176 # Move local changes on filtered changeset
177 mapping[old.node()] = (newid,)
177 mapping[old.node()] = (newid,)
178 else:
178 else:
179 # Fully removed the old commit
179 # Fully removed the old commit
180 mapping[old.node()] = ()
180 mapping[old.node()] = ()
181
181
182 scmutil.cleanupnodes(repo, mapping, 'uncommit')
182 scmutil.cleanupnodes(repo, mapping, 'uncommit')
183
183
184 with repo.dirstate.parentchange():
184 with repo.dirstate.parentchange():
185 repo.dirstate.setparents(newid, node.nullid)
185 repo.dirstate.setparents(newid, node.nullid)
186 s = repo.status(old.p1(), old, match=match)
186 s = repo.status(old.p1(), old, match=match)
187 _fixdirstate(repo, old, repo[newid], s)
187 _fixdirstate(repo, old, repo[newid], s)
188
188
189 def predecessormarkers(ctx):
189 def predecessormarkers(ctx):
190 """yields the obsolete markers marking the given changeset as a successor"""
190 """yields the obsolete markers marking the given changeset as a successor"""
191 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
191 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
192 yield obsutil.marker(ctx.repo(), data)
192 yield obsutil.marker(ctx.repo(), data)
193
193
194 @command('^unamend', [])
194 @command('^unamend', [])
195 def unamend(ui, repo, **opts):
195 def unamend(ui, repo, **opts):
196 """
196 """
197 undo the most recent amend operation on a current changeset
197 undo the most recent amend operation on a current changeset
198
198
199 This command will roll back to the previous version of a changeset,
199 This command will roll back to the previous version of a changeset,
200 leaving working directory in state in which it was before running
200 leaving working directory in state in which it was before running
201 `hg amend` (e.g. files modified as part of an amend will be
201 `hg amend` (e.g. files modified as part of an amend will be
202 marked as modified `hg status`)
202 marked as modified `hg status`)
203 """
203 """
204
204
205 unfi = repo.unfiltered()
205 unfi = repo.unfiltered()
206 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
206 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
207
207
208 # identify the commit from which to unamend
208 # identify the commit from which to unamend
209 curctx = repo['.']
209 curctx = repo['.']
210
210
211 if not curctx.mutable():
211 rewriteutil.precheck(repo, [curctx.rev()], 'unamend')
212 raise error.Abort(_('cannot unamend public changesets'))
213
212
214 # identify the commit to which to unamend
213 # identify the commit to which to unamend
215 markers = list(predecessormarkers(curctx))
214 markers = list(predecessormarkers(curctx))
216 if len(markers) != 1:
215 if len(markers) != 1:
217 e = _("changeset must have one predecessor, found %i predecessors")
216 e = _("changeset must have one predecessor, found %i predecessors")
218 raise error.Abort(e % len(markers))
217 raise error.Abort(e % len(markers))
219
218
220 prednode = markers[0].prednode()
219 prednode = markers[0].prednode()
221 predctx = unfi[prednode]
220 predctx = unfi[prednode]
222
221
223 if curctx.children():
224 raise error.Abort(_("cannot unamend a changeset with children"))
225
226 # add an extra so that we get a new hash
222 # add an extra so that we get a new hash
227 # note: allowing unamend to undo an unamend is an intentional feature
223 # note: allowing unamend to undo an unamend is an intentional feature
228 extras = predctx.extra()
224 extras = predctx.extra()
229 extras['unamend_source'] = curctx.hex()
225 extras['unamend_source'] = curctx.hex()
230
226
231 def filectxfn(repo, ctx_, path):
227 def filectxfn(repo, ctx_, path):
232 try:
228 try:
233 return predctx.filectx(path)
229 return predctx.filectx(path)
234 except KeyError:
230 except KeyError:
235 return None
231 return None
236
232
237 # Make a new commit same as predctx
233 # Make a new commit same as predctx
238 newctx = context.memctx(repo,
234 newctx = context.memctx(repo,
239 parents=(predctx.p1(), predctx.p2()),
235 parents=(predctx.p1(), predctx.p2()),
240 text=predctx.description(),
236 text=predctx.description(),
241 files=predctx.files(),
237 files=predctx.files(),
242 filectxfn=filectxfn,
238 filectxfn=filectxfn,
243 user=predctx.user(),
239 user=predctx.user(),
244 date=predctx.date(),
240 date=predctx.date(),
245 extra=extras)
241 extra=extras)
246 # phase handling
242 # phase handling
247 commitphase = curctx.phase()
243 commitphase = curctx.phase()
248 overrides = {('phases', 'new-commit'): commitphase}
244 overrides = {('phases', 'new-commit'): commitphase}
249 with repo.ui.configoverride(overrides, 'uncommit'):
245 with repo.ui.configoverride(overrides, 'uncommit'):
250 newprednode = repo.commitctx(newctx)
246 newprednode = repo.commitctx(newctx)
251
247
252 newpredctx = repo[newprednode]
248 newpredctx = repo[newprednode]
253 dirstate = repo.dirstate
249 dirstate = repo.dirstate
254
250
255 with dirstate.parentchange():
251 with dirstate.parentchange():
256 dirstate.setparents(newprednode, node.nullid)
252 dirstate.setparents(newprednode, node.nullid)
257 s = repo.status(predctx, curctx)
253 s = repo.status(predctx, curctx)
258 _fixdirstate(repo, curctx, newpredctx, s)
254 _fixdirstate(repo, curctx, newpredctx, s)
259
255
260 mapping = {curctx.node(): (newprednode,)}
256 mapping = {curctx.node(): (newprednode,)}
261 scmutil.cleanupnodes(repo, mapping, 'unamend')
257 scmutil.cleanupnodes(repo, mapping, 'unamend')
@@ -1,366 +1,369 b''
1 Test for command `hg unamend` which lives in uncommit extension
1 Test for command `hg unamend` which lives in uncommit extension
2 ===============================================================
2 ===============================================================
3
3
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [alias]
5 > [alias]
6 > glog = log -G -T '{rev}:{node|short} {desc}'
6 > glog = log -G -T '{rev}:{node|short} {desc}'
7 > [experimental]
7 > [experimental]
8 > evolution = createmarkers, allowunstable
8 > evolution = createmarkers, allowunstable
9 > [extensions]
9 > [extensions]
10 > rebase =
10 > rebase =
11 > amend =
11 > amend =
12 > uncommit =
12 > uncommit =
13 > EOF
13 > EOF
14
14
15 Repo Setup
15 Repo Setup
16
16
17 $ hg init repo
17 $ hg init repo
18 $ cd repo
18 $ cd repo
19 $ for ch in a b c d e f g h; do touch $ch; echo "foo" >> $ch; hg ci -Aqm "Added "$ch; done
19 $ for ch in a b c d e f g h; do touch $ch; echo "foo" >> $ch; hg ci -Aqm "Added "$ch; done
20
20
21 $ hg glog
21 $ hg glog
22 @ 7:ec2426147f0e Added h
22 @ 7:ec2426147f0e Added h
23 |
23 |
24 o 6:87d6d6676308 Added g
24 o 6:87d6d6676308 Added g
25 |
25 |
26 o 5:825660c69f0c Added f
26 o 5:825660c69f0c Added f
27 |
27 |
28 o 4:aa98ab95a928 Added e
28 o 4:aa98ab95a928 Added e
29 |
29 |
30 o 3:62615734edd5 Added d
30 o 3:62615734edd5 Added d
31 |
31 |
32 o 2:28ad74487de9 Added c
32 o 2:28ad74487de9 Added c
33 |
33 |
34 o 1:29becc82797a Added b
34 o 1:29becc82797a Added b
35 |
35 |
36 o 0:18d04c59bb5d Added a
36 o 0:18d04c59bb5d Added a
37
37
38 Trying to unamend when there was no amend done
38 Trying to unamend when there was no amend done
39
39
40 $ hg unamend
40 $ hg unamend
41 abort: changeset must have one predecessor, found 0 predecessors
41 abort: changeset must have one predecessor, found 0 predecessors
42 [255]
42 [255]
43
43
44 Unamend on clean wdir and tip
44 Unamend on clean wdir and tip
45
45
46 $ echo "bar" >> h
46 $ echo "bar" >> h
47 $ hg amend
47 $ hg amend
48
48
49 $ hg exp
49 $ hg exp
50 # HG changeset patch
50 # HG changeset patch
51 # User test
51 # User test
52 # Date 0 0
52 # Date 0 0
53 # Thu Jan 01 00:00:00 1970 +0000
53 # Thu Jan 01 00:00:00 1970 +0000
54 # Node ID c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
54 # Node ID c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
55 # Parent 87d6d66763085b629e6d7ed56778c79827273022
55 # Parent 87d6d66763085b629e6d7ed56778c79827273022
56 Added h
56 Added h
57
57
58 diff -r 87d6d6676308 -r c9fa1a715c1b h
58 diff -r 87d6d6676308 -r c9fa1a715c1b h
59 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60 +++ b/h Thu Jan 01 00:00:00 1970 +0000
60 +++ b/h Thu Jan 01 00:00:00 1970 +0000
61 @@ -0,0 +1,2 @@
61 @@ -0,0 +1,2 @@
62 +foo
62 +foo
63 +bar
63 +bar
64
64
65 $ hg glog --hidden
65 $ hg glog --hidden
66 @ 8:c9fa1a715c1b Added h
66 @ 8:c9fa1a715c1b Added h
67 |
67 |
68 | x 7:ec2426147f0e Added h
68 | x 7:ec2426147f0e Added h
69 |/
69 |/
70 o 6:87d6d6676308 Added g
70 o 6:87d6d6676308 Added g
71 |
71 |
72 o 5:825660c69f0c Added f
72 o 5:825660c69f0c Added f
73 |
73 |
74 o 4:aa98ab95a928 Added e
74 o 4:aa98ab95a928 Added e
75 |
75 |
76 o 3:62615734edd5 Added d
76 o 3:62615734edd5 Added d
77 |
77 |
78 o 2:28ad74487de9 Added c
78 o 2:28ad74487de9 Added c
79 |
79 |
80 o 1:29becc82797a Added b
80 o 1:29becc82797a Added b
81 |
81 |
82 o 0:18d04c59bb5d Added a
82 o 0:18d04c59bb5d Added a
83
83
84 $ hg unamend
84 $ hg unamend
85 $ hg glog --hidden
85 $ hg glog --hidden
86 @ 9:46d02d47eec6 Added h
86 @ 9:46d02d47eec6 Added h
87 |
87 |
88 | x 8:c9fa1a715c1b Added h
88 | x 8:c9fa1a715c1b Added h
89 |/
89 |/
90 | x 7:ec2426147f0e Added h
90 | x 7:ec2426147f0e Added h
91 |/
91 |/
92 o 6:87d6d6676308 Added g
92 o 6:87d6d6676308 Added g
93 |
93 |
94 o 5:825660c69f0c Added f
94 o 5:825660c69f0c Added f
95 |
95 |
96 o 4:aa98ab95a928 Added e
96 o 4:aa98ab95a928 Added e
97 |
97 |
98 o 3:62615734edd5 Added d
98 o 3:62615734edd5 Added d
99 |
99 |
100 o 2:28ad74487de9 Added c
100 o 2:28ad74487de9 Added c
101 |
101 |
102 o 1:29becc82797a Added b
102 o 1:29becc82797a Added b
103 |
103 |
104 o 0:18d04c59bb5d Added a
104 o 0:18d04c59bb5d Added a
105
105
106 $ hg diff
106 $ hg diff
107 diff -r 46d02d47eec6 h
107 diff -r 46d02d47eec6 h
108 --- a/h Thu Jan 01 00:00:00 1970 +0000
108 --- a/h Thu Jan 01 00:00:00 1970 +0000
109 +++ b/h Thu Jan 01 00:00:00 1970 +0000
109 +++ b/h Thu Jan 01 00:00:00 1970 +0000
110 @@ -1,1 +1,2 @@
110 @@ -1,1 +1,2 @@
111 foo
111 foo
112 +bar
112 +bar
113
113
114 $ hg exp
114 $ hg exp
115 # HG changeset patch
115 # HG changeset patch
116 # User test
116 # User test
117 # Date 0 0
117 # Date 0 0
118 # Thu Jan 01 00:00:00 1970 +0000
118 # Thu Jan 01 00:00:00 1970 +0000
119 # Node ID 46d02d47eec6ca096b8dcab3f8f5579c40c3dd9a
119 # Node ID 46d02d47eec6ca096b8dcab3f8f5579c40c3dd9a
120 # Parent 87d6d66763085b629e6d7ed56778c79827273022
120 # Parent 87d6d66763085b629e6d7ed56778c79827273022
121 Added h
121 Added h
122
122
123 diff -r 87d6d6676308 -r 46d02d47eec6 h
123 diff -r 87d6d6676308 -r 46d02d47eec6 h
124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125 +++ b/h Thu Jan 01 00:00:00 1970 +0000
125 +++ b/h Thu Jan 01 00:00:00 1970 +0000
126 @@ -0,0 +1,1 @@
126 @@ -0,0 +1,1 @@
127 +foo
127 +foo
128
128
129 $ hg status
129 $ hg status
130 M h
130 M h
131
131
132 $ hg log -r . -T '{extras % "{extra}\n"}' --config alias.log=log
132 $ hg log -r . -T '{extras % "{extra}\n"}' --config alias.log=log
133 branch=default
133 branch=default
134 unamend_source=c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
134 unamend_source=c9fa1a715c1b7661c0fafb362a9f30bd75878d7d
135
135
136 Using unamend to undo an unamed (intentional)
136 Using unamend to undo an unamed (intentional)
137
137
138 $ hg unamend
138 $ hg unamend
139 $ hg exp
139 $ hg exp
140 # HG changeset patch
140 # HG changeset patch
141 # User test
141 # User test
142 # Date 0 0
142 # Date 0 0
143 # Thu Jan 01 00:00:00 1970 +0000
143 # Thu Jan 01 00:00:00 1970 +0000
144 # Node ID 850ddfc1bc662997ec6094ada958f01f0cc8070a
144 # Node ID 850ddfc1bc662997ec6094ada958f01f0cc8070a
145 # Parent 87d6d66763085b629e6d7ed56778c79827273022
145 # Parent 87d6d66763085b629e6d7ed56778c79827273022
146 Added h
146 Added h
147
147
148 diff -r 87d6d6676308 -r 850ddfc1bc66 h
148 diff -r 87d6d6676308 -r 850ddfc1bc66 h
149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
149 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150 +++ b/h Thu Jan 01 00:00:00 1970 +0000
150 +++ b/h Thu Jan 01 00:00:00 1970 +0000
151 @@ -0,0 +1,2 @@
151 @@ -0,0 +1,2 @@
152 +foo
152 +foo
153 +bar
153 +bar
154 $ hg diff
154 $ hg diff
155
155
156 Unamend on a dirty working directory
156 Unamend on a dirty working directory
157
157
158 $ echo "bar" >> a
158 $ echo "bar" >> a
159 $ hg amend
159 $ hg amend
160 $ echo "foobar" >> a
160 $ echo "foobar" >> a
161 $ echo "bar" >> b
161 $ echo "bar" >> b
162 $ hg status
162 $ hg status
163 M a
163 M a
164 M b
164 M b
165
165
166 $ hg unamend
166 $ hg unamend
167
167
168 $ hg status
168 $ hg status
169 M a
169 M a
170 M b
170 M b
171
171
172 $ hg diff
172 $ hg diff
173 diff -r ec338db45d51 a
173 diff -r ec338db45d51 a
174 --- a/a Thu Jan 01 00:00:00 1970 +0000
174 --- a/a Thu Jan 01 00:00:00 1970 +0000
175 +++ b/a Thu Jan 01 00:00:00 1970 +0000
175 +++ b/a Thu Jan 01 00:00:00 1970 +0000
176 @@ -1,1 +1,3 @@
176 @@ -1,1 +1,3 @@
177 foo
177 foo
178 +bar
178 +bar
179 +foobar
179 +foobar
180 diff -r ec338db45d51 b
180 diff -r ec338db45d51 b
181 --- a/b Thu Jan 01 00:00:00 1970 +0000
181 --- a/b Thu Jan 01 00:00:00 1970 +0000
182 +++ b/b Thu Jan 01 00:00:00 1970 +0000
182 +++ b/b Thu Jan 01 00:00:00 1970 +0000
183 @@ -1,1 +1,2 @@
183 @@ -1,1 +1,2 @@
184 foo
184 foo
185 +bar
185 +bar
186
186
187 Unamending an added file
187 Unamending an added file
188
188
189 $ hg ci -m "Added things to a and b"
189 $ hg ci -m "Added things to a and b"
190 $ echo foo > bar
190 $ echo foo > bar
191 $ hg add bar
191 $ hg add bar
192 $ hg amend
192 $ hg amend
193
193
194 $ hg unamend
194 $ hg unamend
195 $ hg status
195 $ hg status
196 A bar
196 A bar
197
197
198 $ hg revert --all
198 $ hg revert --all
199 forgetting bar
199 forgetting bar
200
200
201 Unamending a removed file
201 Unamending a removed file
202
202
203 $ hg remove a
203 $ hg remove a
204 $ hg amend
204 $ hg amend
205
205
206 $ hg unamend
206 $ hg unamend
207 $ hg status
207 $ hg status
208 R a
208 R a
209 ? bar
209 ? bar
210
210
211 $ hg revert --all
211 $ hg revert --all
212 undeleting a
212 undeleting a
213
213
214 Unamending an added file with dirty wdir status
214 Unamending an added file with dirty wdir status
215
215
216 $ hg add bar
216 $ hg add bar
217 $ hg amend
217 $ hg amend
218 $ echo bar >> bar
218 $ echo bar >> bar
219 $ hg status
219 $ hg status
220 M bar
220 M bar
221
221
222 $ hg unamend
222 $ hg unamend
223 $ hg status
223 $ hg status
224 A bar
224 A bar
225 $ hg diff
225 $ hg diff
226 diff -r 7f79409af972 bar
226 diff -r 7f79409af972 bar
227 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
227 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
228 +++ b/bar Thu Jan 01 00:00:00 1970 +0000
228 +++ b/bar Thu Jan 01 00:00:00 1970 +0000
229 @@ -0,0 +1,2 @@
229 @@ -0,0 +1,2 @@
230 +foo
230 +foo
231 +bar
231 +bar
232
232
233 $ hg revert --all
233 $ hg revert --all
234 forgetting bar
234 forgetting bar
235
235
236 Unamending in middle of a stack
236 Unamending in middle of a stack
237
237
238 $ hg glog
238 $ hg glog
239 @ 19:7f79409af972 Added things to a and b
239 @ 19:7f79409af972 Added things to a and b
240 |
240 |
241 o 12:ec338db45d51 Added h
241 o 12:ec338db45d51 Added h
242 |
242 |
243 o 6:87d6d6676308 Added g
243 o 6:87d6d6676308 Added g
244 |
244 |
245 o 5:825660c69f0c Added f
245 o 5:825660c69f0c Added f
246 |
246 |
247 o 4:aa98ab95a928 Added e
247 o 4:aa98ab95a928 Added e
248 |
248 |
249 o 3:62615734edd5 Added d
249 o 3:62615734edd5 Added d
250 |
250 |
251 o 2:28ad74487de9 Added c
251 o 2:28ad74487de9 Added c
252 |
252 |
253 o 1:29becc82797a Added b
253 o 1:29becc82797a Added b
254 |
254 |
255 o 0:18d04c59bb5d Added a
255 o 0:18d04c59bb5d Added a
256
256
257 $ hg up 5
257 $ hg up 5
258 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
258 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
259 $ echo bar >> f
259 $ echo bar >> f
260 $ hg amend
260 $ hg amend
261 $ hg rebase -s 6 -d . -q
261 $ hg rebase -s 6 -d . -q
262
262
263 $ hg glog
263 $ hg glog
264 o 23:03ddd6fc5af1 Added things to a and b
264 o 23:03ddd6fc5af1 Added things to a and b
265 |
265 |
266 o 22:3e7b64ee157b Added h
266 o 22:3e7b64ee157b Added h
267 |
267 |
268 o 21:49635b68477e Added g
268 o 21:49635b68477e Added g
269 |
269 |
270 @ 20:93f0e8ffab32 Added f
270 @ 20:93f0e8ffab32 Added f
271 |
271 |
272 o 4:aa98ab95a928 Added e
272 o 4:aa98ab95a928 Added e
273 |
273 |
274 o 3:62615734edd5 Added d
274 o 3:62615734edd5 Added d
275 |
275 |
276 o 2:28ad74487de9 Added c
276 o 2:28ad74487de9 Added c
277 |
277 |
278 o 1:29becc82797a Added b
278 o 1:29becc82797a Added b
279 |
279 |
280 o 0:18d04c59bb5d Added a
280 o 0:18d04c59bb5d Added a
281
281
282
282
283 $ hg --config experimental.evolution=createmarkers unamend
284 abort: cannot unamend changeset with children
285 [255]
286
283 $ hg unamend
287 $ hg unamend
284 abort: cannot unamend a changeset with children
285 [255]
286
288
287 Trying to unamend a public changeset
289 Trying to unamend a public changeset
288
290
289 $ hg up
291 $ hg up -C 23
290 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 $ hg phase -r . -p
293 $ hg phase -r . -p
292 $ hg unamend
294 $ hg unamend
293 abort: cannot unamend public changesets
295 abort: cannot unamend public changesets
296 (see 'hg help phases' for details)
294 [255]
297 [255]
295
298
296 Testing whether unamend retains copies or not
299 Testing whether unamend retains copies or not
297
300
298 $ hg status
301 $ hg status
299 ? bar
302 ? bar
300
303
301 $ hg mv a foo
304 $ hg mv a foo
302
305
303 $ hg ci -m "Moved a to foo"
306 $ hg ci -m "Moved a to foo"
304 $ hg exp --git
307 $ hg exp --git
305 # HG changeset patch
308 # HG changeset patch
306 # User test
309 # User test
307 # Date 0 0
310 # Date 0 0
308 # Thu Jan 01 00:00:00 1970 +0000
311 # Thu Jan 01 00:00:00 1970 +0000
309 # Node ID cfef290346fbee5126313d7e1aab51d877679b09
312 # Node ID cfef290346fbee5126313d7e1aab51d877679b09
310 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
313 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
311 Moved a to foo
314 Moved a to foo
312
315
313 diff --git a/a b/foo
316 diff --git a/a b/foo
314 rename from a
317 rename from a
315 rename to foo
318 rename to foo
316
319
317 $ hg mv b foobar
320 $ hg mv b foobar
318 $ hg diff --git
321 $ hg diff --git
319 diff --git a/b b/foobar
322 diff --git a/b b/foobar
320 rename from b
323 rename from b
321 rename to foobar
324 rename to foobar
322 $ hg amend
325 $ hg amend
323
326
324 $ hg exp --git
327 $ hg exp --git
325 # HG changeset patch
328 # HG changeset patch
326 # User test
329 # User test
327 # Date 0 0
330 # Date 0 0
328 # Thu Jan 01 00:00:00 1970 +0000
331 # Thu Jan 01 00:00:00 1970 +0000
329 # Node ID eca050985275bb271ce3092b54e56ea5c85d29a3
332 # Node ID eca050985275bb271ce3092b54e56ea5c85d29a3
330 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
333 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
331 Moved a to foo
334 Moved a to foo
332
335
333 diff --git a/a b/foo
336 diff --git a/a b/foo
334 rename from a
337 rename from a
335 rename to foo
338 rename to foo
336 diff --git a/b b/foobar
339 diff --git a/b b/foobar
337 rename from b
340 rename from b
338 rename to foobar
341 rename to foobar
339
342
340 $ hg mv c wat
343 $ hg mv c wat
341 $ hg unamend
344 $ hg unamend
342
345
343 Retained copies in new prdecessor commit
346 Retained copies in new prdecessor commit
344
347
345 $ hg exp --git
348 $ hg exp --git
346 # HG changeset patch
349 # HG changeset patch
347 # User test
350 # User test
348 # Date 0 0
351 # Date 0 0
349 # Thu Jan 01 00:00:00 1970 +0000
352 # Thu Jan 01 00:00:00 1970 +0000
350 # Node ID 552e3af4f01f620f88ca27be1f898316235b736a
353 # Node ID 552e3af4f01f620f88ca27be1f898316235b736a
351 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
354 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
352 Moved a to foo
355 Moved a to foo
353
356
354 diff --git a/a b/foo
357 diff --git a/a b/foo
355 rename from a
358 rename from a
356 rename to foo
359 rename to foo
357
360
358 Retained copies in working directoy
361 Retained copies in working directoy
359
362
360 $ hg diff --git
363 $ hg diff --git
361 diff --git a/b b/foobar
364 diff --git a/b b/foobar
362 rename from b
365 rename from b
363 rename to foobar
366 rename to foobar
364 diff --git a/c b/wat
367 diff --git a/c b/wat
365 rename from c
368 rename from c
366 rename to wat
369 rename to wat
General Comments 0
You need to be logged in to leave comments. Login now