annotate hgext/histedit.py @ 19020:12c06686d371

histedit: move all arguments checks to the beginning of the command This changeset move all checks and raises related to arguments validation to the top of the file. This gathers all the logic in one place and clarifies the code doing actual work. This paves the way for splitting this gigantic function in separated functions. A `goal` variable is introduced in the process. It holds the action to be done by this invocation (new, continue or abort). An invalid invocation is found in the process (the new code is a bit stricter).
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Tue, 16 Apr 2013 21:17:13 +0200
parents 730614b9b352
children 26b41a902195
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
1 # histedit.py - interactive history editing for mercurial
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
2 #
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
3 # Copyright 2009 Augie Fackler <raf@durin42.com>
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
4 #
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
7 """interactive history editing
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
8
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
9 With this extension installed, Mercurial gains one new command: histedit. Usage
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
10 is as follows, assuming the following history::
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
11
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
12 @ 3[tip] 7c2fd3b9020c 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
13 | Add delta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
14 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
15 o 2 030b686bedc4 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
16 | Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
17 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
18 o 1 c561b4e977df 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
19 | Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
20 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
21 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
22 Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
23
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
24 If you were to run ``hg histedit c561b4e977df``, you would see the following
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
25 file open in your editor::
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
26
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
27 pick c561b4e977df Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
28 pick 030b686bedc4 Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
29 pick 7c2fd3b9020c Add delta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
30
18322
e819c12a8bd0 histedit: correct changeset IDs in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17771
diff changeset
31 # Edit history between c561b4e977df and 7c2fd3b9020c
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
32 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
33 # Commands:
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
34 # p, pick = use commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
35 # e, edit = use commit, but stop for amending
17335
b5c560787a4e histedit: sync docstring with edit comment
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17326
diff changeset
36 # f, fold = use commit, but fold into previous commit (combines N and N-1)
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
37 # d, drop = remove commit from history
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
38 # m, mess = edit message without changing commit content
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
39 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
40
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
41 In this file, lines beginning with ``#`` are ignored. You must specify a rule
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
42 for each revision in your history. For example, if you had meant to add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
43 before beta, and then wanted to add delta in the same revision as beta, you
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
44 would reorganize the file to look like this::
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
45
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
46 pick 030b686bedc4 Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
47 pick c561b4e977df Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
48 fold 7c2fd3b9020c Add delta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
49
18322
e819c12a8bd0 histedit: correct changeset IDs in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17771
diff changeset
50 # Edit history between c561b4e977df and 7c2fd3b9020c
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
51 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
52 # Commands:
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
53 # p, pick = use commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
54 # e, edit = use commit, but stop for amending
17335
b5c560787a4e histedit: sync docstring with edit comment
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17326
diff changeset
55 # f, fold = use commit, but fold into previous commit (combines N and N-1)
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
56 # d, drop = remove commit from history
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
57 # m, mess = edit message without changing commit content
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
58 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
59
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
60 At which point you close the editor and ``histedit`` starts working. When you
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
61 specify a ``fold`` operation, ``histedit`` will open an editor when it folds
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
62 those revisions together, offering you a chance to clean up the commit message::
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
63
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
64 Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
65 ***
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
66 Add delta
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
67
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
68 Edit the commit message to your liking, then close the editor. For
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
69 this example, let's assume that the commit message was changed to
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
70 ``Add beta and delta.`` After histedit has run and had a chance to
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
71 remove any old or temporary revisions it needed, the history looks
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
72 like this::
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
73
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
74 @ 2[tip] 989b4d060121 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
75 | Add beta and delta.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
76 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
77 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
78 | Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
79 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
80 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
81 Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
82
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
83 Note that ``histedit`` does *not* remove any revisions (even its own temporary
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
84 ones) until after it has completed all the editing operations, so it will
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
85 probably perform several strip operations when it's done. For the above example,
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
86 it had to run strip twice. Strip can be slow depending on a variety of factors,
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
87 so you might need to be a little patient. You can choose to keep the original
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
88 revisions by passing the ``--keep`` flag.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
89
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
90 The ``edit`` operation will drop you back to a command prompt,
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
91 allowing you to edit files freely, or even use ``hg record`` to commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
92 some changes as a separate commit. When you're done, any remaining
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
93 uncommitted changes will be committed as well. When done, run ``hg
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
94 histedit --continue`` to finish this step. You'll be prompted for a
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
95 new commit message, but the default commit message will be the
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
96 original message for the ``edit`` ed revision.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
97
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
98 The ``message`` operation will give you a chance to revise a commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
99 message without changing the contents. It's a shortcut for doing
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
100 ``edit`` immediately followed by `hg histedit --continue``.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
101
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
102 If ``histedit`` encounters a conflict when moving a revision (while
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
103 handling ``pick`` or ``fold``), it'll stop in a similar manner to
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
104 ``edit`` with the difference that it won't prompt you for a commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
105 message when done. If you decide at this point that you don't like how
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
106 much work it will be to rearrange history, or that you made a mistake,
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
107 you can use ``hg histedit --abort`` to abandon the new changes you
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
108 have made and return to the state before you attempted to edit your
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
109 history.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
110
18323
7648b87e76db histedit: correct the number of added revisions in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18322
diff changeset
111 If we clone the histedit-ed example repository above and add four more
7648b87e76db histedit: correct the number of added revisions in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18322
diff changeset
112 changes, such that we have the following history::
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
113
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
114 @ 6[tip] 038383181893 2009-04-27 18:04 -0500 stefan
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
115 | Add theta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
116 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
117 o 5 140988835471 2009-04-27 18:04 -0500 stefan
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
118 | Add eta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
119 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
120 o 4 122930637314 2009-04-27 18:04 -0500 stefan
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
121 | Add zeta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
122 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
123 o 3 836302820282 2009-04-27 18:04 -0500 stefan
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
124 | Add epsilon
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
125 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
126 o 2 989b4d060121 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
127 | Add beta and delta.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
128 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
129 o 1 081603921c3f 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
130 | Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
131 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
132 o 0 d8d2fcd0e319 2009-04-27 18:04 -0500 durin42
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
133 Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
134
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
135 If you run ``hg histedit --outgoing`` on the clone then it is the same
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
136 as running ``hg histedit 836302820282``. If you need plan to push to a
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
137 repository that Mercurial does not detect to be related to the source
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
138 repo, you can add a ``--force`` option.
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
139 """
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
140
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
141 try:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
142 import cPickle as pickle
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
143 except ImportError:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
144 import pickle
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
145 import os
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
146 import sys
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
147
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
148 from mercurial import cmdutil
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
149 from mercurial import discovery
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
150 from mercurial import error
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
151 from mercurial import copies
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
152 from mercurial import context
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
153 from mercurial import hg
17326
23b2ee0f758d histedit: add proper locking around repair.strip() calls
Augie Fackler <raf@durin42.com>
parents: 17315
diff changeset
154 from mercurial import lock as lockmod
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
155 from mercurial import node
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
156 from mercurial import repair
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
157 from mercurial import scmutil
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
158 from mercurial import util
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
159 from mercurial import obsolete
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
160 from mercurial import merge as mergemod
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
161 from mercurial.i18n import _
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
162
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
163 cmdtable = {}
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
164 command = cmdutil.command(cmdtable)
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
165
17069
2b1c78674230 histedit: mark as a first party extension
Augie Fackler <raf@durin42.com>
parents: 17068
diff changeset
166 testedwith = 'internal'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
167
17337
474ae9720aa5 histedit, i18n: warn translators about edit command names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17326
diff changeset
168 # i18n: command names and abbreviations must remain untranslated
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
169 editcomment = _("""# Edit history between %s and %s
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
170 #
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
171 # Commands:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
172 # p, pick = use commit
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
173 # e, edit = use commit, but stop for amending
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
174 # f, fold = use commit, but fold into previous commit (combines N and N-1)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
175 # d, drop = remove commit from history
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
176 # m, mess = edit message without changing commit content
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
177 #
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
178 """)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
179
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
180 def commitfuncfor(repo, src):
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
181 """Build a commit function for the replacement of <src>
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
182
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
183 This function ensure we apply the same treatment to all changesets.
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
184
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
185 - Add a 'histedit_source' entry in extra.
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
186
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
187 Note that fold have its own separated logic because its handling is a bit
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
188 different and not easily factored out of the fold method.
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
189 """
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
190 phasemin = src.phase()
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
191 def commitfunc(**kwargs):
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
192 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
193 try:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
194 repo.ui.setconfig('phases', 'new-commit', phasemin)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
195 extra = kwargs.get('extra', {}).copy()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
196 extra['histedit_source'] = src.hex()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
197 kwargs['extra'] = extra
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
198 return repo.commit(**kwargs)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
199 finally:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
200 repo.ui.restoreconfig(phasebackup)
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
201 return commitfunc
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
202
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
203
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
204
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
205 def applychanges(ui, repo, ctx, opts):
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
206 """Merge changeset from ctx (only) in the current working directory"""
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
207 wcpar = repo.dirstate.parents()[0]
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
208 if ctx.p1().node() == wcpar:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
209 # edition ar "in place" we do not need to make any merge,
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
210 # just applies changes on parent for edition
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
211 cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
212 stats = None
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
213 else:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
214 try:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
215 # ui.forcemerge is an internal variable, do not document
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
216 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
217 stats = mergemod.update(repo, ctx.node(), True, True, False,
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
218 ctx.p1().node())
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
219 finally:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
220 repo.ui.setconfig('ui', 'forcemerge', '')
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
221 repo.setparents(wcpar, node.nullid)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
222 repo.dirstate.write()
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
223 # fix up dirstate for copies and renames
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
224 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
225 return stats
17407
31c123a2f273 histedit: factored out diff/patch logic
Leah Xue <leahxue@fb.com>
parents: 17340
diff changeset
226
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
227 def collapse(repo, first, last, commitopts):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
228 """collapse the set of revisions from first to last as new one.
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
229
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
230 Expected commit options are:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
231 - message
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
232 - date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
233 - username
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17666
diff changeset
234 Commit message is edited in all cases.
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
235
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
236 This function works in memory."""
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
237 ctxs = list(repo.set('%d::%d', first, last))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
238 if not ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
239 return None
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
240 base = first.parents()[0]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
241
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
242 # commit a new version of the old changeset, including the update
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
243 # collect all files which might be affected
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
244 files = set()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
245 for ctx in ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
246 files.update(ctx.files())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
247
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
248 # Recompute copies (avoid recording a -> b -> a)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
249 copied = copies.pathcopies(first, last)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
250
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
251 # prune files which were reverted by the updates
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
252 def samefile(f):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
253 if f in last.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
254 a = last.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
255 if f in base.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
256 b = base.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
257 return (a.data() == b.data()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
258 and a.flags() == b.flags())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
259 else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
260 return False
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
261 else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
262 return f not in base.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
263 files = [f for f in files if not samefile(f)]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
264 # commit version of these files as defined by head
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
265 headmf = last.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
266 def filectxfn(repo, ctx, path):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
267 if path in headmf:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
268 fctx = last[path]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
269 flags = fctx.flags()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
270 mctx = context.memfilectx(fctx.path(), fctx.data(),
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
271 islink='l' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
272 isexec='x' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
273 copied=copied.get(path))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
274 return mctx
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
275 raise IOError()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
276
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
277 if commitopts.get('message'):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
278 message = commitopts['message']
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
279 else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
280 message = first.description()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
281 user = commitopts.get('user')
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
282 date = commitopts.get('date')
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
283 extra = commitopts.get('extra')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
284
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
285 parents = (first.p1().node(), first.p2().node())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
286 new = context.memctx(repo,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
287 parents=parents,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
288 text=message,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
289 files=files,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
290 filectxfn=filectxfn,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
291 user=user,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
292 date=date,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
293 extra=extra)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
294 new._text = cmdutil.commitforceeditor(repo, new, [])
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
295 return repo.commitctx(new)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
296
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
297 def pick(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
298 oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
299 if oldctx.parents()[0] == ctx:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
300 ui.debug('node %s unchanged\n' % ha)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
301 return oldctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
302 hg.update(repo, ctx.node())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
303 stats = applychanges(ui, repo, oldctx, opts)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
304 if stats and stats[3] > 0:
18934
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
305 raise error.InterventionRequired(_('Fix up the change and run '
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
306 'hg histedit --continue'))
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
307 # drop the second merge parent
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
308 commit = commitfuncfor(repo, oldctx)
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
309 n = commit(text=oldctx.description(), user=oldctx.user(),
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
310 date=oldctx.date(), extra=oldctx.extra())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
311 if n is None:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
312 ui.warn(_('%s: empty changeset\n')
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
313 % node.hex(ha))
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
314 return ctx, []
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
315 new = repo[n]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
316 return new, [(oldctx.node(), (n,))]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
317
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
318
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
319 def edit(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
320 oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
321 hg.update(repo, ctx.node())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
322 applychanges(ui, repo, oldctx, opts)
18934
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
323 raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
324 _('Make changes as needed, you may commit or record as needed now.\n'
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
325 'When you are finished, run hg histedit --continue to resume.'))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
326
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
327 def fold(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
328 oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
329 hg.update(repo, ctx.node())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
330 stats = applychanges(ui, repo, oldctx, opts)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
331 if stats and stats[3] > 0:
18934
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
332 raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
333 _('Fix up the change and run hg histedit --continue'))
17066
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
334 n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(),
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
335 date=oldctx.date(), extra=oldctx.extra())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
336 if n is None:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
337 ui.warn(_('%s: empty changeset')
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
338 % node.hex(ha))
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
339 return ctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
340 return finishfold(ui, repo, ctx, oldctx, n, opts, [])
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
341
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
342 def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
343 parent = ctx.parents()[0].node()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
344 hg.update(repo, parent)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
345 ### prepare new commit data
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
346 commitopts = opts.copy()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
347 # username
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
348 if ctx.user() == oldctx.user():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
349 username = ctx.user()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
350 else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
351 username = ui.username()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
352 commitopts['user'] = username
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
353 # commit message
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
354 newmessage = '\n***\n'.join(
17066
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
355 [ctx.description()] +
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
356 [repo[r].description() for r in internalchanges] +
17241
c2f13180001f histedit: end folding message with an LF
Patrick Mezard <patrick@mezard.eu>
parents: 17191
diff changeset
357 [oldctx.description()]) + '\n'
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
358 commitopts['message'] = newmessage
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
359 # date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
360 commitopts['date'] = max(ctx.date(), oldctx.date())
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
361 extra = ctx.extra().copy()
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
362 # histedit_source
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
363 # note: ctx is likely a temporary commit but that the best we can do here
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
364 # This is sufficient to solve issue3681 anyway
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
365 extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
366 commitopts['extra'] = extra
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
367 phasebackup = repo.ui.backupconfig('phases', 'new-commit')
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
368 try:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
369 phasemin = max(ctx.phase(), oldctx.phase())
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
370 repo.ui.setconfig('phases', 'new-commit', phasemin)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
371 n = collapse(repo, ctx, repo[newnode], commitopts)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
372 finally:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
373 repo.ui.restoreconfig(phasebackup)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
374 if n is None:
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
375 return ctx, []
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
376 hg.update(repo, n)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
377 replacements = [(oldctx.node(), (newnode,)),
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
378 (ctx.node(), (n,)),
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
379 (newnode, (n,)),
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
380 ]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
381 for ich in internalchanges:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
382 replacements.append((ich, (n,)))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
383 return repo[n], replacements
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
384
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
385 def drop(ui, repo, ctx, ha, opts):
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
386 return ctx, [(repo[ha].node(), ())]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
387
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
388
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
389 def message(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
390 oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
391 hg.update(repo, ctx.node())
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
392 stats = applychanges(ui, repo, oldctx, opts)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
393 if stats and stats[3] > 0:
18934
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
394 raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
395 _('Fix up the change and run hg histedit --continue'))
17285
0f6f10d5f7a6 histedit: add trailing newline when editing commit messages
Mads Kiilerich <mads@kiilerich.com>
parents: 17275
diff changeset
396 message = oldctx.description() + '\n'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
397 message = ui.edit(message, ui.username())
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
398 commit = commitfuncfor(repo, oldctx)
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
399 new = commit(text=message, user=oldctx.user(), date=oldctx.date(),
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
400 extra=oldctx.extra())
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
401 newctx = repo[new]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
402 if oldctx.node() != newctx.node():
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
403 return newctx, [(oldctx.node(), (new,))]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
404 # We didn't make an edit, so just indicate no replaced nodes
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
405 return newctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
406
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
407 actiontable = {'p': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
408 'pick': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
409 'e': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
410 'edit': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
411 'f': fold,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
412 'fold': fold,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
413 'd': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
414 'drop': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
415 'm': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
416 'mess': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
417 }
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
418
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
419 @command('histedit',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
420 [('', 'commands', '',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
421 _('Read history edits from the specified file.')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
422 ('c', 'continue', False, _('continue an edit already in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
423 ('k', 'keep', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
424 _("don't strip old nodes after edit is complete")),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
425 ('', 'abort', False, _('abort an edit in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
426 ('o', 'outgoing', False, _('changesets not found in destination')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
427 ('f', 'force', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
428 _('force outgoing even for unrelated repositories')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
429 ('r', 'rev', [], _('first revision to be edited'))],
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
430 _("[PARENT]"))
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
431 def histedit(ui, repo, *freeargs, **opts):
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
432 """interactively edit changeset history
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
433 """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
434 # TODO only abort if we try and histedit mq patches, not just
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
435 # blanket if mq patches are applied somewhere
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
436 mq = getattr(repo, 'mq', None)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
437 if mq and mq.applied:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
438 raise util.Abort(_('source has mq patches applied'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
439
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
440 # basic argument incompatibility processing
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
441 outg = opts.get('outgoing')
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
442 cont = opts.get('continue')
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
443 abort = opts.get('abort')
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
444 force = opts.get('force')
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
445 rules = opts.get('commands', '')
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
446 revs = opts.get('rev', [])
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
447 goal = 'new' # This invocation goal, in new, continue, abort
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
448 if force and not outg:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
449 raise util.Abort(_('--force only allowed with --outgoing'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
450 if cont:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
451 if util.any((outg, abort, revs, freeargs, rules)):
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
452 raise util.Abort(_('no arguments allowed with --continue'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
453 goal = 'continue'
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
454 elif abort:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
455 if util.any((outg, revs, freeargs, rules)):
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
456 raise util.Abort(_('no arguments allowed with --abort'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
457 goal = 'abort'
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
458 else:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
459 if os.path.exists(os.path.join(repo.path, 'histedit-state')):
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
460 raise util.Abort(_('history edit already in progress, try '
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
461 '--continue or --abort'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
462 if outg:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
463 if revs:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
464 raise util.Abort(_('no revisions allowed with --outgoing'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
465 if len(freeargs) > 1:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
466 raise util.Abort(
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
467 _('only one repo argument allowed with --outgoing'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
468 else:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
469 parent = list(freeargs) + opts.get('rev', [])
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
470 if len(parent) != 1:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
471 raise util.Abort(
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
472 _('histedit requires exactly one parent revision'))
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
473
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
474 if opts.get('outgoing'):
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
475 if freeargs:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
476 parent = freeargs[0]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
477
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
478 dest = ui.expandpath(parent or 'default-push', parent or 'default')
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
479 dest, revs = hg.parseurl(dest, None)[:2]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
480 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
481
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
482 revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
17191
5884812686f7 peer: introduce peer methods to prepare for peer classes
Sune Foldager <cryo@cyanite.org>
parents: 17147
diff changeset
483 other = hg.peer(repo, opts, dest)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
484
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
485 if revs:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
486 revs = [repo.lookup(rev) for rev in revs]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
487
18507
c795c9f87792 histedit: prevent parent guessed via --outgoing from being a revset (issue3770)
Augie Fackler <raf@durin42.com>
parents: 18440
diff changeset
488 # hexlify nodes from outgoing, because we're going to parse
c795c9f87792 histedit: prevent parent guessed via --outgoing from being a revset (issue3770)
Augie Fackler <raf@durin42.com>
parents: 18440
diff changeset
489 # parent[0] using revsingle below, and if the binary hash
c795c9f87792 histedit: prevent parent guessed via --outgoing from being a revset (issue3770)
Augie Fackler <raf@durin42.com>
parents: 18440
diff changeset
490 # contains special revset characters like ":" the revset
c795c9f87792 histedit: prevent parent guessed via --outgoing from being a revset (issue3770)
Augie Fackler <raf@durin42.com>
parents: 18440
diff changeset
491 # parser can choke.
c795c9f87792 histedit: prevent parent guessed via --outgoing from being a revset (issue3770)
Augie Fackler <raf@durin42.com>
parents: 18440
diff changeset
492 parent = [node.hex(n) for n in discovery.findcommonoutgoing(
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
493 repo, other, revs, force=force).missing[0:1]]
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
494 if not parent:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
495 raise util.Abort(_('no outgoing ancestors'))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
496
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
497 if goal == 'continue':
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
498 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
499 currentparent, wantnull = repo.dirstate.parents()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
500 parentctx = repo[parentctxnode]
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
501 parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
502 replacements.extend(repl)
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
503 elif goal == 'abort':
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
504 (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
505 mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
506 ui.debug('restore wc to old parent %s\n' % node.short(topmost))
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
507 hg.clean(repo, topmost)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
508 cleanupnode(ui, repo, 'created', tmpnodes)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
509 cleanupnode(ui, repo, 'temp', leafs)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
510 os.unlink(os.path.join(repo.path, 'histedit-state'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
511 return
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
512 else:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
513 cmdutil.bailifchanged(repo)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
514
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
515 topmost, empty = repo.dirstate.parents()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
516
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
517 parent = scmutil.revsingle(repo, parent[0]).node()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
518
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
519 keep = opts.get('keep', False)
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
520 revs = between(repo, parent, topmost, keep)
17766
d9da327516f8 histedit: clean abort when there is nothing to edit
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17765
diff changeset
521 if not revs:
18608
3adbd57e1794 histedit: report when revisions to edit are not ancestors of working dir
Simon Heimberg <simohe@besonet.ch>
parents: 18507
diff changeset
522 raise util.Abort(_('%s is not an ancestor of working directory') %
3adbd57e1794 histedit: report when revisions to edit are not ancestors of working dir
Simon Heimberg <simohe@besonet.ch>
parents: 18507
diff changeset
523 node.short(parent))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
524
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
525 ctxs = [repo[r] for r in revs]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
526 if not rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
527 rules = '\n'.join([makedesc(c) for c in ctxs])
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
528 rules += '\n\n'
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
529 rules += editcomment % (node.short(parent), node.short(topmost))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
530 rules = ui.edit(rules, ui.username())
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
531 # Save edit rules in .hg/histedit-last-edit.txt in case
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
532 # the user needs to ask for help after something
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
533 # surprising happens.
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
534 f = open(repo.join('histedit-last-edit.txt'), 'w')
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
535 f.write(rules)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
536 f.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
537 else:
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
538 if rules == '-':
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
539 f = sys.stdin
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
540 else:
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
541 f = open(rules)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
542 rules = f.read()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
543 f.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
544 rules = [l for l in (r.strip() for r in rules.splitlines())
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
545 if l and not l[0] == '#']
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
546 rules = verifyrules(rules, repo, ctxs)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
547
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
548 parentctx = repo[parent].parents()[0]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
549 keep = opts.get('keep', False)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
550 replacements = []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
551
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
552
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
553 while rules:
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
554 writestate(repo, parentctx.node(), rules, keep, topmost, replacements)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
555 action, ha = rules.pop(0)
17645
4721fc933943 histedit: display action being processed in debug mode
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17644
diff changeset
556 ui.debug('histedit: processing %s %s\n' % (action, ha))
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
557 actfunc = actiontable[action]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
558 parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
559 replacements.extend(replacement_)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
560
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
561 hg.update(repo, parentctx.node())
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
562
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
563 mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
564 if mapping:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
565 for prec, succs in mapping.iteritems():
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
566 if not succs:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
567 ui.debug('histedit: %s is dropped\n' % node.short(prec))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
568 else:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
569 ui.debug('histedit: %s is replaced by %s\n' % (
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
570 node.short(prec), node.short(succs[0])))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
571 if len(succs) > 1:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
572 m = 'histedit: %s'
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
573 for n in succs[1:]:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
574 ui.debug(m % node.short(n))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
575
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
576 if not keep:
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
577 if mapping:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
578 movebookmarks(ui, repo, mapping, topmost, ntm)
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
579 # TODO update mq state
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
580 if obsolete._enabled:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
581 markers = []
17771
dcfa526b180b histedit: create obsolescence markers in deterministic order
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17769
diff changeset
582 # sort by revision number because it sound "right"
dcfa526b180b histedit: create obsolescence markers in deterministic order
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17769
diff changeset
583 for prec in sorted(mapping, key=repo.changelog.rev):
dcfa526b180b histedit: create obsolescence markers in deterministic order
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17769
diff changeset
584 succs = mapping[prec]
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
585 markers.append((repo[prec],
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
586 tuple(repo[s] for s in succs)))
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
587 if markers:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
588 obsolete.createmarkers(repo, markers)
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
589 else:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
590 cleanupnode(ui, repo, 'replaced', mapping)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
591
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
592 cleanupnode(ui, repo, 'temp', tmpnodes)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
593 os.unlink(os.path.join(repo.path, 'histedit-state'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
594 if os.path.exists(repo.sjoin('undo')):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
595 os.unlink(repo.sjoin('undo'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
596
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
597
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
598 def bootstrapcontinue(ui, repo, parentctx, rules, opts):
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
599 action, currentnode = rules.pop(0)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
600 ctx = repo[currentnode]
17749
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
601 # is there any new commit between the expected parent and "."
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
602 #
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
603 # note: does not take non linear new change in account (but previous
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
604 # implementation didn't used them anyway (issue3655)
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
605 newchildren = [c.node() for c in repo.set('(%d::.)', parentctx)]
18913
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
606 if parentctx.node() != node.nullid:
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
607 if not newchildren:
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
608 # `parentctxnode` should match but no result. This means that
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
609 # currentnode is not a descendant from parentctxnode.
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
610 msg = _('%s is not an ancestor of working directory')
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
611 hint = _('update to %s or descendant and run "hg histedit '
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
612 '--continue" again') % parentctx
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
613 raise util.Abort(msg % parentctx, hint=hint)
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
614 newchildren.pop(0) # remove parentctxnode
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
615 # Commit dirty working directory if necessary
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
616 new = None
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
617 m, a, r, d = repo.status()[:4]
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
618 if m or a or r or d:
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
619 # prepare the message for the commit to comes
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
620 if action in ('f', 'fold'):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
621 message = 'fold-temp-revision %s' % currentnode
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
622 else:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
623 message = ctx.description() + '\n'
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
624 if action in ('e', 'edit', 'm', 'mess'):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
625 editor = cmdutil.commitforceeditor
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
626 else:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
627 editor = False
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
628 commit = commitfuncfor(repo, ctx)
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
629 new = commit(text=message, user=ctx.user(),
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
630 date=ctx.date(), extra=ctx.extra(),
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
631 editor=editor)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
632 if new is not None:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
633 newchildren.append(new)
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
634
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
635 replacements = []
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
636 # track replacements
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
637 if ctx.node() not in newchildren:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
638 # note: new children may be empty when the changeset is dropped.
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
639 # this happen e.g during conflicting pick where we revert content
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
640 # to parent.
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
641 replacements.append((ctx.node(), tuple(newchildren)))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
642
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
643 if action in ('f', 'fold'):
19017
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
644 if newchildren:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
645 # finalize fold operation if applicable
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
646 if new is None:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
647 new = newchildren[-1]
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
648 else:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
649 newchildren.pop() # remove new from internal changes
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
650 parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
651 newchildren)
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
652 replacements.extend(repl)
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
653 else:
19017
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
654 # newchildren is empty if the fold did not result in any commit
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
655 # this happen when all folded change are discarded during the
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
656 # merge.
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
657 replacements.append((ctx.node(), (parentctx.node(),)))
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
658 elif newchildren:
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
659 # otherwise update "parentctx" before proceeding to further operation
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
660 parentctx = repo[newchildren[-1]]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
661 return parentctx, replacements
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
662
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
663
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
664 def between(repo, old, new, keep):
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
665 """select and validate the set of revision to edit
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
666
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
667 When keep is false, the specified set can't have children."""
17765
ef7760f0be87 histedit: rename `revs` in `ctxs` inside the `between` function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17762
diff changeset
668 ctxs = list(repo.set('%n::%n', old, new))
17766
d9da327516f8 histedit: clean abort when there is nothing to edit
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17765
diff changeset
669 if ctxs and not keep:
18165
0f5a0a2073a8 histedit: allow operation from non-head if obsolete is enabled
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17922
diff changeset
670 if (not obsolete._enabled and
18270
48deb483a8f8 clfilter: drop unnecessary explicit filtering on histedit
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18165
diff changeset
671 repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
17762
57f27cbfc5bb histedit: refuse to edit public changeset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17761
diff changeset
672 raise util.Abort(_('cannot edit history that would orphan nodes'))
17767
a787e46d3b94 histedit: do not use "min" on ctx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17766
diff changeset
673 root = ctxs[0] # list is already sorted by repo.set
17762
57f27cbfc5bb histedit: refuse to edit public changeset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17761
diff changeset
674 if not root.phase():
57f27cbfc5bb histedit: refuse to edit public changeset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17761
diff changeset
675 raise util.Abort(_('cannot edit immutable changeset: %s') % root)
17765
ef7760f0be87 histedit: rename `revs` in `ctxs` inside the `between` function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17762
diff changeset
676 return [c.node() for c in ctxs]
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
677
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
678
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
679 def writestate(repo, parentnode, rules, keep, topmost, replacements):
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
680 fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
681 pickle.dump((parentnode, rules, keep, topmost, replacements), fp)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
682 fp.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
683
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
684 def readstate(repo):
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
685 """Returns a tuple of (parentnode, rules, keep, topmost, replacements).
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
686 """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
687 fp = open(os.path.join(repo.path, 'histedit-state'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
688 return pickle.load(fp)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
689
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
690
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
691 def makedesc(c):
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
692 """build a initial action line for a ctx `c`
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
693
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
694 line are in the form:
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
695
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
696 pick <hash> <rev> <summary>
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
697 """
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
698 summary = ''
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
699 if c.description():
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
700 summary = c.description().splitlines()[0]
17662
4f2390e3f4b0 histedit: remove all usages of hex[:12]
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17647
diff changeset
701 line = 'pick %s %d %s' % (c, c.rev(), summary)
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
702 return line[:80] # trim to 80 chars so it's not stupidly wide in my editor
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
703
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
704 def verifyrules(rules, repo, ctxs):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
705 """Verify that there exists exactly one edit rule per given changeset.
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
706
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
707 Will abort if there are to many or too few rules, a malformed rule,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
708 or a rule on a changeset outside of the user-given range.
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
709 """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
710 parsed = []
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
711 if len(rules) != len(ctxs):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
712 raise util.Abort(_('must specify a rule for each changeset once'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
713 for r in rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
714 if ' ' not in r:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
715 raise util.Abort(_('malformed line "%s"') % r)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
716 action, rest = r.split(' ', 1)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
717 if ' ' in rest.strip():
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
718 ha, rest = rest.split(' ', 1)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
719 else:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
720 ha = r.strip()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
721 try:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
722 if repo[ha] not in ctxs:
17066
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
723 raise util.Abort(
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
724 _('may not use changesets other than the ones listed'))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
725 except error.RepoError:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
726 raise util.Abort(_('unknown changeset %s listed') % ha)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
727 if action not in actiontable:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
728 raise util.Abort(_('unknown action "%s"') % action)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
729 parsed.append([action, ha])
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
730 return parsed
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
731
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
732 def processreplacement(repo, replacements):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
733 """process the list of replacements to return
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
734
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
735 1) the final mapping between original and created nodes
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
736 2) the list of temporary node created by histedit
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
737 3) the list of new commit created by histedit"""
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
738 allsuccs = set()
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
739 replaced = set()
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
740 fullmapping = {}
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
741 # initialise basic set
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
742 # fullmapping record all operation recorded in replacement
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
743 for rep in replacements:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
744 allsuccs.update(rep[1])
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
745 replaced.add(rep[0])
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
746 fullmapping.setdefault(rep[0], set()).update(rep[1])
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
747 new = allsuccs - replaced
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
748 tmpnodes = allsuccs & replaced
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
749 # Reduce content fullmapping into direct relation between original nodes
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
750 # and final node created during history edition
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
751 # Dropped changeset are replaced by an empty list
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
752 toproceed = set(fullmapping)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
753 final = {}
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
754 while toproceed:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
755 for x in list(toproceed):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
756 succs = fullmapping[x]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
757 for s in list(succs):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
758 if s in toproceed:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
759 # non final node with unknown closure
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
760 # We can't process this now
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
761 break
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
762 elif s in final:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
763 # non final node, replace with closure
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
764 succs.remove(s)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
765 succs.update(final[s])
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
766 else:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
767 final[x] = succs
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
768 toproceed.remove(x)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
769 # remove tmpnodes from final mapping
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
770 for n in tmpnodes:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
771 del final[n]
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
772 # we expect all changes involved in final to exist in the repo
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
773 # turn `final` into list (topologically sorted)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
774 nm = repo.changelog.nodemap
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
775 for prec, succs in final.items():
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
776 final[prec] = sorted(succs, key=nm.get)
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
777
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
778 # computed topmost element (necessary for bookmark)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
779 if new:
17769
8672e615d81c histedit: max(x, key=y) and min(x, key=y) are not available in python 2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17767
diff changeset
780 newtopmost = sorted(new, key=repo.changelog.rev)[-1]
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
781 elif not final:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
782 # Nothing rewritten at all. we won't need `newtopmost`
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
783 # It is the same as `oldtopmost` and `processreplacement` know it
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
784 newtopmost = None
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
785 else:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
786 # every body died. The newtopmost is the parent of the root.
17769
8672e615d81c histedit: max(x, key=y) and min(x, key=y) are not available in python 2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17767
diff changeset
787 newtopmost = repo[sorted(final, key=repo.changelog.rev)[0]].p1().node()
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
788
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
789 return final, tmpnodes, new, newtopmost
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
790
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
791 def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
792 """Move bookmark from old to newly created node"""
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
793 if not mapping:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
794 # if nothing got rewritten there is not purpose for this function
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
795 return
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
796 moves = []
18370
c605e12dd622 histedit: process bookmarks in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18324
diff changeset
797 for bk, old in sorted(repo._bookmarks.iteritems()):
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
798 if old == oldtopmost:
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
799 # special case ensure bookmark stay on tip.
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
800 #
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
801 # This is arguably a feature and we may only want that for the
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
802 # active bookmark. But the behavior is kept compatible with the old
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
803 # version for now.
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
804 moves.append((bk, newtopmost))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
805 continue
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
806 base = old
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
807 new = mapping.get(base, None)
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
808 if new is None:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
809 continue
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
810 while not new:
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
811 # base is killed, trying with parent
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
812 base = repo[base].p1().node()
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
813 new = mapping.get(base, (base,))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
814 # nothing to move
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
815 moves.append((bk, new[-1]))
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
816 if moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
817 marks = repo._bookmarks
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
818 for mark, new in moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
819 old = marks[mark]
17758
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
820 ui.note(_('histedit: moving bookmarks %s from %s to %s\n')
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
821 % (mark, node.short(old), node.short(new)))
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
822 marks[mark] = new
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
823 marks.write()
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
824
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
825 def cleanupnode(ui, repo, name, nodes):
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
826 """strip a group of nodes from the repository
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
827
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
828 The set of node to strip may contains unknown nodes."""
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
829 ui.debug('should strip %s nodes %s\n' %
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
830 (name, ', '.join([node.short(n) for n in nodes])))
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
831 lock = None
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
832 try:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
833 lock = repo.lock()
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
834 # Find all node that need to be stripped
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
835 # (we hg %lr instead of %ln to silently ignore unknown item
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
836 nm = repo.changelog.nodemap
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
837 nodes = [n for n in nodes if n in nm]
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
838 roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
839 for c in roots:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
840 # We should process node in reverse order to strip tip most first.
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
841 # but this trigger a bug in changegroup hook.
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
842 # This would reduce bundle overhead
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
843 repair.strip(ui, repo, c)
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
844 finally:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
845 lockmod.release(lock)