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