##// END OF EJS Templates
unamend: drop unused vars, query after taking lock, use ctx.hex() for extras...
Pulkit Goyal -
r35201:9e339c97 default
parent child Browse files
Show More
@@ -1,277 +1,270 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 obsolete,
31 obsolete,
32 obsutil,
32 obsutil,
33 pycompat,
33 pycompat,
34 registrar,
34 registrar,
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, fctx.path(), fctx.data(),
80 mctx = context.memfilectx(repo, 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 wctx = repo[None]
158 wctx = repo[None]
159
159
160 if not pats and not repo.ui.configbool('experimental',
160 if not pats and not repo.ui.configbool('experimental',
161 'uncommitondirtywdir'):
161 'uncommitondirtywdir'):
162 cmdutil.bailifchanged(repo)
162 cmdutil.bailifchanged(repo)
163 if wctx.parents()[0].node() == node.nullid:
163 if wctx.parents()[0].node() == node.nullid:
164 raise error.Abort(_("cannot uncommit null changeset"))
164 raise error.Abort(_("cannot uncommit null changeset"))
165 if len(wctx.parents()) > 1:
165 if len(wctx.parents()) > 1:
166 raise error.Abort(_("cannot uncommit while merging"))
166 raise error.Abort(_("cannot uncommit while merging"))
167 old = repo['.']
167 old = repo['.']
168 if not old.mutable():
168 if not old.mutable():
169 raise error.Abort(_('cannot uncommit public changesets'))
169 raise error.Abort(_('cannot uncommit public changesets'))
170 if len(old.parents()) > 1:
170 if len(old.parents()) > 1:
171 raise error.Abort(_("cannot uncommit merge changeset"))
171 raise error.Abort(_("cannot uncommit merge changeset"))
172 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
172 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
173 if not allowunstable and old.children():
173 if not allowunstable and old.children():
174 raise error.Abort(_('cannot uncommit changeset with children'))
174 raise error.Abort(_('cannot uncommit changeset with children'))
175
175
176 with repo.transaction('uncommit'):
176 with repo.transaction('uncommit'):
177 match = scmutil.match(old, pats, opts)
177 match = scmutil.match(old, pats, opts)
178 newid = _commitfiltered(repo, old, match, opts.get('keep'))
178 newid = _commitfiltered(repo, old, match, opts.get('keep'))
179 if newid is None:
179 if newid is None:
180 ui.status(_("nothing to uncommit\n"))
180 ui.status(_("nothing to uncommit\n"))
181 return 1
181 return 1
182
182
183 mapping = {}
183 mapping = {}
184 if newid != old.p1().node():
184 if newid != old.p1().node():
185 # Move local changes on filtered changeset
185 # Move local changes on filtered changeset
186 mapping[old.node()] = (newid,)
186 mapping[old.node()] = (newid,)
187 else:
187 else:
188 # Fully removed the old commit
188 # Fully removed the old commit
189 mapping[old.node()] = ()
189 mapping[old.node()] = ()
190
190
191 scmutil.cleanupnodes(repo, mapping, 'uncommit')
191 scmutil.cleanupnodes(repo, mapping, 'uncommit')
192
192
193 with repo.dirstate.parentchange():
193 with repo.dirstate.parentchange():
194 repo.dirstate.setparents(newid, node.nullid)
194 repo.dirstate.setparents(newid, node.nullid)
195 s = repo.status(old.p1(), old, match=match)
195 s = repo.status(old.p1(), old, match=match)
196 _fixdirstate(repo, old, repo[newid], s)
196 _fixdirstate(repo, old, repo[newid], s)
197
197
198 def predecessormarkers(ctx):
198 def predecessormarkers(ctx):
199 """yields the obsolete markers marking the given changeset as a successor"""
199 """yields the obsolete markers marking the given changeset as a successor"""
200 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
200 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
201 yield obsutil.marker(ctx.repo(), data)
201 yield obsutil.marker(ctx.repo(), data)
202
202
203 @command('^unamend', [])
203 @command('^unamend', [])
204 def unamend(ui, repo, **opts):
204 def unamend(ui, repo, **opts):
205 """
205 """
206 undo the most recent amend operation on a current changeset
206 undo the most recent amend operation on a current changeset
207
207
208 This command will roll back to the previous version of a changeset,
208 This command will roll back to the previous version of a changeset,
209 leaving working directory in state in which it was before running
209 leaving working directory in state in which it was before running
210 `hg amend` (e.g. files modified as part of an amend will be
210 `hg amend` (e.g. files modified as part of an amend will be
211 marked as modified `hg status`)
211 marked as modified `hg status`)
212 """
212 """
213
213
214 unfi = repo.unfiltered()
214 unfi = repo.unfiltered()
215 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
215
216
216 # identify the commit from which to unamend
217 # identify the commit from which to unamend
217 curctx = repo['.']
218 curctx = repo['.']
218
219
219 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
220 if not curctx.mutable():
220 if not curctx.mutable():
221 raise error.Abort(_('cannot unamend public changesets'))
221 raise error.Abort(_('cannot unamend public changesets'))
222
222
223 # identify the commit to which to unamend
223 # identify the commit to which to unamend
224 markers = list(predecessormarkers(curctx))
224 markers = list(predecessormarkers(curctx))
225 if len(markers) != 1:
225 if len(markers) != 1:
226 e = _("changeset must have one predecessor, found %i predecessors")
226 e = _("changeset must have one predecessor, found %i predecessors")
227 raise error.Abort(e % len(markers))
227 raise error.Abort(e % len(markers))
228
228
229 prednode = markers[0].prednode()
229 prednode = markers[0].prednode()
230 predctx = unfi[prednode]
230 predctx = unfi[prednode]
231
231
232 if curctx.children():
232 if curctx.children():
233 raise error.Abort(_("cannot unamend a changeset with children"))
233 raise error.Abort(_("cannot unamend a changeset with children"))
234
234
235 # add an extra so that we get a new hash
235 # add an extra so that we get a new hash
236 # note: allowing unamend to undo an unamend is an intentional feature
236 # note: allowing unamend to undo an unamend is an intentional feature
237 extras = predctx.extra()
237 extras = predctx.extra()
238 extras['unamend_source'] = curctx.node()
238 extras['unamend_source'] = curctx.hex()
239
239
240 def filectxfn(repo, ctx_, path):
240 def filectxfn(repo, ctx_, path):
241 try:
241 try:
242 return predctx.filectx(path)
242 return predctx.filectx(path)
243 except KeyError:
243 except KeyError:
244 return None
244 return None
245
245
246 # Make a new commit same as predctx
246 # Make a new commit same as predctx
247 newctx = context.memctx(repo,
247 newctx = context.memctx(repo,
248 parents=(predctx.p1(), predctx.p2()),
248 parents=(predctx.p1(), predctx.p2()),
249 text=predctx.description(),
249 text=predctx.description(),
250 files=predctx.files(),
250 files=predctx.files(),
251 filectxfn=filectxfn,
251 filectxfn=filectxfn,
252 user=predctx.user(),
252 user=predctx.user(),
253 date=predctx.date(),
253 date=predctx.date(),
254 extra=extras)
254 extra=extras)
255 # phase handling
255 # phase handling
256 commitphase = curctx.phase()
256 commitphase = curctx.phase()
257 overrides = {('phases', 'new-commit'): commitphase}
257 overrides = {('phases', 'new-commit'): commitphase}
258 with repo.ui.configoverride(overrides, 'uncommit'):
258 with repo.ui.configoverride(overrides, 'uncommit'):
259 newprednode = repo.commitctx(newctx)
259 newprednode = repo.commitctx(newctx)
260
260
261 newpredctx = repo[newprednode]
261 newpredctx = repo[newprednode]
262
263 changedfiles = []
264 wctx = repo[None]
265 wm = wctx.manifest()
266 cm = newpredctx.manifest()
267 dirstate = repo.dirstate
262 dirstate = repo.dirstate
268 diff = cm.diff(wm)
269 changedfiles.extend(diff.iterkeys())
270
263
271 with dirstate.parentchange():
264 with dirstate.parentchange():
272 dirstate.setparents(newprednode, node.nullid)
265 dirstate.setparents(newprednode, node.nullid)
273 s = repo.status(predctx, curctx)
266 s = repo.status(predctx, curctx)
274 _fixdirstate(repo, curctx, newpredctx, s)
267 _fixdirstate(repo, curctx, newpredctx, s)
275
268
276 mapping = {curctx.node(): (newprednode,)}
269 mapping = {curctx.node(): (newprednode,)}
277 scmutil.cleanupnodes(repo, mapping, 'unamend')
270 scmutil.cleanupnodes(repo, mapping, 'unamend')
@@ -1,366 +1,366 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:8da14a1fd653 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 8da14a1fd653 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 8da14a1fd653c3f07fdad5760511c9e12652a306
119 # Node ID 46d02d47eec6ca096b8dcab3f8f5579c40c3dd9a
120 # Parent 87d6d66763085b629e6d7ed56778c79827273022
120 # Parent 87d6d66763085b629e6d7ed56778c79827273022
121 Added h
121 Added h
122
122
123 diff -r 87d6d6676308 -r 8da14a1fd653 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=\xc9\xfa\x1aq\\\x1bva\xc0\xfa\xfb6*\x9f0\xbdu\x87\x8d}
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 1c09887216571a9755fc9d2e7f0e41c2b49e341b
144 # Node ID 850ddfc1bc662997ec6094ada958f01f0cc8070a
145 # Parent 87d6d66763085b629e6d7ed56778c79827273022
145 # Parent 87d6d66763085b629e6d7ed56778c79827273022
146 Added h
146 Added h
147
147
148 diff -r 87d6d6676308 -r 1c0988721657 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 956548224719 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 956548224719 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 ff917aa01c86 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:ff917aa01c86 Added things to a and b
239 @ 19:7f79409af972 Added things to a and b
240 |
240 |
241 o 12:956548224719 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:2b41b42e192a Added things to a and b
264 o 23:03ddd6fc5af1 Added things to a and b
265 |
265 |
266 o 22:1860df151f01 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 unamend
283 $ hg unamend
284 abort: cannot unamend a changeset with children
284 abort: cannot unamend a changeset with children
285 [255]
285 [255]
286
286
287 Trying to unamend a public changeset
287 Trying to unamend a public changeset
288
288
289 $ hg up
289 $ hg up
290 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 $ hg phase -r . -p
291 $ hg phase -r . -p
292 $ hg unamend
292 $ hg unamend
293 abort: cannot unamend public changesets
293 abort: cannot unamend public changesets
294 [255]
294 [255]
295
295
296 Testing whether unamend retains copies or not
296 Testing whether unamend retains copies or not
297
297
298 $ hg status
298 $ hg status
299 ? bar
299 ? bar
300
300
301 $ hg mv a foo
301 $ hg mv a foo
302
302
303 $ hg ci -m "Moved a to foo"
303 $ hg ci -m "Moved a to foo"
304 $ hg exp --git
304 $ hg exp --git
305 # HG changeset patch
305 # HG changeset patch
306 # User test
306 # User test
307 # Date 0 0
307 # Date 0 0
308 # Thu Jan 01 00:00:00 1970 +0000
308 # Thu Jan 01 00:00:00 1970 +0000
309 # Node ID b087c66cada118d6c5487d3d7cb29cac239bd98a
309 # Node ID cfef290346fbee5126313d7e1aab51d877679b09
310 # Parent 2b41b42e192adc425b106643c3fc89170d6b8add
310 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
311 Moved a to foo
311 Moved a to foo
312
312
313 diff --git a/a b/foo
313 diff --git a/a b/foo
314 rename from a
314 rename from a
315 rename to foo
315 rename to foo
316
316
317 $ hg mv b foobar
317 $ hg mv b foobar
318 $ hg diff --git
318 $ hg diff --git
319 diff --git a/b b/foobar
319 diff --git a/b b/foobar
320 rename from b
320 rename from b
321 rename to foobar
321 rename to foobar
322 $ hg amend
322 $ hg amend
323
323
324 $ hg exp --git
324 $ hg exp --git
325 # HG changeset patch
325 # HG changeset patch
326 # User test
326 # User test
327 # Date 0 0
327 # Date 0 0
328 # Thu Jan 01 00:00:00 1970 +0000
328 # Thu Jan 01 00:00:00 1970 +0000
329 # Node ID 9fa06fb09a83a86ec7368d15004dbc52ac1a5d2e
329 # Node ID eca050985275bb271ce3092b54e56ea5c85d29a3
330 # Parent 2b41b42e192adc425b106643c3fc89170d6b8add
330 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
331 Moved a to foo
331 Moved a to foo
332
332
333 diff --git a/a b/foo
333 diff --git a/a b/foo
334 rename from a
334 rename from a
335 rename to foo
335 rename to foo
336 diff --git a/b b/foobar
336 diff --git a/b b/foobar
337 rename from b
337 rename from b
338 rename to foobar
338 rename to foobar
339
339
340 $ hg mv c wat
340 $ hg mv c wat
341 $ hg unamend
341 $ hg unamend
342
342
343 Retained copies in new prdecessor commit
343 Retained copies in new prdecessor commit
344
344
345 $ hg exp --git
345 $ hg exp --git
346 # HG changeset patch
346 # HG changeset patch
347 # User test
347 # User test
348 # Date 0 0
348 # Date 0 0
349 # Thu Jan 01 00:00:00 1970 +0000
349 # Thu Jan 01 00:00:00 1970 +0000
350 # Node ID 4cf9987c9b941f615930e7c46307b4dbf35697cf
350 # Node ID 552e3af4f01f620f88ca27be1f898316235b736a
351 # Parent 2b41b42e192adc425b106643c3fc89170d6b8add
351 # Parent 03ddd6fc5af19e028c44a2fd6d790dd22712f231
352 Moved a to foo
352 Moved a to foo
353
353
354 diff --git a/a b/foo
354 diff --git a/a b/foo
355 rename from a
355 rename from a
356 rename to foo
356 rename to foo
357
357
358 Retained copies in working directoy
358 Retained copies in working directoy
359
359
360 $ hg diff --git
360 $ hg diff --git
361 diff --git a/b b/foobar
361 diff --git a/b b/foobar
362 rename from b
362 rename from b
363 rename to foobar
363 rename to foobar
364 diff --git a/c b/wat
364 diff --git a/c b/wat
365 rename from c
365 rename from c
366 rename to wat
366 rename to wat
General Comments 0
You need to be logged in to leave comments. Login now