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