##// END OF EJS Templates
split: use the new movedirstate() we now have in scmutil...
Martin von Zweigbergk -
r42132:42e2c7c5 default
parent child Browse files
Show More
@@ -1,180 +1,177 b''
1 # split.py - split a changeset into smaller ones
1 # split.py - split a changeset into smaller ones
2 #
2 #
3 # Copyright 2015 Laurent Charignon <lcharignon@fb.com>
3 # Copyright 2015 Laurent Charignon <lcharignon@fb.com>
4 # Copyright 2017 Facebook, Inc.
4 # Copyright 2017 Facebook, Inc.
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8 """command to split a changeset into smaller ones (EXPERIMENTAL)"""
8 """command to split a changeset into smaller ones (EXPERIMENTAL)"""
9
9
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11
11
12 from mercurial.i18n import _
12 from mercurial.i18n import _
13
13
14 from mercurial.node import (
14 from mercurial.node import (
15 nullid,
15 nullid,
16 short,
16 short,
17 )
17 )
18
18
19 from mercurial import (
19 from mercurial import (
20 bookmarks,
20 bookmarks,
21 cmdutil,
21 cmdutil,
22 commands,
22 commands,
23 error,
23 error,
24 hg,
24 hg,
25 obsolete,
25 obsolete,
26 phases,
26 phases,
27 pycompat,
27 pycompat,
28 registrar,
28 registrar,
29 revsetlang,
29 revsetlang,
30 scmutil,
30 scmutil,
31 )
31 )
32
32
33 # allow people to use split without explicitly enabling rebase extension
33 # allow people to use split without explicitly enabling rebase extension
34 from . import (
34 from . import (
35 rebase,
35 rebase,
36 )
36 )
37
37
38 cmdtable = {}
38 cmdtable = {}
39 command = registrar.command(cmdtable)
39 command = registrar.command(cmdtable)
40
40
41 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
41 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
42 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
42 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
43 # be specifying the version(s) of Mercurial they are tested with, or
43 # be specifying the version(s) of Mercurial they are tested with, or
44 # leave the attribute unspecified.
44 # leave the attribute unspecified.
45 testedwith = 'ships-with-hg-core'
45 testedwith = 'ships-with-hg-core'
46
46
47 @command('split',
47 @command('split',
48 [('r', 'rev', '', _("revision to split"), _('REV')),
48 [('r', 'rev', '', _("revision to split"), _('REV')),
49 ('', 'rebase', True, _('rebase descendants after split')),
49 ('', 'rebase', True, _('rebase descendants after split')),
50 ] + cmdutil.commitopts2,
50 ] + cmdutil.commitopts2,
51 _('hg split [--no-rebase] [[-r] REV]'),
51 _('hg split [--no-rebase] [[-r] REV]'),
52 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
52 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, helpbasic=True)
53 def split(ui, repo, *revs, **opts):
53 def split(ui, repo, *revs, **opts):
54 """split a changeset into smaller ones
54 """split a changeset into smaller ones
55
55
56 Repeatedly prompt changes and commit message for new changesets until there
56 Repeatedly prompt changes and commit message for new changesets until there
57 is nothing left in the original changeset.
57 is nothing left in the original changeset.
58
58
59 If --rev was not given, split the working directory parent.
59 If --rev was not given, split the working directory parent.
60
60
61 By default, rebase connected non-obsoleted descendants onto the new
61 By default, rebase connected non-obsoleted descendants onto the new
62 changeset. Use --no-rebase to avoid the rebase.
62 changeset. Use --no-rebase to avoid the rebase.
63 """
63 """
64 opts = pycompat.byteskwargs(opts)
64 opts = pycompat.byteskwargs(opts)
65 revlist = []
65 revlist = []
66 if opts.get('rev'):
66 if opts.get('rev'):
67 revlist.append(opts.get('rev'))
67 revlist.append(opts.get('rev'))
68 revlist.extend(revs)
68 revlist.extend(revs)
69 with repo.wlock(), repo.lock(), repo.transaction('split') as tr:
69 with repo.wlock(), repo.lock(), repo.transaction('split') as tr:
70 revs = scmutil.revrange(repo, revlist or ['.'])
70 revs = scmutil.revrange(repo, revlist or ['.'])
71 if len(revs) > 1:
71 if len(revs) > 1:
72 raise error.Abort(_('cannot split multiple revisions'))
72 raise error.Abort(_('cannot split multiple revisions'))
73
73
74 rev = revs.first()
74 rev = revs.first()
75 ctx = repo[rev]
75 ctx = repo[rev]
76 if rev is None or ctx.node() == nullid:
76 if rev is None or ctx.node() == nullid:
77 ui.status(_('nothing to split\n'))
77 ui.status(_('nothing to split\n'))
78 return 1
78 return 1
79 if ctx.node() is None:
79 if ctx.node() is None:
80 raise error.Abort(_('cannot split working directory'))
80 raise error.Abort(_('cannot split working directory'))
81
81
82 # rewriteutil.precheck is not very useful here because:
82 # rewriteutil.precheck is not very useful here because:
83 # 1. null check is done above and it's more friendly to return 1
83 # 1. null check is done above and it's more friendly to return 1
84 # instead of abort
84 # instead of abort
85 # 2. mergestate check is done below by cmdutil.bailifchanged
85 # 2. mergestate check is done below by cmdutil.bailifchanged
86 # 3. unstable check is more complex here because of --rebase
86 # 3. unstable check is more complex here because of --rebase
87 #
87 #
88 # So only "public" check is useful and it's checked directly here.
88 # So only "public" check is useful and it's checked directly here.
89 if ctx.phase() == phases.public:
89 if ctx.phase() == phases.public:
90 raise error.Abort(_('cannot split public changeset'),
90 raise error.Abort(_('cannot split public changeset'),
91 hint=_("see 'hg help phases' for details"))
91 hint=_("see 'hg help phases' for details"))
92
92
93 descendants = list(repo.revs('(%d::) - (%d)', rev, rev))
93 descendants = list(repo.revs('(%d::) - (%d)', rev, rev))
94 alloworphaned = obsolete.isenabled(repo, obsolete.allowunstableopt)
94 alloworphaned = obsolete.isenabled(repo, obsolete.allowunstableopt)
95 if opts.get('rebase'):
95 if opts.get('rebase'):
96 # Skip obsoleted descendants and their descendants so the rebase
96 # Skip obsoleted descendants and their descendants so the rebase
97 # won't cause conflicts for sure.
97 # won't cause conflicts for sure.
98 torebase = list(repo.revs('%ld - (%ld & obsolete())::',
98 torebase = list(repo.revs('%ld - (%ld & obsolete())::',
99 descendants, descendants))
99 descendants, descendants))
100 if not alloworphaned and len(torebase) != len(descendants):
100 if not alloworphaned and len(torebase) != len(descendants):
101 raise error.Abort(_('split would leave orphaned changesets '
101 raise error.Abort(_('split would leave orphaned changesets '
102 'behind'))
102 'behind'))
103 else:
103 else:
104 if not alloworphaned and descendants:
104 if not alloworphaned and descendants:
105 raise error.Abort(
105 raise error.Abort(
106 _('cannot split changeset with children without rebase'))
106 _('cannot split changeset with children without rebase'))
107 torebase = ()
107 torebase = ()
108
108
109 if len(ctx.parents()) > 1:
109 if len(ctx.parents()) > 1:
110 raise error.Abort(_('cannot split a merge changeset'))
110 raise error.Abort(_('cannot split a merge changeset'))
111
111
112 cmdutil.bailifchanged(repo)
112 cmdutil.bailifchanged(repo)
113
113
114 # Deactivate bookmark temporarily so it won't get moved unintentionally
114 # Deactivate bookmark temporarily so it won't get moved unintentionally
115 bname = repo._activebookmark
115 bname = repo._activebookmark
116 if bname and repo._bookmarks[bname] != ctx.node():
116 if bname and repo._bookmarks[bname] != ctx.node():
117 bookmarks.deactivate(repo)
117 bookmarks.deactivate(repo)
118
118
119 wnode = repo['.'].node()
119 wnode = repo['.'].node()
120 top = None
120 top = None
121 try:
121 try:
122 top = dosplit(ui, repo, tr, ctx, opts)
122 top = dosplit(ui, repo, tr, ctx, opts)
123 finally:
123 finally:
124 # top is None: split failed, need update --clean recovery.
124 # top is None: split failed, need update --clean recovery.
125 # wnode == ctx.node(): wnode split, no need to update.
125 # wnode == ctx.node(): wnode split, no need to update.
126 if top is None or wnode != ctx.node():
126 if top is None or wnode != ctx.node():
127 hg.clean(repo, wnode, show_stats=False)
127 hg.clean(repo, wnode, show_stats=False)
128 if bname:
128 if bname:
129 bookmarks.activate(repo, bname)
129 bookmarks.activate(repo, bname)
130 if torebase and top:
130 if torebase and top:
131 dorebase(ui, repo, torebase, top)
131 dorebase(ui, repo, torebase, top)
132
132
133 def dosplit(ui, repo, tr, ctx, opts):
133 def dosplit(ui, repo, tr, ctx, opts):
134 committed = [] # [ctx]
134 committed = [] # [ctx]
135
135
136 # Set working parent to ctx.p1(), and keep working copy as ctx's content
136 # Set working parent to ctx.p1(), and keep working copy as ctx's content
137 # NOTE: if we can have "update without touching working copy" API, the
137 if ctx.node() != repo.dirstate.p1():
138 # revert step could be cheaper.
138 hg.clean(repo, ctx.node(), show_stats=False)
139 hg.clean(repo, ctx.p1().node(), show_stats=False)
139 with repo.dirstate.parentchange():
140 parents = repo.changelog.parents(ctx.node())
140 scmutil.movedirstate(repo, ctx.p1())
141 ui.pushbuffer()
142 cmdutil.revert(ui, repo, ctx, parents)
143 ui.popbuffer() # discard "reverting ..." messages
144
141
145 # Any modified, added, removed, deleted result means split is incomplete
142 # Any modified, added, removed, deleted result means split is incomplete
146 incomplete = lambda repo: any(repo.status()[:4])
143 incomplete = lambda repo: any(repo.status()[:4])
147
144
148 # Main split loop
145 # Main split loop
149 while incomplete(repo):
146 while incomplete(repo):
150 if committed:
147 if committed:
151 header = (_('HG: Splitting %s. So far it has been split into:\n')
148 header = (_('HG: Splitting %s. So far it has been split into:\n')
152 % short(ctx.node()))
149 % short(ctx.node()))
153 for c in committed:
150 for c in committed:
154 firstline = c.description().split('\n', 1)[0]
151 firstline = c.description().split('\n', 1)[0]
155 header += _('HG: - %s: %s\n') % (short(c.node()), firstline)
152 header += _('HG: - %s: %s\n') % (short(c.node()), firstline)
156 header += _('HG: Write commit message for the next split '
153 header += _('HG: Write commit message for the next split '
157 'changeset.\n')
154 'changeset.\n')
158 else:
155 else:
159 header = _('HG: Splitting %s. Write commit message for the '
156 header = _('HG: Splitting %s. Write commit message for the '
160 'first split changeset.\n') % short(ctx.node())
157 'first split changeset.\n') % short(ctx.node())
161 opts.update({
158 opts.update({
162 'edit': True,
159 'edit': True,
163 'interactive': True,
160 'interactive': True,
164 'message': header + ctx.description(),
161 'message': header + ctx.description(),
165 })
162 })
166 commands.commit(ui, repo, **pycompat.strkwargs(opts))
163 commands.commit(ui, repo, **pycompat.strkwargs(opts))
167 newctx = repo['.']
164 newctx = repo['.']
168 committed.append(newctx)
165 committed.append(newctx)
169
166
170 if not committed:
167 if not committed:
171 raise error.Abort(_('cannot split an empty revision'))
168 raise error.Abort(_('cannot split an empty revision'))
172
169
173 scmutil.cleanupnodes(repo, {ctx.node(): [c.node() for c in committed]},
170 scmutil.cleanupnodes(repo, {ctx.node(): [c.node() for c in committed]},
174 operation='split', fixphase=True)
171 operation='split', fixphase=True)
175
172
176 return committed[-1]
173 return committed[-1]
177
174
178 def dorebase(ui, repo, src, destctx):
175 def dorebase(ui, repo, src, destctx):
179 rebase.rebase(ui, repo, rev=[revsetlang.formatspec('%ld', src)],
176 rebase.rebase(ui, repo, rev=[revsetlang.formatspec('%ld', src)],
180 dest=revsetlang.formatspec('%d', destctx.rev()))
177 dest=revsetlang.formatspec('%d', destctx.rev()))
@@ -1,355 +1,267 b''
1 Tests for experimental.removeemptydirs
1 Tests for experimental.removeemptydirs
2
2
3 $ NO_RM=--config=experimental.removeemptydirs=0
3 $ NO_RM=--config=experimental.removeemptydirs=0
4 $ isdir() { if [ -d $1 ]; then echo yes; else echo no; fi }
4 $ isdir() { if [ -d $1 ]; then echo yes; else echo no; fi }
5 $ isfile() { if [ -f $1 ]; then echo yes; else echo no; fi }
5 $ isfile() { if [ -f $1 ]; then echo yes; else echo no; fi }
6
6
7 `hg rm` of the last file in a directory:
7 `hg rm` of the last file in a directory:
8 $ hg init hgrm
8 $ hg init hgrm
9 $ cd hgrm
9 $ cd hgrm
10 $ mkdir somedir
10 $ mkdir somedir
11 $ echo hi > somedir/foo
11 $ echo hi > somedir/foo
12 $ hg ci -qAm foo
12 $ hg ci -qAm foo
13 $ isdir somedir
13 $ isdir somedir
14 yes
14 yes
15 $ hg rm somedir/foo
15 $ hg rm somedir/foo
16 $ isdir somedir
16 $ isdir somedir
17 no
17 no
18 $ hg revert -qa
18 $ hg revert -qa
19 $ isdir somedir
19 $ isdir somedir
20 yes
20 yes
21 $ hg $NO_RM rm somedir/foo
21 $ hg $NO_RM rm somedir/foo
22 $ isdir somedir
22 $ isdir somedir
23 yes
23 yes
24 $ ls somedir
24 $ ls somedir
25 $ cd $TESTTMP
25 $ cd $TESTTMP
26
26
27 `hg mv` of the last file in a directory:
27 `hg mv` of the last file in a directory:
28 $ hg init hgmv
28 $ hg init hgmv
29 $ cd hgmv
29 $ cd hgmv
30 $ mkdir somedir
30 $ mkdir somedir
31 $ mkdir destdir
31 $ mkdir destdir
32 $ echo hi > somedir/foo
32 $ echo hi > somedir/foo
33 $ hg ci -qAm foo
33 $ hg ci -qAm foo
34 $ isdir somedir
34 $ isdir somedir
35 yes
35 yes
36 $ hg mv somedir/foo destdir/foo
36 $ hg mv somedir/foo destdir/foo
37 $ isdir somedir
37 $ isdir somedir
38 no
38 no
39 $ hg revert -qa
39 $ hg revert -qa
40 (revert doesn't get rid of destdir/foo?)
40 (revert doesn't get rid of destdir/foo?)
41 $ rm destdir/foo
41 $ rm destdir/foo
42 $ isdir somedir
42 $ isdir somedir
43 yes
43 yes
44 $ hg $NO_RM mv somedir/foo destdir/foo
44 $ hg $NO_RM mv somedir/foo destdir/foo
45 $ isdir somedir
45 $ isdir somedir
46 yes
46 yes
47 $ ls somedir
47 $ ls somedir
48 $ cd $TESTTMP
48 $ cd $TESTTMP
49
49
50 Updating to a commit that doesn't have the directory:
50 Updating to a commit that doesn't have the directory:
51 $ hg init hgupdate
51 $ hg init hgupdate
52 $ cd hgupdate
52 $ cd hgupdate
53 $ echo hi > r0
53 $ echo hi > r0
54 $ hg ci -qAm r0
54 $ hg ci -qAm r0
55 $ mkdir somedir
55 $ mkdir somedir
56 $ echo hi > somedir/foo
56 $ echo hi > somedir/foo
57 $ hg ci -qAm r1
57 $ hg ci -qAm r1
58 $ isdir somedir
58 $ isdir somedir
59 yes
59 yes
60 $ hg co -q -r ".^"
60 $ hg co -q -r ".^"
61 $ isdir somedir
61 $ isdir somedir
62 no
62 no
63 $ hg co -q tip
63 $ hg co -q tip
64 $ isdir somedir
64 $ isdir somedir
65 yes
65 yes
66 $ hg $NO_RM co -q -r ".^"
66 $ hg $NO_RM co -q -r ".^"
67 $ isdir somedir
67 $ isdir somedir
68 yes
68 yes
69 $ ls somedir
69 $ ls somedir
70 $ cd $TESTTMP
70 $ cd $TESTTMP
71
71
72 Rebasing across a commit that doesn't have the directory, from inside the
72 Rebasing across a commit that doesn't have the directory, from inside the
73 directory:
73 directory:
74 $ hg init hgrebase
74 $ hg init hgrebase
75 $ cd hgrebase
75 $ cd hgrebase
76 $ echo hi > r0
76 $ echo hi > r0
77 $ hg ci -qAm r0
77 $ hg ci -qAm r0
78 $ mkdir somedir
78 $ mkdir somedir
79 $ echo hi > somedir/foo
79 $ echo hi > somedir/foo
80 $ hg ci -qAm first_rebase_source
80 $ hg ci -qAm first_rebase_source
81 $ hg $NO_RM co -q -r ".^"
81 $ hg $NO_RM co -q -r ".^"
82 $ echo hi > somedir/bar
82 $ echo hi > somedir/bar
83 $ hg ci -qAm first_rebase_dest
83 $ hg ci -qAm first_rebase_dest
84 $ hg $NO_RM co -q -r ".^"
84 $ hg $NO_RM co -q -r ".^"
85 $ echo hi > somedir/baz
85 $ echo hi > somedir/baz
86 $ hg ci -qAm second_rebase_dest
86 $ hg ci -qAm second_rebase_dest
87 $ hg co -qr 'desc(first_rebase_source)'
87 $ hg co -qr 'desc(first_rebase_source)'
88 $ cd $TESTTMP/hgrebase/somedir
88 $ cd $TESTTMP/hgrebase/somedir
89 $ hg --config extensions.rebase= rebase -qr . -d 'desc(first_rebase_dest)'
89 $ hg --config extensions.rebase= rebase -qr . -d 'desc(first_rebase_dest)'
90 current directory was removed (rmcwd !)
90 current directory was removed (rmcwd !)
91 (consider changing to repo root: $TESTTMP/hgrebase) (rmcwd !)
91 (consider changing to repo root: $TESTTMP/hgrebase) (rmcwd !)
92 $ cd $TESTTMP/hgrebase/somedir
92 $ cd $TESTTMP/hgrebase/somedir
93 (The current node is the rebased first_rebase_source on top of
93 (The current node is the rebased first_rebase_source on top of
94 first_rebase_dest)
94 first_rebase_dest)
95 This should not output anything about current directory being removed:
95 This should not output anything about current directory being removed:
96 $ hg $NO_RM --config extensions.rebase= rebase -qr . -d 'desc(second_rebase_dest)'
96 $ hg $NO_RM --config extensions.rebase= rebase -qr . -d 'desc(second_rebase_dest)'
97 $ cd $TESTTMP
97 $ cd $TESTTMP
98
98
99 Histediting across a commit that doesn't have the directory, from inside the
99 Histediting across a commit that doesn't have the directory, from inside the
100 directory (reordering nodes):
100 directory (reordering nodes):
101 $ hg init hghistedit
101 $ hg init hghistedit
102 $ cd hghistedit
102 $ cd hghistedit
103 $ echo hi > r0
103 $ echo hi > r0
104 $ hg ci -qAm r0
104 $ hg ci -qAm r0
105 $ echo hi > r1
105 $ echo hi > r1
106 $ hg ci -qAm r1
106 $ hg ci -qAm r1
107 $ echo hi > r2
107 $ echo hi > r2
108 $ hg ci -qAm r2
108 $ hg ci -qAm r2
109 $ mkdir somedir
109 $ mkdir somedir
110 $ echo hi > somedir/foo
110 $ echo hi > somedir/foo
111 $ hg ci -qAm migrating_revision
111 $ hg ci -qAm migrating_revision
112 $ cat > histedit_commands <<EOF
112 $ cat > histedit_commands <<EOF
113 > pick 89079fab8aee 0 r0
113 > pick 89079fab8aee 0 r0
114 > pick e6d271df3142 1 r1
114 > pick e6d271df3142 1 r1
115 > pick 89e25aa83f0f 3 migrating_revision
115 > pick 89e25aa83f0f 3 migrating_revision
116 > pick b550aa12d873 2 r2
116 > pick b550aa12d873 2 r2
117 > EOF
117 > EOF
118 $ cd $TESTTMP/hghistedit/somedir
118 $ cd $TESTTMP/hghistedit/somedir
119 $ hg --config extensions.histedit= histedit -q --commands ../histedit_commands
119 $ hg --config extensions.histedit= histedit -q --commands ../histedit_commands
120
120
121 histedit doesn't output anything when the current diretory is removed. We rely
121 histedit doesn't output anything when the current diretory is removed. We rely
122 on the tests being commonly run on machines where the current directory
122 on the tests being commonly run on machines where the current directory
123 disappearing from underneath us actually has an observable effect, such as an
123 disappearing from underneath us actually has an observable effect, such as an
124 error or no files listed
124 error or no files listed
125 #if linuxormacos
125 #if linuxormacos
126 $ isfile foo
126 $ isfile foo
127 no
127 no
128 #endif
128 #endif
129 $ cd $TESTTMP/hghistedit/somedir
129 $ cd $TESTTMP/hghistedit/somedir
130 $ isfile foo
130 $ isfile foo
131 yes
131 yes
132
132
133 $ cd $TESTTMP/hghistedit
133 $ cd $TESTTMP/hghistedit
134 $ cat > histedit_commands <<EOF
134 $ cat > histedit_commands <<EOF
135 > pick 89079fab8aee 0 r0
135 > pick 89079fab8aee 0 r0
136 > pick 7c7a22c6009f 3 migrating_revision
136 > pick 7c7a22c6009f 3 migrating_revision
137 > pick e6d271df3142 1 r1
137 > pick e6d271df3142 1 r1
138 > pick 40a53c2d4276 2 r2
138 > pick 40a53c2d4276 2 r2
139 > EOF
139 > EOF
140 $ cd $TESTTMP/hghistedit/somedir
140 $ cd $TESTTMP/hghistedit/somedir
141 $ hg $NO_RM --config extensions.histedit= histedit -q --commands ../histedit_commands
141 $ hg $NO_RM --config extensions.histedit= histedit -q --commands ../histedit_commands
142 Regardless of system, we should always get a 'yes' here.
142 Regardless of system, we should always get a 'yes' here.
143 $ isfile foo
143 $ isfile foo
144 yes
144 yes
145 $ cd $TESTTMP
145 $ cd $TESTTMP
146
146
147 This is essentially the exact test from issue5826, just cleaned up a little:
147 This is essentially the exact test from issue5826, just cleaned up a little:
148
148
149 $ hg init issue5826_withrm
149 $ hg init issue5826_withrm
150 $ cd issue5826_withrm
150 $ cd issue5826_withrm
151
151
152 Let's only turn this on for this repo so that we don't contaminate later tests.
152 Let's only turn this on for this repo so that we don't contaminate later tests.
153 $ cat >> .hg/hgrc <<EOF
153 $ cat >> .hg/hgrc <<EOF
154 > [extensions]
154 > [extensions]
155 > histedit =
155 > histedit =
156 > EOF
156 > EOF
157 Commit three revisions that each create a directory:
157 Commit three revisions that each create a directory:
158
158
159 $ mkdir foo
159 $ mkdir foo
160 $ touch foo/bar
160 $ touch foo/bar
161 $ hg commit -qAm "add foo"
161 $ hg commit -qAm "add foo"
162
162
163 $ mkdir bar
163 $ mkdir bar
164 $ touch bar/bar
164 $ touch bar/bar
165 $ hg commit -qAm "add bar"
165 $ hg commit -qAm "add bar"
166
166
167 $ mkdir baz
167 $ mkdir baz
168 $ touch baz/bar
168 $ touch baz/bar
169 $ hg commit -qAm "add baz"
169 $ hg commit -qAm "add baz"
170
170
171 Enter the first directory:
171 Enter the first directory:
172
172
173 $ cd foo
173 $ cd foo
174
174
175 Histedit doing 'pick, pick, fold':
175 Histedit doing 'pick, pick, fold':
176
176
177 #if rmcwd
177 #if rmcwd
178
178
179 $ hg histedit --commands - <<EOF
179 $ hg histedit --commands - <<EOF
180 > pick 6274c77c93c3 1 add bar
180 > pick 6274c77c93c3 1 add bar
181 > pick ff70a87b588f 0 add foo
181 > pick ff70a87b588f 0 add foo
182 > fold 9992bb0ac0db 2 add baz
182 > fold 9992bb0ac0db 2 add baz
183 > EOF
183 > EOF
184 abort: $ENOENT$
184 abort: $ENOENT$
185 [255]
185 [255]
186
186
187 Go back to the repo root after losing it as part of that operation:
187 Go back to the repo root after losing it as part of that operation:
188 $ cd $TESTTMP/issue5826_withrm
188 $ cd $TESTTMP/issue5826_withrm
189
189
190 Note the lack of a non-zero exit code from this function - it exits
190 Note the lack of a non-zero exit code from this function - it exits
191 successfully, but doesn't really do anything.
191 successfully, but doesn't really do anything.
192 $ hg histedit --continue
192 $ hg histedit --continue
193 9992bb0ac0db: cannot fold - working copy is not a descendant of previous commit 5c806432464a
193 9992bb0ac0db: cannot fold - working copy is not a descendant of previous commit 5c806432464a
194 saved backup bundle to $TESTTMP/issue5826_withrm/.hg/strip-backup/ff70a87b588f-e94f9789-histedit.hg
194 saved backup bundle to $TESTTMP/issue5826_withrm/.hg/strip-backup/ff70a87b588f-e94f9789-histedit.hg
195
195
196 $ hg log -T '{rev}:{node|short} {desc}\n'
196 $ hg log -T '{rev}:{node|short} {desc}\n'
197 2:94e3f9fae1d6 fold-temp-revision 9992bb0ac0db
197 2:94e3f9fae1d6 fold-temp-revision 9992bb0ac0db
198 1:5c806432464a add foo
198 1:5c806432464a add foo
199 0:d17db4b0303a add bar
199 0:d17db4b0303a add bar
200
200
201 #else
201 #else
202
202
203 $ cd $TESTTMP/issue5826_withrm
203 $ cd $TESTTMP/issue5826_withrm
204
204
205 $ hg histedit --commands - <<EOF
205 $ hg histedit --commands - <<EOF
206 > pick 6274c77c93c3 1 add bar
206 > pick 6274c77c93c3 1 add bar
207 > pick ff70a87b588f 0 add foo
207 > pick ff70a87b588f 0 add foo
208 > fold 9992bb0ac0db 2 add baz
208 > fold 9992bb0ac0db 2 add baz
209 > EOF
209 > EOF
210 saved backup bundle to $TESTTMP/issue5826_withrm/.hg/strip-backup/5c806432464a-cd4c8d86-histedit.hg
210 saved backup bundle to $TESTTMP/issue5826_withrm/.hg/strip-backup/5c806432464a-cd4c8d86-histedit.hg
211
211
212 $ hg log -T '{rev}:{node|short} {desc}\n'
212 $ hg log -T '{rev}:{node|short} {desc}\n'
213 1:b9eddaa97cbc add foo
213 1:b9eddaa97cbc add foo
214 ***
214 ***
215 add baz
215 add baz
216 0:d17db4b0303a add bar
216 0:d17db4b0303a add bar
217
217
218 #endif
218 #endif
219
219
220 Now test that again with experimental.removeemptydirs=false:
220 Now test that again with experimental.removeemptydirs=false:
221 $ hg init issue5826_norm
221 $ hg init issue5826_norm
222 $ cd issue5826_norm
222 $ cd issue5826_norm
223
223
224 Let's only turn this on for this repo so that we don't contaminate later tests.
224 Let's only turn this on for this repo so that we don't contaminate later tests.
225 $ cat >> .hg/hgrc <<EOF
225 $ cat >> .hg/hgrc <<EOF
226 > [extensions]
226 > [extensions]
227 > histedit =
227 > histedit =
228 > [experimental]
228 > [experimental]
229 > removeemptydirs = false
229 > removeemptydirs = false
230 > EOF
230 > EOF
231 Commit three revisions that each create a directory:
231 Commit three revisions that each create a directory:
232
232
233 $ mkdir foo
233 $ mkdir foo
234 $ touch foo/bar
234 $ touch foo/bar
235 $ hg commit -qAm "add foo"
235 $ hg commit -qAm "add foo"
236
236
237 $ mkdir bar
237 $ mkdir bar
238 $ touch bar/bar
238 $ touch bar/bar
239 $ hg commit -qAm "add bar"
239 $ hg commit -qAm "add bar"
240
240
241 $ mkdir baz
241 $ mkdir baz
242 $ touch baz/bar
242 $ touch baz/bar
243 $ hg commit -qAm "add baz"
243 $ hg commit -qAm "add baz"
244
244
245 Enter the first directory:
245 Enter the first directory:
246
246
247 $ cd foo
247 $ cd foo
248
248
249 Histedit doing 'pick, pick, fold':
249 Histedit doing 'pick, pick, fold':
250
250
251 $ hg histedit --commands - <<EOF
251 $ hg histedit --commands - <<EOF
252 > pick 6274c77c93c3 1 add bar
252 > pick 6274c77c93c3 1 add bar
253 > pick ff70a87b588f 0 add foo
253 > pick ff70a87b588f 0 add foo
254 > fold 9992bb0ac0db 2 add baz
254 > fold 9992bb0ac0db 2 add baz
255 > EOF
255 > EOF
256 saved backup bundle to $TESTTMP/issue5826_withrm/issue5826_norm/.hg/strip-backup/5c806432464a-cd4c8d86-histedit.hg
256 saved backup bundle to $TESTTMP/issue5826_withrm/issue5826_norm/.hg/strip-backup/5c806432464a-cd4c8d86-histedit.hg
257
257
258 Note the lack of a 'cd' being necessary here, and we don't need to 'histedit
258 Note the lack of a 'cd' being necessary here, and we don't need to 'histedit
259 --continue'
259 --continue'
260
260
261 $ hg log -T '{rev}:{node|short} {desc}\n'
261 $ hg log -T '{rev}:{node|short} {desc}\n'
262 1:b9eddaa97cbc add foo
262 1:b9eddaa97cbc add foo
263 ***
263 ***
264 add baz
264 add baz
265 0:d17db4b0303a add bar
265 0:d17db4b0303a add bar
266
266
267 $ cd $TESTTMP
267 $ cd $TESTTMP
268
269 Testing `hg split` being run from inside of a directory that was created in the
270 commit being split:
271
272 $ hg init hgsplit
273 $ cd hgsplit
274 $ cat >> .hg/hgrc << EOF
275 > [ui]
276 > interactive = 1
277 > [extensions]
278 > split =
279 > EOF
280 $ echo anchor > anchor.txt
281 $ hg ci -qAm anchor
282
283 Create a changeset with '/otherfile_in_root' and 'somedir/foo', then try to
284 split it.
285 $ echo otherfile > otherfile_in_root
286 $ mkdir somedir
287 $ cd somedir
288 $ echo hi > foo
289 $ hg ci -qAm split_me
290 (Note: need to make this file not in this directory, or else the bug doesn't
291 reproduce; we're using a separate file due to concerns of portability on
292 `echo -e`)
293 $ cat > ../split_commands << EOF
294 > n
295 > y
296 > y
297 > a
298 > EOF
299
300 The split succeeds on no-rmcwd platforms, which alters the rest of the tests
301 #if rmcwd
302 $ cat ../split_commands | hg split
303 current directory was removed
304 (consider changing to repo root: $TESTTMP/hgsplit)
305 diff --git a/otherfile_in_root b/otherfile_in_root
306 new file mode 100644
307 examine changes to 'otherfile_in_root'? [Ynesfdaq?] n
308
309 diff --git a/somedir/foo b/somedir/foo
310 new file mode 100644
311 examine changes to 'somedir/foo'? [Ynesfdaq?] y
312
313 @@ -0,0 +1,1 @@
314 +hi
315 record change 2/2 to 'somedir/foo'? [Ynesfdaq?] y
316
317 abort: $ENOENT$
318 [255]
319 #endif
320
321 Let's try that again without the rmdir
322 $ cd $TESTTMP/hgsplit/somedir
323 Show that the previous split didn't do anything
324 $ hg log -T '{rev}:{node|short} {desc}\n'
325 1:e26b22a4f0b7 split_me
326 0:7e53273730c0 anchor
327 $ hg status
328 ? split_commands
329 Try again
330 $ cat ../split_commands | hg $NO_RM split
331 diff --git a/otherfile_in_root b/otherfile_in_root
332 new file mode 100644
333 examine changes to 'otherfile_in_root'? [Ynesfdaq?] n
334
335 diff --git a/somedir/foo b/somedir/foo
336 new file mode 100644
337 examine changes to 'somedir/foo'? [Ynesfdaq?] y
338
339 @@ -0,0 +1,1 @@
340 +hi
341 record change 2/2 to 'somedir/foo'? [Ynesfdaq?] y
342
343 created new head
344 diff --git a/otherfile_in_root b/otherfile_in_root
345 new file mode 100644
346 examine changes to 'otherfile_in_root'? [Ynesfdaq?] a
347
348 saved backup bundle to $TESTTMP/hgsplit/.hg/strip-backup/*-split.hg (glob)
349 Show that this split did something
350 $ hg log -T '{rev}:{node|short} {desc}\n'
351 2:a440f24fca4f split_me
352 1:c994f20276ab split_me
353 0:7e53273730c0 anchor
354 $ hg status
355 ? split_commands
General Comments 0
You need to be logged in to leave comments. Login now