Mercurial > public > mercurial-scm > hg
annotate hgext/split.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 42e2c7c52e1b |
children | 687b865b95ad |
rev | line source |
---|---|
35455 | 1 # split.py - split a changeset into smaller ones |
2 # | |
3 # Copyright 2015 Laurent Charignon <lcharignon@fb.com> | |
4 # Copyright 2017 Facebook, Inc. | |
5 # | |
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. | |
8 """command to split a changeset into smaller ones (EXPERIMENTAL)""" | |
9 | |
10 from __future__ import absolute_import | |
11 | |
12 from mercurial.i18n import _ | |
13 | |
14 from mercurial.node import ( | |
15 nullid, | |
16 short, | |
17 ) | |
18 | |
19 from mercurial import ( | |
20 bookmarks, | |
21 cmdutil, | |
22 commands, | |
23 error, | |
24 hg, | |
25 obsolete, | |
26 phases, | |
36400
7b86aa31b004
py3: fix handling of keyword arguments at more places
Pulkit Goyal <7895pulkit@gmail.com>
parents:
35455
diff
changeset
|
27 pycompat, |
35455 | 28 registrar, |
29 revsetlang, | |
30 scmutil, | |
31 ) | |
32 | |
33 # allow people to use split without explicitly enabling rebase extension | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
34 from . import rebase |
35455 | 35 |
36 cmdtable = {} | |
37 command = registrar.command(cmdtable) | |
38 | |
39 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | |
40 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | |
41 # be specifying the version(s) of Mercurial they are tested with, or | |
42 # leave the attribute unspecified. | |
43 testedwith = 'ships-with-hg-core' | |
44 | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
45 |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
46 @command( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
47 'split', |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
48 [ |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
49 ('r', 'rev', '', _("revision to split"), _('REV')), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
50 ('', 'rebase', True, _('rebase descendants after split')), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
51 ] |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
52 + cmdutil.commitopts2, |
40293
c303d65d2e34
help: assigning categories to existing commands
rdamazio@google.com
parents:
38424
diff
changeset
|
53 _('hg split [--no-rebase] [[-r] REV]'), |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
54 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
55 helpbasic=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
56 ) |
35455 | 57 def split(ui, repo, *revs, **opts): |
58 """split a changeset into smaller ones | |
59 | |
60 Repeatedly prompt changes and commit message for new changesets until there | |
61 is nothing left in the original changeset. | |
62 | |
63 If --rev was not given, split the working directory parent. | |
64 | |
65 By default, rebase connected non-obsoleted descendants onto the new | |
66 changeset. Use --no-rebase to avoid the rebase. | |
67 """ | |
38069
5ba0cf22e4d0
py3: fix kwargs handling in hgext/split.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
36408
diff
changeset
|
68 opts = pycompat.byteskwargs(opts) |
35455 | 69 revlist = [] |
70 if opts.get('rev'): | |
71 revlist.append(opts.get('rev')) | |
72 revlist.extend(revs) | |
73 with repo.wlock(), repo.lock(), repo.transaction('split') as tr: | |
74 revs = scmutil.revrange(repo, revlist or ['.']) | |
75 if len(revs) > 1: | |
76 raise error.Abort(_('cannot split multiple revisions')) | |
77 | |
78 rev = revs.first() | |
79 ctx = repo[rev] | |
80 if rev is None or ctx.node() == nullid: | |
81 ui.status(_('nothing to split\n')) | |
82 return 1 | |
83 if ctx.node() is None: | |
84 raise error.Abort(_('cannot split working directory')) | |
85 | |
86 # rewriteutil.precheck is not very useful here because: | |
87 # 1. null check is done above and it's more friendly to return 1 | |
88 # instead of abort | |
89 # 2. mergestate check is done below by cmdutil.bailifchanged | |
90 # 3. unstable check is more complex here because of --rebase | |
91 # | |
92 # So only "public" check is useful and it's checked directly here. | |
93 if ctx.phase() == phases.public: | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
94 raise error.Abort( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
95 _('cannot split public changeset'), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
96 hint=_("see 'hg help phases' for details"), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
97 ) |
35455 | 98 |
99 descendants = list(repo.revs('(%d::) - (%d)', rev, rev)) | |
100 alloworphaned = obsolete.isenabled(repo, obsolete.allowunstableopt) | |
101 if opts.get('rebase'): | |
102 # Skip obsoleted descendants and their descendants so the rebase | |
103 # won't cause conflicts for sure. | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
104 torebase = list( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
105 repo.revs( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
106 '%ld - (%ld & obsolete())::', descendants, descendants |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
107 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
108 ) |
35455 | 109 if not alloworphaned and len(torebase) != len(descendants): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
110 raise error.Abort( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
111 _('split would leave orphaned changesets ' 'behind') |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
112 ) |
35455 | 113 else: |
114 if not alloworphaned and descendants: | |
115 raise error.Abort( | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
116 _('cannot split changeset with children without rebase') |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
117 ) |
35455 | 118 torebase = () |
119 | |
120 if len(ctx.parents()) > 1: | |
121 raise error.Abort(_('cannot split a merge changeset')) | |
122 | |
123 cmdutil.bailifchanged(repo) | |
124 | |
125 # Deactivate bookmark temporarily so it won't get moved unintentionally | |
126 bname = repo._activebookmark | |
127 if bname and repo._bookmarks[bname] != ctx.node(): | |
128 bookmarks.deactivate(repo) | |
129 | |
130 wnode = repo['.'].node() | |
131 top = None | |
132 try: | |
133 top = dosplit(ui, repo, tr, ctx, opts) | |
134 finally: | |
135 # top is None: split failed, need update --clean recovery. | |
136 # wnode == ctx.node(): wnode split, no need to update. | |
137 if top is None or wnode != ctx.node(): | |
138 hg.clean(repo, wnode, show_stats=False) | |
139 if bname: | |
140 bookmarks.activate(repo, bname) | |
141 if torebase and top: | |
142 dorebase(ui, repo, torebase, top) | |
143 | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
144 |
35455 | 145 def dosplit(ui, repo, tr, ctx, opts): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
146 committed = [] # [ctx] |
35455 | 147 |
148 # Set working parent to ctx.p1(), and keep working copy as ctx's content | |
41966
42e2c7c52e1b
split: use the new movedirstate() we now have in scmutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
40295
diff
changeset
|
149 if ctx.node() != repo.dirstate.p1(): |
42e2c7c52e1b
split: use the new movedirstate() we now have in scmutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
40295
diff
changeset
|
150 hg.clean(repo, ctx.node(), show_stats=False) |
42e2c7c52e1b
split: use the new movedirstate() we now have in scmutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
40295
diff
changeset
|
151 with repo.dirstate.parentchange(): |
42e2c7c52e1b
split: use the new movedirstate() we now have in scmutil
Martin von Zweigbergk <martinvonz@google.com>
parents:
40295
diff
changeset
|
152 scmutil.movedirstate(repo, ctx.p1()) |
35455 | 153 |
154 # Any modified, added, removed, deleted result means split is incomplete | |
155 incomplete = lambda repo: any(repo.status()[:4]) | |
156 | |
157 # Main split loop | |
158 while incomplete(repo): | |
159 if committed: | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
160 header = _( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
161 'HG: Splitting %s. So far it has been split into:\n' |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
162 ) % short(ctx.node()) |
35455 | 163 for c in committed: |
164 firstline = c.description().split('\n', 1)[0] | |
165 header += _('HG: - %s: %s\n') % (short(c.node()), firstline) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
166 header += _( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
167 'HG: Write commit message for the next split ' 'changeset.\n' |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
168 ) |
35455 | 169 else: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
170 header = _( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
171 'HG: Splitting %s. Write commit message for the ' |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
172 'first split changeset.\n' |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
173 ) % short(ctx.node()) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
174 opts.update( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
175 { |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
176 'edit': True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
177 'interactive': True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
178 'message': header + ctx.description(), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
179 } |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
180 ) |
36400
7b86aa31b004
py3: fix handling of keyword arguments at more places
Pulkit Goyal <7895pulkit@gmail.com>
parents:
35455
diff
changeset
|
181 commands.commit(ui, repo, **pycompat.strkwargs(opts)) |
35455 | 182 newctx = repo['.'] |
183 committed.append(newctx) | |
184 | |
185 if not committed: | |
186 raise error.Abort(_('cannot split an empty revision')) | |
187 | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
188 scmutil.cleanupnodes( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
189 repo, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
190 {ctx.node(): [c.node() for c in committed]}, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
191 operation='split', |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
192 fixphase=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
193 ) |
35455 | 194 |
195 return committed[-1] | |
196 | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
197 |
36408
83bade6206d4
split: use ctx.rev() instead of %d % ctx
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36400
diff
changeset
|
198 def dorebase(ui, repo, src, destctx): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
199 rebase.rebase( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
200 ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
201 repo, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
202 rev=[revsetlang.formatspec('%ld', src)], |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
203 dest=revsetlang.formatspec('%d', destctx.rev()), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41966
diff
changeset
|
204 ) |