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