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