##// END OF EJS Templates
uncommit: leave empty commit if all files are uncommitted...
Martin von Zweigbergk -
r36990:28ba7d11 default
parent child Browse files
Show More
@@ -1,256 +1,257 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,
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, allowempty):
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 67 files = (initialfiles - exclude)
68 68 # return the p1 so that we don't create an obsmarker later
69 69 if not files and not allowempty:
70 70 return ctx.parents()[0].node()
71 71
72 72 # Filter copies
73 73 copied = copies.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 86 new = context.memctx(repo,
87 87 parents=[base.node(), node.nullid],
88 88 text=ctx.description(),
89 89 files=files,
90 90 filectxfn=filectxfn,
91 91 user=ctx.user(),
92 92 date=ctx.date(),
93 93 extra=ctx.extra())
94 94 # phase handling
95 95 commitphase = ctx.phase()
96 96 overrides = {('phases', 'new-commit'): commitphase}
97 97 with repo.ui.configoverride(overrides, 'uncommit'):
98 98 newid = repo.commitctx(new)
99 99 return newid
100 100
101 101 def _fixdirstate(repo, oldctx, newctx, status):
102 102 """ fix the dirstate after switching the working directory from oldctx to
103 103 newctx which can be result of either unamend or uncommit.
104 104 """
105 105 ds = repo.dirstate
106 106 copies = dict(ds.copies())
107 107 s = status
108 108 for f in s.modified:
109 109 if ds[f] == 'r':
110 110 # modified + removed -> removed
111 111 continue
112 112 ds.normallookup(f)
113 113
114 114 for f in s.added:
115 115 if ds[f] == 'r':
116 116 # added + removed -> unknown
117 117 ds.drop(f)
118 118 elif ds[f] != 'a':
119 119 ds.add(f)
120 120
121 121 for f in s.removed:
122 122 if ds[f] == 'a':
123 123 # removed + added -> normal
124 124 ds.normallookup(f)
125 125 elif ds[f] != 'r':
126 126 ds.remove(f)
127 127
128 128 # Merge old parent and old working dir copies
129 129 oldcopies = {}
130 130 for f in (s.modified + s.added):
131 131 src = oldctx[f].renamed()
132 132 if src:
133 133 oldcopies[f] = src[0]
134 134 oldcopies.update(copies)
135 135 copies = dict((dst, oldcopies.get(src, src))
136 136 for dst, src in oldcopies.iteritems())
137 137 # Adjust the dirstate copies
138 138 for dst, src in copies.iteritems():
139 139 if (src not in newctx or dst in newctx or ds[dst] != 'a'):
140 140 src = None
141 141 ds.copy(src, dst)
142 142
143 143 @command('uncommit',
144 144 [('', 'keep', False, _('allow an empty commit after uncommiting')),
145 145 ] + commands.walkopts,
146 146 _('[OPTION]... [FILE]...'))
147 147 def uncommit(ui, repo, *pats, **opts):
148 148 """uncommit part or all of a local changeset
149 149
150 150 This command undoes the effect of a local commit, returning the affected
151 151 files to their uncommitted state. This means that files modified or
152 152 deleted in the changeset will be left unchanged, and so will remain
153 153 modified in the working directory.
154 154 """
155 155 opts = pycompat.byteskwargs(opts)
156 156
157 157 with repo.wlock(), repo.lock():
158 158
159 159 if not pats and not repo.ui.configbool('experimental',
160 160 'uncommitondirtywdir'):
161 161 cmdutil.bailifchanged(repo)
162 162 old = repo['.']
163 163 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
164 164 if len(old.parents()) > 1:
165 165 raise error.Abort(_("cannot uncommit merge changeset"))
166 166
167 167 with repo.transaction('uncommit'):
168 168 match = scmutil.match(old, pats, opts)
169 newid = _commitfiltered(repo, old, match, opts.get('keep'))
169 allowempty = opts.get('keep') or pats
170 newid = _commitfiltered(repo, old, match, allowempty)
170 171 if newid is None:
171 172 ui.status(_("nothing to uncommit\n"))
172 173 return 1
173 174
174 175 mapping = {}
175 176 if newid != old.p1().node():
176 177 # Move local changes on filtered changeset
177 178 mapping[old.node()] = (newid,)
178 179 else:
179 180 # Fully removed the old commit
180 181 mapping[old.node()] = ()
181 182
182 183 scmutil.cleanupnodes(repo, mapping, 'uncommit')
183 184
184 185 with repo.dirstate.parentchange():
185 186 repo.dirstate.setparents(newid, node.nullid)
186 187 s = repo.status(old.p1(), old, match=match)
187 188 _fixdirstate(repo, old, repo[newid], s)
188 189
189 190 def predecessormarkers(ctx):
190 191 """yields the obsolete markers marking the given changeset as a successor"""
191 192 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
192 193 yield obsutil.marker(ctx.repo(), data)
193 194
194 195 @command('^unamend', [])
195 196 def unamend(ui, repo, **opts):
196 197 """undo the most recent amend operation on a current changeset
197 198
198 199 This command will roll back to the previous version of a changeset,
199 200 leaving working directory in state in which it was before running
200 201 `hg amend` (e.g. files modified as part of an amend will be
201 202 marked as modified `hg status`)
202 203 """
203 204
204 205 unfi = repo.unfiltered()
205 206 with repo.wlock(), repo.lock(), repo.transaction('unamend'):
206 207
207 208 # identify the commit from which to unamend
208 209 curctx = repo['.']
209 210
210 211 rewriteutil.precheck(repo, [curctx.rev()], 'unamend')
211 212
212 213 # identify the commit to which to unamend
213 214 markers = list(predecessormarkers(curctx))
214 215 if len(markers) != 1:
215 216 e = _("changeset must have one predecessor, found %i predecessors")
216 217 raise error.Abort(e % len(markers))
217 218
218 219 prednode = markers[0].prednode()
219 220 predctx = unfi[prednode]
220 221
221 222 # add an extra so that we get a new hash
222 223 # note: allowing unamend to undo an unamend is an intentional feature
223 224 extras = predctx.extra()
224 225 extras['unamend_source'] = curctx.hex()
225 226
226 227 def filectxfn(repo, ctx_, path):
227 228 try:
228 229 return predctx.filectx(path)
229 230 except KeyError:
230 231 return None
231 232
232 233 # Make a new commit same as predctx
233 234 newctx = context.memctx(repo,
234 235 parents=(predctx.p1(), predctx.p2()),
235 236 text=predctx.description(),
236 237 files=predctx.files(),
237 238 filectxfn=filectxfn,
238 239 user=predctx.user(),
239 240 date=predctx.date(),
240 241 extra=extras)
241 242 # phase handling
242 243 commitphase = curctx.phase()
243 244 overrides = {('phases', 'new-commit'): commitphase}
244 245 with repo.ui.configoverride(overrides, 'uncommit'):
245 246 newprednode = repo.commitctx(newctx)
246 247
247 248 newpredctx = repo[newprednode]
248 249 dirstate = repo.dirstate
249 250
250 251 with dirstate.parentchange():
251 252 dirstate.setparents(newprednode, node.nullid)
252 253 s = repo.status(predctx, curctx)
253 254 _fixdirstate(repo, curctx, newpredctx, s)
254 255
255 256 mapping = {curctx.node(): (newprednode,)}
256 257 scmutil.cleanupnodes(repo, mapping, 'unamend')
@@ -1,388 +1,390 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 (use 'hg help -e uncommit' to show help for the uncommit extension)
31 31
32 32 options ([+] can be repeated):
33 33
34 34 --keep allow an empty commit after uncommiting
35 35 -I --include PATTERN [+] include names matching the given patterns
36 36 -X --exclude PATTERN [+] exclude names matching the given patterns
37 37
38 38 (some details hidden, use --verbose to show complete help)
39 39
40 40 Uncommit with no commits should fail
41 41
42 42 $ hg uncommit
43 43 abort: cannot uncommit null changeset
44 44 (no changeset checked out)
45 45 [255]
46 46
47 47 Create some commits
48 48
49 49 $ touch files
50 50 $ hg add files
51 51 $ 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
52 52 $ ls
53 53 file-a
54 54 file-ab
55 55 file-abc
56 56 file-abcd
57 57 file-abcde
58 58 files
59 59
60 60 $ hg log -G -T '{rev}:{node} {desc}' --hidden
61 61 @ 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
62 62 |
63 63 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
64 64 |
65 65 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
66 66 |
67 67 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
68 68 |
69 69 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
70 70
71 71 Simple uncommit off the top, also moves bookmark
72 72
73 73 $ hg bookmark
74 74 * foo 4:6c4fd43ed714
75 75 $ hg uncommit
76 76 $ hg status
77 77 M files
78 78 A file-abcde
79 79 $ hg bookmark
80 80 * foo 3:6db330d65db4
81 81
82 82 $ hg log -G -T '{rev}:{node} {desc}' --hidden
83 83 x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
84 84 |
85 85 @ 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
86 86 |
87 87 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
88 88 |
89 89 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
90 90 |
91 91 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
92 92
93 93
94 94 Recommit
95 95
96 96 $ hg commit -m 'new change abcde'
97 97 $ hg status
98 98 $ hg heads -T '{rev}:{node} {desc}'
99 99 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde (no-eol)
100 100
101 101 Uncommit of non-existent and unchanged files has no effect
102 102 $ hg uncommit nothinghere
103 103 nothing to uncommit
104 104 [1]
105 105 $ hg status
106 106 $ hg uncommit file-abc
107 107 nothing to uncommit
108 108 [1]
109 109 $ hg status
110 110
111 111 Try partial uncommit, also moves bookmark
112 112
113 113 $ hg bookmark
114 114 * foo 5:0c07a3ccda77
115 115 $ hg uncommit files
116 116 $ hg status
117 117 M files
118 118 $ hg bookmark
119 119 * foo 6:3727deee06f7
120 120 $ hg heads -T '{rev}:{node} {desc}'
121 121 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde (no-eol)
122 122 $ hg log -r . -p -T '{rev}:{node} {desc}'
123 123 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcdediff -r 6db330d65db4 -r 3727deee06f7 file-abcde
124 124 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125 125 +++ b/file-abcde Thu Jan 01 00:00:00 1970 +0000
126 126 @@ -0,0 +1,1 @@
127 127 +abcde
128 128
129 129 $ hg log -G -T '{rev}:{node} {desc}' --hidden
130 130 @ 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
131 131 |
132 132 | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
133 133 |/
134 134 | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
135 135 |/
136 136 o 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
137 137 |
138 138 o 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
139 139 |
140 140 o 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
141 141 |
142 142 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
143 143
144 144 $ hg commit -m 'update files for abcde'
145 145
146 146 Uncommit with dirty state
147 147
148 148 $ echo "foo" >> files
149 149 $ cat files
150 150 abcde
151 151 foo
152 152 $ hg status
153 153 M files
154 154 $ hg uncommit
155 155 abort: uncommitted changes
156 156 [255]
157 157 $ hg uncommit files
158 158 $ cat files
159 159 abcde
160 160 foo
161 $ hg commit -m "files abcde + foo"
161 $ hg commit --amend -m "files abcde + foo"
162 162
163 163 Testing the 'experimental.uncommitondirtywdir' config
164 164
165 165 $ echo "bar" >> files
166 166 $ hg uncommit
167 167 abort: uncommitted changes
168 168 [255]
169 169 $ hg uncommit --config experimental.uncommitondirtywdir=True
170 170 $ hg commit -m "files abcde + foo"
171 171
172 172 Uncommit in the middle of a stack, does not move bookmark
173 173
174 174 $ hg checkout '.^^^'
175 175 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
176 176 (leaving bookmark foo)
177 177 $ hg log -r . -p -T '{rev}:{node} {desc}'
178 178 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abcdiff -r 69a232e754b0 -r abf2df566fc1 file-abc
179 179 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180 180 +++ b/file-abc Thu Jan 01 00:00:00 1970 +0000
181 181 @@ -0,0 +1,1 @@
182 182 +abc
183 183 diff -r 69a232e754b0 -r abf2df566fc1 files
184 184 --- a/files Thu Jan 01 00:00:00 1970 +0000
185 185 +++ b/files Thu Jan 01 00:00:00 1970 +0000
186 186 @@ -1,1 +1,1 @@
187 187 -ab
188 188 +abc
189 189
190 190 $ hg bookmark
191 foo 9:48e5bd7cd583
191 foo 10:48e5bd7cd583
192 192 $ hg uncommit
193 193 3 new orphan changesets
194 194 $ hg status
195 195 M files
196 196 A file-abc
197 197 $ hg heads -T '{rev}:{node} {desc}'
198 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo (no-eol)
198 10:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo (no-eol)
199 199 $ hg bookmark
200 foo 9:48e5bd7cd583
200 foo 10:48e5bd7cd583
201 201 $ hg commit -m 'new abc'
202 202 created new head
203 203
204 204 Partial uncommit in the middle, does not move bookmark
205 205
206 206 $ hg checkout '.^'
207 207 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
208 208 $ hg log -r . -p -T '{rev}:{node} {desc}'
209 209 1:69a232e754b08d568c4899475faf2eb44b857802 added file-abdiff -r 3004d2d9b508 -r 69a232e754b0 file-ab
210 210 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
211 211 +++ b/file-ab Thu Jan 01 00:00:00 1970 +0000
212 212 @@ -0,0 +1,1 @@
213 213 +ab
214 214 diff -r 3004d2d9b508 -r 69a232e754b0 files
215 215 --- a/files Thu Jan 01 00:00:00 1970 +0000
216 216 +++ b/files Thu Jan 01 00:00:00 1970 +0000
217 217 @@ -1,1 +1,1 @@
218 218 -a
219 219 +ab
220 220
221 221 $ hg bookmark
222 foo 9:48e5bd7cd583
222 foo 10:48e5bd7cd583
223 223 $ hg uncommit file-ab
224 224 1 new orphan changesets
225 225 $ hg status
226 226 A file-ab
227 227
228 228 $ hg heads -T '{rev}:{node} {desc}\n'
229 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
230 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
231 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
229 12:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
230 11:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
231 10:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
232 232
233 233 $ hg bookmark
234 foo 9:48e5bd7cd583
234 foo 10:48e5bd7cd583
235 235 $ hg commit -m 'update ab'
236 236 $ hg status
237 237 $ hg heads -T '{rev}:{node} {desc}\n'
238 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
239 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
240 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
238 13:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
239 11:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
240 10:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
241 241
242 242 $ hg log -G -T '{rev}:{node} {desc}' --hidden
243 @ 12:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
243 @ 13:f21039c59242b085491bb58f591afc4ed1c04c09 update ab
244 244 |
245 o 11:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
245 o 12:8eb87968f2edb7f27f27fe676316e179de65fff6 added file-ab
246 246 |
247 | * 10:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
247 | * 11:5dc89ca4486f8a88716c5797fa9f498d13d7c2e1 new abc
248 248 | |
249 | | * 9:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
249 | | * 10:48e5bd7cd583eb24164ef8b89185819c84c96ed7 files abcde + foo
250 250 | | |
251 | | | x 8:83815831694b1271e9f207cb1b79b2b19275edcb files abcde + foo
251 | | | x 9:8a6b58c173ca6a2e3745d8bd86698718d664bc6c files abcde + foo
252 | | |/
253 | | | x 8:39ad452c7f684a55d161c574340c5766c4569278 update files for abcde
252 254 | | |/
253 255 | | | x 7:0977fa602c2fd7d8427ed4e7ee15ea13b84c9173 update files for abcde
254 256 | | |/
255 257 | | * 6:3727deee06f72f5ffa8db792ee299cf39e3e190b new change abcde
256 258 | | |
257 259 | | | x 5:0c07a3ccda771b25f1cb1edbd02e683723344ef1 new change abcde
258 260 | | |/
259 261 | | | x 4:6c4fd43ed714e7fcd8adbaa7b16c953c2e985b60 added file-abcde
260 262 | | |/
261 263 | | * 3:6db330d65db434145c0b59d291853e9a84719b24 added file-abcd
262 264 | | |
263 265 | | x 2:abf2df566fc193b3ac34d946e63c1583e4d4732b added file-abc
264 266 | |/
265 267 | x 1:69a232e754b08d568c4899475faf2eb44b857802 added file-ab
266 268 |/
267 269 o 0:3004d2d9b50883c1538fc754a3aeb55f1b4084f6 added file-a
268 270
269 271 Uncommit with draft parent
270 272
271 273 $ hg uncommit
272 274 $ hg phase -r .
273 11: draft
275 12: draft
274 276 $ hg commit -m 'update ab again'
275 277
276 278 Uncommit with public parent
277 279
278 280 $ hg phase -p "::.^"
279 281 $ hg uncommit
280 282 $ hg phase -r .
281 11: public
283 12: public
282 284
283 285 Partial uncommit with public parent
284 286
285 287 $ echo xyz > xyz
286 288 $ hg add xyz
287 289 $ hg commit -m "update ab and add xyz"
288 290 $ hg uncommit xyz
289 291 $ hg status
290 292 A xyz
291 293 $ hg phase -r .
292 15: draft
294 16: draft
293 295 $ hg phase -r ".^"
294 11: public
296 12: public
295 297
296 298 Uncommit leaving an empty changeset
297 299
298 300 $ cd $TESTTMP
299 301 $ hg init repo1
300 302 $ cd repo1
301 303 $ hg debugdrawdag <<'EOS'
302 304 > Q
303 305 > |
304 306 > P
305 307 > EOS
306 308 $ hg up Q -q
307 309 $ hg uncommit --keep
308 310 $ hg log -G -T '{desc} FILES: {files}'
309 311 @ Q FILES:
310 312 |
311 313 | x Q FILES: Q
312 314 |/
313 315 o P FILES: P
314 316
315 317 $ hg status
316 318 A Q
317 319
318 320 $ cd ..
319 321 $ rm -rf repo1
320 322
321 323 Testing uncommit while merge
322 324
323 325 $ hg init repo2
324 326 $ cd repo2
325 327
326 328 Create some history
327 329
328 330 $ touch a
329 331 $ hg add a
330 332 $ for i in 1 2 3; do echo $i > a; hg commit -m "a $i"; done
331 333 $ hg checkout 0
332 334 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 335 $ touch b
334 336 $ hg add b
335 337 $ for i in 1 2 3; do echo $i > b; hg commit -m "b $i"; done
336 338 created new head
337 339 $ hg log -G -T '{rev}:{node} {desc}' --hidden
338 340 @ 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
339 341 |
340 342 o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
341 343 |
342 344 o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
343 345 |
344 346 | o 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
345 347 | |
346 348 | o 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
347 349 |/
348 350 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
349 351
350 352
351 353 Add and expect uncommit to fail on both merge working dir and merge changeset
352 354
353 355 $ hg merge 2
354 356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 357 (branch merge, don't forget to commit)
356 358
357 359 $ hg uncommit
358 360 abort: outstanding uncommitted merge
359 361 [255]
360 362
361 363 $ hg uncommit --config experimental.uncommitondirtywdir=True
362 364 abort: cannot uncommit while merging
363 365 [255]
364 366
365 367 $ hg status
366 368 M a
367 369 $ hg commit -m 'merge a and b'
368 370
369 371 $ hg uncommit
370 372 abort: cannot uncommit merge changeset
371 373 [255]
372 374
373 375 $ hg status
374 376 $ hg log -G -T '{rev}:{node} {desc}' --hidden
375 377 @ 6:c03b9c37bc67bf504d4912061cfb527b47a63c6e merge a and b
376 378 |\
377 379 | o 5:2cd56cdde163ded2fbb16ba2f918c96046ab0bf2 b 3
378 380 | |
379 381 | o 4:c3a0d5bb3b15834ffd2ef9ef603e93ec65cf2037 b 2
380 382 | |
381 383 | o 3:49bb009ca26078726b8870f1edb29fae8f7618f5 b 1
382 384 | |
383 385 o | 2:990982b7384266e691f1bc08ca36177adcd1c8a9 a 3
384 386 | |
385 387 o | 1:24d38e3cf160c7b6f5ffe82179332229886a6d34 a 2
386 388 |/
387 389 o 0:ea4e33293d4d274a2ba73150733c2612231f398c a 1
388 390
General Comments 0
You need to be logged in to leave comments. Login now