##// END OF EJS Templates
uncommit: add flag --allow-dirty-working-copy...
Navaneeth Suresh -
r42026:aa284d9a default
parent child Browse files
Show More
@@ -1,259 +1,262 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 as copiesmod,
28 copies as copiesmod,
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 configitem('experimental', 'uncommit.keep',
47 configitem('experimental', 'uncommit.keep',
48 default=False,
48 default=False,
49 )
49 )
50
50
51 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
51 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
52 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
52 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
53 # be specifying the version(s) of Mercurial they are tested with, or
53 # be specifying the version(s) of Mercurial they are tested with, or
54 # leave the attribute unspecified.
54 # leave the attribute unspecified.
55 testedwith = 'ships-with-hg-core'
55 testedwith = 'ships-with-hg-core'
56
56
57 def _commitfiltered(repo, ctx, match, keepcommit):
57 def _commitfiltered(repo, ctx, match, keepcommit):
58 """Recommit ctx with changed files not in match. Return the new
58 """Recommit ctx with changed files not in match. Return the new
59 node identifier, or None if nothing changed.
59 node identifier, or None if nothing changed.
60 """
60 """
61 base = ctx.p1()
61 base = ctx.p1()
62 # ctx
62 # ctx
63 initialfiles = set(ctx.files())
63 initialfiles = set(ctx.files())
64 exclude = set(f for f in initialfiles if match(f))
64 exclude = set(f for f in initialfiles if match(f))
65
65
66 # No files matched commit, so nothing excluded
66 # No files matched commit, so nothing excluded
67 if not exclude:
67 if not exclude:
68 return None
68 return None
69
69
70 # return the p1 so that we don't create an obsmarker later
70 # return the p1 so that we don't create an obsmarker later
71 if not keepcommit:
71 if not keepcommit:
72 return ctx.p1().node()
72 return ctx.p1().node()
73
73
74 files = (initialfiles - exclude)
74 files = (initialfiles - exclude)
75 # Filter copies
75 # Filter copies
76 copied = copiesmod.pathcopies(base, ctx)
76 copied = copiesmod.pathcopies(base, ctx)
77 copied = dict((dst, src) for dst, src in copied.iteritems()
77 copied = dict((dst, src) for dst, src in copied.iteritems()
78 if dst in files)
78 if dst in files)
79 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
79 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
80 if path not in contentctx:
80 if path not in contentctx:
81 return None
81 return None
82 fctx = contentctx[path]
82 fctx = contentctx[path]
83 mctx = context.memfilectx(repo, memctx, fctx.path(), fctx.data(),
83 mctx = context.memfilectx(repo, memctx, fctx.path(), fctx.data(),
84 fctx.islink(),
84 fctx.islink(),
85 fctx.isexec(),
85 fctx.isexec(),
86 copied=copied.get(path))
86 copied=copied.get(path))
87 return mctx
87 return mctx
88
88
89 if not files:
89 if not files:
90 repo.ui.status(_("note: keeping empty commit\n"))
90 repo.ui.status(_("note: keeping empty commit\n"))
91
91
92 new = context.memctx(repo,
92 new = context.memctx(repo,
93 parents=[base.node(), node.nullid],
93 parents=[base.node(), node.nullid],
94 text=ctx.description(),
94 text=ctx.description(),
95 files=files,
95 files=files,
96 filectxfn=filectxfn,
96 filectxfn=filectxfn,
97 user=ctx.user(),
97 user=ctx.user(),
98 date=ctx.date(),
98 date=ctx.date(),
99 extra=ctx.extra())
99 extra=ctx.extra())
100 return repo.commitctx(new)
100 return repo.commitctx(new)
101
101
102 def _fixdirstate(repo, oldctx, newctx, match=None):
102 def _fixdirstate(repo, oldctx, newctx, match=None):
103 """ fix the dirstate after switching the working directory from oldctx to
103 """ fix the dirstate after switching the working directory from oldctx to
104 newctx which can be result of either unamend or uncommit.
104 newctx which can be result of either unamend or uncommit.
105 """
105 """
106 ds = repo.dirstate
106 ds = repo.dirstate
107 ds.setparents(newctx.node(), node.nullid)
107 ds.setparents(newctx.node(), node.nullid)
108 copies = dict(ds.copies())
108 copies = dict(ds.copies())
109 s = newctx.status(oldctx, match=match)
109 s = newctx.status(oldctx, match=match)
110 for f in s.modified:
110 for f in s.modified:
111 if ds[f] == 'r':
111 if ds[f] == 'r':
112 # modified + removed -> removed
112 # modified + removed -> removed
113 continue
113 continue
114 ds.normallookup(f)
114 ds.normallookup(f)
115
115
116 for f in s.added:
116 for f in s.added:
117 if ds[f] == 'r':
117 if ds[f] == 'r':
118 # added + removed -> unknown
118 # added + removed -> unknown
119 ds.drop(f)
119 ds.drop(f)
120 elif ds[f] != 'a':
120 elif ds[f] != 'a':
121 ds.add(f)
121 ds.add(f)
122
122
123 for f in s.removed:
123 for f in s.removed:
124 if ds[f] == 'a':
124 if ds[f] == 'a':
125 # removed + added -> normal
125 # removed + added -> normal
126 ds.normallookup(f)
126 ds.normallookup(f)
127 elif ds[f] != 'r':
127 elif ds[f] != 'r':
128 ds.remove(f)
128 ds.remove(f)
129
129
130 # Merge old parent and old working dir copies
130 # Merge old parent and old working dir copies
131 oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
131 oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
132 oldcopies.update(copies)
132 oldcopies.update(copies)
133 copies = dict((dst, oldcopies.get(src, src))
133 copies = dict((dst, oldcopies.get(src, src))
134 for dst, src in oldcopies.iteritems())
134 for dst, src in oldcopies.iteritems())
135 # Adjust the dirstate copies
135 # Adjust the dirstate copies
136 for dst, src in copies.iteritems():
136 for dst, src in copies.iteritems():
137 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
137 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
138 src = None
138 src = None
139 ds.copy(src, dst)
139 ds.copy(src, dst)
140
140
141 @command('uncommit',
141 @command('uncommit',
142 [('', 'keep', None, _('allow an empty commit after uncommiting')),
142 [('', 'keep', None, _('allow an empty commit after uncommiting')),
143 ('', 'allow-dirty-working-copy', False,
144 _('allow uncommit with outstanding changes'))
143 ] + commands.walkopts,
145 ] + commands.walkopts,
144 _('[OPTION]... [FILE]...'),
146 _('[OPTION]... [FILE]...'),
145 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
147 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
146 def uncommit(ui, repo, *pats, **opts):
148 def uncommit(ui, repo, *pats, **opts):
147 """uncommit part or all of a local changeset
149 """uncommit part or all of a local changeset
148
150
149 This command undoes the effect of a local commit, returning the affected
151 This command undoes the effect of a local commit, returning the affected
150 files to their uncommitted state. This means that files modified or
152 files to their uncommitted state. This means that files modified or
151 deleted in the changeset will be left unchanged, and so will remain
153 deleted in the changeset will be left unchanged, and so will remain
152 modified in the working directory.
154 modified in the working directory.
153
155
154 If no files are specified, the commit will be pruned, unless --keep is
156 If no files are specified, the commit will be pruned, unless --keep is
155 given.
157 given.
156 """
158 """
157 opts = pycompat.byteskwargs(opts)
159 opts = pycompat.byteskwargs(opts)
158
160
159 with repo.wlock(), repo.lock():
161 with repo.wlock(), repo.lock():
160
162
161 m, a, r, d = repo.status()[:4]
163 m, a, r, d = repo.status()[:4]
162 isdirtypath = any(set(m + a + r + d) & set(pats))
164 isdirtypath = any(set(m + a + r + d) & set(pats))
163 if (not repo.ui.configbool('experimental', 'uncommitondirtywdir') and
165 allowdirtywcopy = (opts['allow_dirty_working_copy'] or
164 (not pats or isdirtypath)):
166 repo.ui.configbool('experimental', 'uncommitondirtywdir'))
167 if not allowdirtywcopy and (not pats or isdirtypath):
165 cmdutil.bailifchanged(repo, hint=_('requires '
168 cmdutil.bailifchanged(repo, hint=_('requires '
166 'experimental.uncommitondirtywdir to uncommit'))
169 '--allow-dirty-working-copy to uncommit'))
167 old = repo['.']
170 old = repo['.']
168 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
171 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
169 if len(old.parents()) > 1:
172 if len(old.parents()) > 1:
170 raise error.Abort(_("cannot uncommit merge changeset"))
173 raise error.Abort(_("cannot uncommit merge changeset"))
171
174
172 with repo.transaction('uncommit'):
175 with repo.transaction('uncommit'):
173 match = scmutil.match(old, pats, opts)
176 match = scmutil.match(old, pats, opts)
174 keepcommit = pats
177 keepcommit = pats
175 if not keepcommit:
178 if not keepcommit:
176 if opts.get('keep') is not None:
179 if opts.get('keep') is not None:
177 keepcommit = opts.get('keep')
180 keepcommit = opts.get('keep')
178 else:
181 else:
179 keepcommit = ui.configbool('experimental', 'uncommit.keep')
182 keepcommit = ui.configbool('experimental', 'uncommit.keep')
180 newid = _commitfiltered(repo, old, match, keepcommit)
183 newid = _commitfiltered(repo, old, match, keepcommit)
181 if newid is None:
184 if newid is None:
182 ui.status(_("nothing to uncommit\n"))
185 ui.status(_("nothing to uncommit\n"))
183 return 1
186 return 1
184
187
185 mapping = {}
188 mapping = {}
186 if newid != old.p1().node():
189 if newid != old.p1().node():
187 # Move local changes on filtered changeset
190 # Move local changes on filtered changeset
188 mapping[old.node()] = (newid,)
191 mapping[old.node()] = (newid,)
189 else:
192 else:
190 # Fully removed the old commit
193 # Fully removed the old commit
191 mapping[old.node()] = ()
194 mapping[old.node()] = ()
192
195
193 with repo.dirstate.parentchange():
196 with repo.dirstate.parentchange():
194 _fixdirstate(repo, old, repo[newid], match)
197 _fixdirstate(repo, old, repo[newid], match)
195
198
196 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True)
199 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True)
197
200
198 def predecessormarkers(ctx):
201 def predecessormarkers(ctx):
199 """yields the obsolete markers marking the given changeset as a successor"""
202 """yields the obsolete markers marking the given changeset as a successor"""
200 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
203 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
201 yield obsutil.marker(ctx.repo(), data)
204 yield obsutil.marker(ctx.repo(), data)
202
205
203 @command('unamend', [], helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
206 @command('unamend', [], helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
204 helpbasic=True)
207 helpbasic=True)
205 def unamend(ui, repo, **opts):
208 def unamend(ui, repo, **opts):
206 """undo the most recent amend operation on a current changeset
209 """undo the most recent amend operation on a current changeset
207
210
208 This command will roll back to the previous version of a changeset,
211 This command will roll back to the previous version of a changeset,
209 leaving working directory in state in which it was before running
212 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
213 `hg amend` (e.g. files modified as part of an amend will be
211 marked as modified `hg status`)
214 marked as modified `hg status`)
212 """
215 """
213
216
214 unfi = repo.unfiltered()
217 unfi = repo.unfiltered()
215 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
218 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
216
219
217 # identify the commit from which to unamend
220 # identify the commit from which to unamend
218 curctx = repo['.']
221 curctx = repo['.']
219
222
220 rewriteutil.precheck(repo, [curctx.rev()], 'unamend')
223 rewriteutil.precheck(repo, [curctx.rev()], 'unamend')
221
224
222 # identify the commit to which to unamend
225 # identify the commit to which to unamend
223 markers = list(predecessormarkers(curctx))
226 markers = list(predecessormarkers(curctx))
224 if len(markers) != 1:
227 if len(markers) != 1:
225 e = _("changeset must have one predecessor, found %i predecessors")
228 e = _("changeset must have one predecessor, found %i predecessors")
226 raise error.Abort(e % len(markers))
229 raise error.Abort(e % len(markers))
227
230
228 prednode = markers[0].prednode()
231 prednode = markers[0].prednode()
229 predctx = unfi[prednode]
232 predctx = unfi[prednode]
230
233
231 # add an extra so that we get a new hash
234 # add an extra so that we get a new hash
232 # note: allowing unamend to undo an unamend is an intentional feature
235 # note: allowing unamend to undo an unamend is an intentional feature
233 extras = predctx.extra()
236 extras = predctx.extra()
234 extras['unamend_source'] = curctx.hex()
237 extras['unamend_source'] = curctx.hex()
235
238
236 def filectxfn(repo, ctx_, path):
239 def filectxfn(repo, ctx_, path):
237 try:
240 try:
238 return predctx.filectx(path)
241 return predctx.filectx(path)
239 except KeyError:
242 except KeyError:
240 return None
243 return None
241
244
242 # Make a new commit same as predctx
245 # Make a new commit same as predctx
243 newctx = context.memctx(repo,
246 newctx = context.memctx(repo,
244 parents=(predctx.p1(), predctx.p2()),
247 parents=(predctx.p1(), predctx.p2()),
245 text=predctx.description(),
248 text=predctx.description(),
246 files=predctx.files(),
249 files=predctx.files(),
247 filectxfn=filectxfn,
250 filectxfn=filectxfn,
248 user=predctx.user(),
251 user=predctx.user(),
249 date=predctx.date(),
252 date=predctx.date(),
250 extra=extras)
253 extra=extras)
251 newprednode = repo.commitctx(newctx)
254 newprednode = repo.commitctx(newctx)
252 newpredctx = repo[newprednode]
255 newpredctx = repo[newprednode]
253 dirstate = repo.dirstate
256 dirstate = repo.dirstate
254
257
255 with dirstate.parentchange():
258 with dirstate.parentchange():
256 _fixdirstate(repo, curctx, newpredctx)
259 _fixdirstate(repo, curctx, newpredctx)
257
260
258 mapping = {curctx.node(): (newprednode,)}
261 mapping = {curctx.node(): (newprednode,)}
259 scmutil.cleanupnodes(repo, mapping, 'unamend', fixphase=True)
262 scmutil.cleanupnodes(repo, mapping, 'unamend', fixphase=True)
@@ -1,514 +1,515 b''
1 Test uncommit - set up the config
1 Test uncommit - set up the config
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [experimental]
4 > [experimental]
5 > evolution.createmarkers=True
5 > evolution.createmarkers=True
6 > evolution.allowunstable=True
6 > evolution.allowunstable=True
7 > [extensions]
7 > [extensions]
8 > uncommit =
8 > uncommit =
9 > drawdag=$TESTDIR/drawdag.py
9 > drawdag=$TESTDIR/drawdag.py
10 > EOF
10 > EOF
11
11
12 Build up a repo
12 Build up a repo
13
13
14 $ hg init repo
14 $ hg init repo
15 $ cd repo
15 $ cd repo
16 $ hg bookmark foo
16 $ hg bookmark foo
17
17
18 Help for uncommit
18 Help for uncommit
19
19
20 $ hg help uncommit
20 $ hg help uncommit
21 hg uncommit [OPTION]... [FILE]...
21 hg uncommit [OPTION]... [FILE]...
22
22
23 uncommit part or all of a local changeset
23 uncommit part or all of a local changeset
24
24
25 This command undoes the effect of a local commit, returning the affected
25 This command undoes the effect of a local commit, returning the affected
26 files to their uncommitted state. This means that files modified or
26 files to their uncommitted state. This means that files modified or
27 deleted in the changeset will be left unchanged, and so will remain
27 deleted in the changeset will be left unchanged, and so will remain
28 modified in the working directory.
28 modified in the working directory.
29
29
30 If no files are specified, the commit will be pruned, unless --keep is
30 If no files are specified, the commit will be pruned, unless --keep is
31 given.
31 given.
32
32
33 (use 'hg help -e uncommit' to show help for the uncommit extension)
33 (use 'hg help -e uncommit' to show help for the uncommit extension)
34
34
35 options ([+] can be repeated):
35 options ([+] can be repeated):
36
36
37 --keep allow an empty commit after uncommiting
37 --keep allow an empty commit after uncommiting
38 -I --include PATTERN [+] include names matching the given patterns
38 --allow-dirty-working-copy allow uncommit with outstanding changes
39 -X --exclude PATTERN [+] exclude names matching the given patterns
39 -I --include PATTERN [+] include names matching the given patterns
40 -X --exclude PATTERN [+] exclude names matching the given patterns
40
41
41 (some details hidden, use --verbose to show complete help)
42 (some details hidden, use --verbose to show complete help)
42
43
43 Uncommit with no commits should fail
44 Uncommit with no commits should fail
44
45
45 $ hg uncommit
46 $ hg uncommit
46 abort: cannot uncommit null changeset
47 abort: cannot uncommit null changeset
47 (no changeset checked out)
48 (no changeset checked out)
48 [255]
49 [255]
49
50
50 Create some commits
51 Create some commits
51
52
52 $ touch files
53 $ touch files
53 $ hg add files
54 $ hg add files
54 $ for i in a ab abc abcd abcde; do echo $i > files; echo $i > file-$i; hg add file-$i; hg commit -m "added file-$i"; done
55 $ for i in a ab abc abcd abcde; do echo $i > files; echo $i > file-$i; hg add file-$i; hg commit -m "added file-$i"; done
55 $ ls
56 $ ls
56 file-a
57 file-a
57 file-ab
58 file-ab
58 file-abc
59 file-abc
59 file-abcd
60 file-abcd
60 file-abcde
61 file-abcde
61 files
62 files
62
63
63 $ hg log -G -T '{rev}:{node} {desc}' --hidden
64 $ hg log -G -T '{rev}:{node} {desc}' --hidden
64 @ 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
65 @ 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
65 |
66 |
66 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
67 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
67 |
68 |
68 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
69 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
69 |
70 |
70 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
71 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
71 |
72 |
72 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
73 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
73
74
74 Simple uncommit off the top, also moves bookmark
75 Simple uncommit off the top, also moves bookmark
75
76
76 $ hg bookmark
77 $ hg bookmark
77 * foo 4:6c4fd43ed714
78 * foo 4:6c4fd43ed714
78 $ hg uncommit
79 $ hg uncommit
79 $ hg status
80 $ hg status
80 M files
81 M files
81 A file-abcde
82 A file-abcde
82 $ hg bookmark
83 $ hg bookmark
83 * foo 3:6db330d65db4
84 * foo 3:6db330d65db4
84
85
85 $ hg log -G -T '{rev}:{node} {desc}' --hidden
86 $ hg log -G -T '{rev}:{node} {desc}' --hidden
86 x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
87 x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
87 |
88 |
88 @ 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
89 @ 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
89 |
90 |
90 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
91 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
91 |
92 |
92 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
93 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
93 |
94 |
94 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
95 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
95
96
96
97
97 Recommit
98 Recommit
98
99
99 $ hg commit -m 'new change abcde'
100 $ hg commit -m 'new change abcde'
100 $ hg status
101 $ hg status
101 $ hg heads -T '{rev}:{node} {desc}'
102 $ hg heads -T '{rev}:{node} {desc}'
102 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde (no-eol)
103 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde (no-eol)
103
104
104 Uncommit of non-existent and unchanged files has no effect
105 Uncommit of non-existent and unchanged files has no effect
105 $ hg uncommit nothinghere
106 $ hg uncommit nothinghere
106 nothing to uncommit
107 nothing to uncommit
107 [1]
108 [1]
108 $ hg status
109 $ hg status
109 $ hg uncommit file-abc
110 $ hg uncommit file-abc
110 nothing to uncommit
111 nothing to uncommit
111 [1]
112 [1]
112 $ hg status
113 $ hg status
113
114
114 Try partial uncommit, also moves bookmark
115 Try partial uncommit, also moves bookmark
115
116
116 $ hg bookmark
117 $ hg bookmark
117 * foo 5:0c07a3ccda77
118 * foo 5:0c07a3ccda77
118 $ hg uncommit files
119 $ hg uncommit files
119 $ hg status
120 $ hg status
120 M files
121 M files
121 $ hg bookmark
122 $ hg bookmark
122 * foo 6:3727deee06f7
123 * foo 6:3727deee06f7
123 $ hg heads -T '{rev}:{node} {desc}'
124 $ hg heads -T '{rev}:{node} {desc}'
124 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde (no-eol)
125 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde (no-eol)
125 $ hg log -r . -p -T '{rev}:{node} {desc}'
126 $ hg log -r . -p -T '{rev}:{node} {desc}'
126 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcdediff -r 6db330d65db4 -r 3727deee06f7 file-abcde
127 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcdediff -r 6db330d65db4 -r 3727deee06f7 file-abcde
127 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
128 +++ b/file-abcde Thu Jan 01 00:00:00 1970 +0000
129 +++ b/file-abcde Thu Jan 01 00:00:00 1970 +0000
129 @@ -0,0 +1,1 @@
130 @@ -0,0 +1,1 @@
130 +abcde
131 +abcde
131
132
132 $ hg log -G -T '{rev}:{node} {desc}' --hidden
133 $ hg log -G -T '{rev}:{node} {desc}' --hidden
133 @ 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
134 @ 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
134 |
135 |
135 | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
136 | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
136 |/
137 |/
137 | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
138 | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
138 |/
139 |/
139 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
140 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
140 |
141 |
141 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
142 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
142 |
143 |
143 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
144 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
144 |
145 |
145 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
146 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
146
147
147 $ hg commit -m 'update files for abcde'
148 $ hg commit -m 'update files for abcde'
148
149
149 Uncommit with dirty state
150 Uncommit with dirty state
150
151
151 $ echo "foo" >> files
152 $ echo "foo" >> files
152 $ cat files
153 $ cat files
153 abcde
154 abcde
154 foo
155 foo
155 $ hg status
156 $ hg status
156 M files
157 M files
157 $ hg uncommit
158 $ hg uncommit
158 abort: uncommitted changes
159 abort: uncommitted changes
159 (requires experimental.uncommitondirtywdir to uncommit)
160 (requires --allow-dirty-working-copy to uncommit)
160 [255]
161 [255]
161 $ hg uncommit files
162 $ hg uncommit files
162 abort: uncommitted changes
163 abort: uncommitted changes
163 (requires experimental.uncommitondirtywdir to uncommit)
164 (requires --allow-dirty-working-copy to uncommit)
164 [255]
165 [255]
165 $ cat files
166 $ cat files
166 abcde
167 abcde
167 foo
168 foo
168 $ hg commit --amend -m "files abcde + foo"
169 $ hg commit --amend -m "files abcde + foo"
169
170
170 Testing the 'experimental.uncommitondirtywdir' config
171 Testing the 'experimental.uncommitondirtywdir' config
171
172
172 $ echo "bar" >> files
173 $ echo "bar" >> files
173 $ hg uncommit
174 $ hg uncommit
174 abort: uncommitted changes
175 abort: uncommitted changes
175 (requires experimental.uncommitondirtywdir to uncommit)
176 (requires --allow-dirty-working-copy to uncommit)
176 [255]
177 [255]
177 $ hg uncommit --config experimental.uncommitondirtywdir=True
178 $ hg uncommit --config experimental.uncommitondirtywdir=True
178 $ hg commit -m "files abcde + foo"
179 $ hg commit -m "files abcde + foo"
179
180
180 Uncommit in the middle of a stack, does not move bookmark
181 Uncommit in the middle of a stack, does not move bookmark
181
182
182 $ hg checkout '.^^^'
183 $ hg checkout '.^^^'
183 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
184 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
184 (leaving bookmark foo)
185 (leaving bookmark foo)
185 $ hg log -r . -p -T '{rev}:{node} {desc}'
186 $ hg log -r . -p -T '{rev}:{node} {desc}'
186 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abcdiff -r 69a232e754b0 -r abf2df566fc1 file-abc
187 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abcdiff -r 69a232e754b0 -r abf2df566fc1 file-abc
187 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
188 +++ b/file-abc Thu Jan 01 00:00:00 1970 +0000
189 +++ b/file-abc Thu Jan 01 00:00:00 1970 +0000
189 @@ -0,0 +1,1 @@
190 @@ -0,0 +1,1 @@
190 +abc
191 +abc
191 diff -r 69a232e754b0 -r abf2df566fc1 files
192 diff -r 69a232e754b0 -r abf2df566fc1 files
192 --- a/files Thu Jan 01 00:00:00 1970 +0000
193 --- a/files Thu Jan 01 00:00:00 1970 +0000
193 +++ b/files Thu Jan 01 00:00:00 1970 +0000
194 +++ b/files Thu Jan 01 00:00:00 1970 +0000
194 @@ -1,1 +1,1 @@
195 @@ -1,1 +1,1 @@
195 -ab
196 -ab
196 +abc
197 +abc
197
198
198 $ hg bookmark
199 $ hg bookmark
199 foo 9:48e5bd7cd583
200 foo 9:48e5bd7cd583
200 $ hg uncommit
201 $ hg uncommit
201 3 new orphan changesets
202 3 new orphan changesets
202 $ hg status
203 $ hg status
203 M files
204 M files
204 A file-abc
205 A file-abc
205 $ hg heads -T '{rev}:{node} {desc}'
206 $ hg heads -T '{rev}:{node} {desc}'
206 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo (no-eol)
207 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo (no-eol)
207 $ hg bookmark
208 $ hg bookmark
208 foo 9:48e5bd7cd583
209 foo 9:48e5bd7cd583
209 $ hg commit -m 'new abc'
210 $ hg commit -m 'new abc'
210 created new head
211 created new head
211
212
212 Partial uncommit in the middle, does not move bookmark
213 Partial uncommit in the middle, does not move bookmark
213
214
214 $ hg checkout '.^'
215 $ hg checkout '.^'
215 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
216 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
216 $ hg log -r . -p -T '{rev}:{node} {desc}'
217 $ hg log -r . -p -T '{rev}:{node} {desc}'
217 1:69a232e754b08d568c4899475faf2eb44b857802 added file-abdiff -r 3004d2d9b508 -r 69a232e754b0 file-ab
218 1:69a232e754b08d568c4899475faf2eb44b857802 added file-abdiff -r 3004d2d9b508 -r 69a232e754b0 file-ab
218 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
219 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
219 +++ b/file-ab Thu Jan 01 00:00:00 1970 +0000
220 +++ b/file-ab Thu Jan 01 00:00:00 1970 +0000
220 @@ -0,0 +1,1 @@
221 @@ -0,0 +1,1 @@
221 +ab
222 +ab
222 diff -r 3004d2d9b508 -r 69a232e754b0 files
223 diff -r 3004d2d9b508 -r 69a232e754b0 files
223 --- a/files Thu Jan 01 00:00:00 1970 +0000
224 --- a/files Thu Jan 01 00:00:00 1970 +0000
224 +++ b/files Thu Jan 01 00:00:00 1970 +0000
225 +++ b/files Thu Jan 01 00:00:00 1970 +0000
225 @@ -1,1 +1,1 @@
226 @@ -1,1 +1,1 @@
226 -a
227 -a
227 +ab
228 +ab
228
229
229 $ hg bookmark
230 $ hg bookmark
230 foo 9:48e5bd7cd583
231 foo 9:48e5bd7cd583
231 $ hg uncommit file-ab
232 $ hg uncommit file-ab
232 1 new orphan changesets
233 1 new orphan changesets
233 $ hg status
234 $ hg status
234 A file-ab
235 A file-ab
235
236
236 $ hg heads -T '{rev}:{node} {desc}\n'
237 $ hg heads -T '{rev}:{node} {desc}\n'
237 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
238 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
238 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
239 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
239 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
240 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
240
241
241 $ hg bookmark
242 $ hg bookmark
242 foo 9:48e5bd7cd583
243 foo 9:48e5bd7cd583
243 $ hg commit -m 'update ab'
244 $ hg commit -m 'update ab'
244 $ hg status
245 $ hg status
245 $ hg heads -T '{rev}:{node} {desc}\n'
246 $ hg heads -T '{rev}:{node} {desc}\n'
246 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
247 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
247 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
248 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
248 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
249 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
249
250
250 $ hg log -G -T '{rev}:{node} {desc}' --hidden
251 $ hg log -G -T '{rev}:{node} {desc}' --hidden
251 @ 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
252 @ 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
252 |
253 |
253 o 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
254 o 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
254 |
255 |
255 | * 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
256 | * 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
256 | |
257 | |
257 | | * 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
258 | | * 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
258 | | |
259 | | |
259 | | | x 8:84beeba0ac30e19521c036e4d2dd3a5fa02586ff files abcde + foo
260 | | | x 8:84beeba0ac30e19521c036e4d2dd3a5fa02586ff files abcde + foo
260 | | |/
261 | | |/
261 | | | x 7:0977fa602c2fd7d8427ed4e7ee15ea13b84c9173 update files for abcde
262 | | | x 7:0977fa602c2fd7d8427ed4e7ee15ea13b84c9173 update files for abcde
262 | | |/
263 | | |/
263 | | * 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
264 | | * 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
264 | | |
265 | | |
265 | | | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
266 | | | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
266 | | |/
267 | | |/
267 | | | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
268 | | | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
268 | | |/
269 | | |/
269 | | * 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
270 | | * 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
270 | | |
271 | | |
271 | | x 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
272 | | x 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
272 | |/
273 | |/
273 | x 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
274 | x 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
274 |/
275 |/
275 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
276 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
276
277
277 Uncommit with draft parent
278 Uncommit with draft parent
278
279
279 $ hg uncommit
280 $ hg uncommit
280 $ hg phase -r .
281 $ hg phase -r .
281 11: draft
282 11: draft
282 $ hg commit -m 'update ab again'
283 $ hg commit -m 'update ab again'
283
284
284 Phase is preserved
285 Phase is preserved
285
286
286 $ hg uncommit --keep --config phases.new-commit=secret
287 $ hg uncommit --keep --config phases.new-commit=secret
287 note: keeping empty commit
288 note: keeping empty commit
288 $ hg phase -r .
289 $ hg phase -r .
289 14: draft
290 14: draft
290 $ hg commit --amend -m 'update ab again'
291 $ hg commit --amend -m 'update ab again'
291
292
292 Uncommit with public parent
293 Uncommit with public parent
293
294
294 $ hg phase -p "::.^"
295 $ hg phase -p "::.^"
295 $ hg uncommit
296 $ hg uncommit
296 $ hg phase -r .
297 $ hg phase -r .
297 11: public
298 11: public
298
299
299 Partial uncommit with public parent
300 Partial uncommit with public parent
300
301
301 $ echo xyz > xyz
302 $ echo xyz > xyz
302 $ hg add xyz
303 $ hg add xyz
303 $ hg commit -m "update ab and add xyz"
304 $ hg commit -m "update ab and add xyz"
304 $ hg uncommit xyz
305 $ hg uncommit xyz
305 $ hg status
306 $ hg status
306 A xyz
307 A xyz
307 $ hg phase -r .
308 $ hg phase -r .
308 17: draft
309 17: draft
309 $ hg phase -r ".^"
310 $ hg phase -r ".^"
310 11: public
311 11: public
311
312
312 Uncommit with --keep or experimental.uncommit.keep leaves an empty changeset
313 Uncommit with --keep or experimental.uncommit.keep leaves an empty changeset
313
314
314 $ cd $TESTTMP
315 $ cd $TESTTMP
315 $ hg init repo1
316 $ hg init repo1
316 $ cd repo1
317 $ cd repo1
317 $ hg debugdrawdag <<'EOS'
318 $ hg debugdrawdag <<'EOS'
318 > Q
319 > Q
319 > |
320 > |
320 > P
321 > P
321 > EOS
322 > EOS
322 $ hg up Q -q
323 $ hg up Q -q
323 $ hg uncommit --keep
324 $ hg uncommit --keep
324 note: keeping empty commit
325 note: keeping empty commit
325 $ hg log -G -T '{desc} FILES: {files}'
326 $ hg log -G -T '{desc} FILES: {files}'
326 @ Q FILES:
327 @ Q FILES:
327 |
328 |
328 | x Q FILES: Q
329 | x Q FILES: Q
329 |/
330 |/
330 o P FILES: P
331 o P FILES: P
331
332
332 $ cat >> .hg/hgrc <<EOF
333 $ cat >> .hg/hgrc <<EOF
333 > [experimental]
334 > [experimental]
334 > uncommit.keep=True
335 > uncommit.keep=True
335 > EOF
336 > EOF
336 $ hg ci --amend
337 $ hg ci --amend
337 $ hg uncommit
338 $ hg uncommit
338 note: keeping empty commit
339 note: keeping empty commit
339 $ hg log -G -T '{desc} FILES: {files}'
340 $ hg log -G -T '{desc} FILES: {files}'
340 @ Q FILES:
341 @ Q FILES:
341 |
342 |
342 | x Q FILES: Q
343 | x Q FILES: Q
343 |/
344 |/
344 o P FILES: P
345 o P FILES: P
345
346
346 $ hg status
347 $ hg status
347 A Q
348 A Q
348 $ hg ci --amend
349 $ hg ci --amend
349 $ hg uncommit --no-keep
350 $ hg uncommit --no-keep
350 $ hg log -G -T '{desc} FILES: {files}'
351 $ hg log -G -T '{desc} FILES: {files}'
351 x Q FILES: Q
352 x Q FILES: Q
352 |
353 |
353 @ P FILES: P
354 @ P FILES: P
354
355
355 $ hg status
356 $ hg status
356 A Q
357 A Q
357 $ cd ..
358 $ cd ..
358 $ rm -rf repo1
359 $ rm -rf repo1
359
360
360 Testing uncommit while merge
361 Testing uncommit while merge
361
362
362 $ hg init repo2
363 $ hg init repo2
363 $ cd repo2
364 $ cd repo2
364
365
365 Create some history
366 Create some history
366
367
367 $ touch a
368 $ touch a
368 $ hg add a
369 $ hg add a
369 $ for i in 1 2 3; do echo $i > a; hg commit -m "a $i"; done
370 $ for i in 1 2 3; do echo $i > a; hg commit -m "a $i"; done
370 $ hg checkout 0
371 $ hg checkout 0
371 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
372 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
372 $ touch b
373 $ touch b
373 $ hg add b
374 $ hg add b
374 $ for i in 1 2 3; do echo $i > b; hg commit -m "b $i"; done
375 $ for i in 1 2 3; do echo $i > b; hg commit -m "b $i"; done
375 created new head
376 created new head
376 $ hg log -G -T '{rev}:{node} {desc}' --hidden
377 $ hg log -G -T '{rev}:{node} {desc}' --hidden
377 @ 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
378 @ 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
378 |
379 |
379 o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
380 o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
380 |
381 |
381 o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
382 o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
382 |
383 |
383 | o 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
384 | o 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
384 | |
385 | |
385 | o 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
386 | o 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
386 |/
387 |/
387 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
388 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
388
389
389
390
390 Add and expect uncommit to fail on both merge working dir and merge changeset
391 Add and expect uncommit to fail on both merge working dir and merge changeset
391
392
392 $ hg merge 2
393 $ hg merge 2
393 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 (branch merge, don't forget to commit)
395 (branch merge, don't forget to commit)
395
396
396 $ hg uncommit
397 $ hg uncommit
397 abort: outstanding uncommitted merge
398 abort: outstanding uncommitted merge
398 (requires experimental.uncommitondirtywdir to uncommit)
399 (requires --allow-dirty-working-copy to uncommit)
399 [255]
400 [255]
400
401
401 $ hg uncommit --config experimental.uncommitondirtywdir=True
402 $ hg uncommit --config experimental.uncommitondirtywdir=True
402 abort: cannot uncommit while merging
403 abort: cannot uncommit while merging
403 [255]
404 [255]
404
405
405 $ hg status
406 $ hg status
406 M a
407 M a
407 $ hg commit -m 'merge a and b'
408 $ hg commit -m 'merge a and b'
408
409
409 $ hg uncommit
410 $ hg uncommit
410 abort: cannot uncommit merge changeset
411 abort: cannot uncommit merge changeset
411 [255]
412 [255]
412
413
413 $ hg status
414 $ hg status
414 $ hg log -G -T '{rev}:{node} {desc}' --hidden
415 $ hg log -G -T '{rev}:{node} {desc}' --hidden
415 @ 6:c03b9c37bc67bf504d4912061cfb527b47a63c6e merge a and b
416 @ 6:c03b9c37bc67bf504d4912061cfb527b47a63c6e merge a and b
416 |\
417 |\
417 | o 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
418 | o 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
418 | |
419 | |
419 | o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
420 | o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
420 | |
421 | |
421 | o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
422 | o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
422 | |
423 | |
423 o | 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
424 o | 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
424 | |
425 | |
425 o | 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
426 o | 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
426 |/
427 |/
427 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
428 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
428
429
429
430
430 Rename a->b, then remove b in working copy. Result should remove a.
431 Rename a->b, then remove b in working copy. Result should remove a.
431
432
432 $ hg co -q 0
433 $ hg co -q 0
433 $ hg mv a b
434 $ hg mv a b
434 $ hg ci -qm 'move a to b'
435 $ hg ci -qm 'move a to b'
435 $ hg rm b
436 $ hg rm b
436 $ hg uncommit --config experimental.uncommitondirtywdir=True
437 $ hg uncommit --config experimental.uncommitondirtywdir=True
437 $ hg st --copies
438 $ hg st --copies
438 R a
439 R a
439 $ hg revert a
440 $ hg revert a
440
441
441 Rename a->b, then rename b->c in working copy. Result should rename a->c.
442 Rename a->b, then rename b->c in working copy. Result should rename a->c.
442
443
443 $ hg co -q 0
444 $ hg co -q 0
444 $ hg mv a b
445 $ hg mv a b
445 $ hg ci -qm 'move a to b'
446 $ hg ci -qm 'move a to b'
446 $ hg mv b c
447 $ hg mv b c
447 $ hg uncommit --config experimental.uncommitondirtywdir=True
448 $ hg uncommit --config experimental.uncommitondirtywdir=True
448 $ hg st --copies
449 $ hg st --copies
449 A c
450 A c
450 a
451 a
451 R a
452 R a
452 $ hg revert a
453 $ hg revert a
453 $ hg forget c
454 $ hg forget c
454 $ rm c
455 $ rm c
455
456
456 Copy a->b1 and a->b2, then rename b1->c in working copy. Result should copy a->b2 and a->c.
457 Copy a->b1 and a->b2, then rename b1->c in working copy. Result should copy a->b2 and a->c.
457
458
458 $ hg co -q 0
459 $ hg co -q 0
459 $ hg cp a b1
460 $ hg cp a b1
460 $ hg cp a b2
461 $ hg cp a b2
461 $ hg ci -qm 'move a to b1 and b2'
462 $ hg ci -qm 'move a to b1 and b2'
462 $ hg mv b1 c
463 $ hg mv b1 c
463 $ hg uncommit --config experimental.uncommitondirtywdir=True
464 $ hg uncommit --config experimental.uncommitondirtywdir=True
464 $ hg st --copies
465 $ hg st --copies
465 A b2
466 A b2
466 a
467 a
467 A c
468 A c
468 a
469 a
469 $ cd ..
470 $ cd ..
470
471
471 experimental.uncommitondirtywdir should also work on a dirty PATH
472 experimental.uncommitondirtywdir should also work on a dirty PATH
472
473
473 $ hg init issue5977
474 $ hg init issue5977
474 $ cd issue5977
475 $ cd issue5977
475 $ echo 'super critical info!' > a
476 $ echo 'super critical info!' > a
476 $ hg ci -Am 'add a'
477 $ hg ci -Am 'add a'
477 adding a
478 adding a
478 $ echo 'foo' > b
479 $ echo 'foo' > b
479 $ hg add b
480 $ hg add b
480 $ hg status
481 $ hg status
481 A b
482 A b
482 $ hg unc a
483 $ hg unc a
483 note: keeping empty commit
484 note: keeping empty commit
484 $ hg unc b
485 $ hg unc b
485 abort: uncommitted changes
486 abort: uncommitted changes
486 (requires experimental.uncommitondirtywdir to uncommit)
487 (requires --allow-dirty-working-copy to uncommit)
487 [255]
488 [255]
488 $ cat a
489 $ cat a
489 super critical info!
490 super critical info!
490 $ hg log
491 $ hg log
491 changeset: 1:656ba143d384
492 changeset: 1:656ba143d384
492 tag: tip
493 tag: tip
493 parent: -1:000000000000
494 parent: -1:000000000000
494 user: test
495 user: test
495 date: Thu Jan 01 00:00:00 1970 +0000
496 date: Thu Jan 01 00:00:00 1970 +0000
496 summary: add a
497 summary: add a
497
498
498 $ hg ci -Am 'add b'
499 $ hg ci -Am 'add b'
499 $ echo 'foo bar' > b
500 $ echo 'foo bar' > b
500 $ hg unc --config experimental.uncommitondirtywdir=True b
501 $ hg unc --allow-dirty-working-copy b
501 $ hg log
502 $ hg log
502 changeset: 3:30fa958635b2
503 changeset: 3:30fa958635b2
503 tag: tip
504 tag: tip
504 parent: 1:656ba143d384
505 parent: 1:656ba143d384
505 user: test
506 user: test
506 date: Thu Jan 01 00:00:00 1970 +0000
507 date: Thu Jan 01 00:00:00 1970 +0000
507 summary: add b
508 summary: add b
508
509
509 changeset: 1:656ba143d384
510 changeset: 1:656ba143d384
510 parent: -1:000000000000
511 parent: -1:000000000000
511 user: test
512 user: test
512 date: Thu Jan 01 00:00:00 1970 +0000
513 date: Thu Jan 01 00:00:00 1970 +0000
513 summary: add a
514 summary: add a
514
515
General Comments 0
You need to be logged in to leave comments. Login now