hgext/histedit.py
author Brodie Rao <brodie@sf.io>
Fri, 15 Nov 2013 23:18:08 -0500
changeset 20181 b9515fb9e72a
parent 20071 4778f398ec83
child 20503 23dc77874191
child 20770 5d22cadd1938
permissions -rw-r--r--
branchmap: add documentation on the branchcache on-disk format
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
19284
87bb53367633 histedit: raise ImportError when demandloading is enabled
Simon Heimberg <simohe@besonet.ch>
parents: 19048
diff changeset
   143
    pickle.dump # import now
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   144
except ImportError:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   145
    import pickle
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   146
import os
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   147
import sys
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   148
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   149
from mercurial import cmdutil
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   150
from mercurial import discovery
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   151
from mercurial import error
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   152
from mercurial import copies
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   153
from mercurial import context
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   154
from mercurial import hg
17326
23b2ee0f758d histedit: add proper locking around repair.strip() calls
Augie Fackler <raf@durin42.com>
parents: 17315
diff changeset
   155
from mercurial import lock as lockmod
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   156
from mercurial import node
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   157
from mercurial import repair
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   158
from mercurial import scmutil
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   159
from mercurial import util
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   160
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
   161
from mercurial import merge as mergemod
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   162
from mercurial.lock import release
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   163
from mercurial.i18n import _
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   164
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   165
cmdtable = {}
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   166
command = cmdutil.command(cmdtable)
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   167
17069
2b1c78674230 histedit: mark as a first party extension
Augie Fackler <raf@durin42.com>
parents: 17068
diff changeset
   168
testedwith = 'internal'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   169
17337
474ae9720aa5 histedit, i18n: warn translators about edit command names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17326
diff changeset
   170
# 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
   171
editcomment = _("""# Edit history between %s and %s
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   172
#
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   173
# Commands:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   174
#  p, pick = use commit
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   175
#  e, edit = use commit, but stop for amending
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   176
#  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
   177
#  d, drop = remove commit from history
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   178
#  m, mess = edit message without changing commit content
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   179
#
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
   180
""")
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   181
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   182
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
   183
    """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
   184
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
   185
    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
   186
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   187
    - 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
   188
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   189
    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
   190
    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
   191
    """
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   192
    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
   193
    def commitfunc(**kwargs):
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   194
        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
   195
        try:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   196
            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
   197
            extra = kwargs.get('extra', {}).copy()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   198
            extra['histedit_source'] = src.hex()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   199
            kwargs['extra'] = extra
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   200
            return repo.commit(**kwargs)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   201
        finally:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   202
            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
   203
    return commitfunc
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   204
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   205
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   206
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   207
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
   208
    """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
   209
    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
   210
    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
   211
        # 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
   212
        # 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
   213
        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
   214
        stats = None
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   215
    else:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   216
        try:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   217
            # 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
   218
            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
   219
            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
   220
                                    ctx.p1().node())
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   221
        finally:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   222
            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
   223
        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
   224
        repo.dirstate.write()
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   225
        # 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
   226
    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
   227
    return stats
17407
31c123a2f273 histedit: factored out diff/patch logic
Leah Xue <leahxue@fb.com>
parents: 17340
diff changeset
   228
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   229
def collapse(repo, first, last, commitopts):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   230
    """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
   231
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   232
    Expected commit options are:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   233
        - message
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   234
        - date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   235
        - username
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17666
diff changeset
   236
    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
   237
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   238
    This function works in memory."""
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   239
    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
   240
    if not ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   241
        return None
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   242
    base = first.parents()[0]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   243
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   244
    # 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
   245
    # collect all files which might be affected
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   246
    files = set()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   247
    for ctx in ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   248
        files.update(ctx.files())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   249
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   250
    # Recompute copies (avoid recording a -> b -> a)
19392
f6b047cf9272 histedit: use base for computing renames when folding (issue3729)
Martin Geisler <martin@geisler.net>
parents: 19284
diff changeset
   251
    copied = copies.pathcopies(base, last)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   252
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   253
    # 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
   254
    def samefile(f):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   255
        if f in last.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   256
            a = last.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   257
            if f in base.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   258
                b = base.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   259
                return (a.data() == b.data()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   260
                        and a.flags() == b.flags())
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 False
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   263
        else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   264
            return f not in base.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   265
    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
   266
    # 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
   267
    headmf = last.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   268
    def filectxfn(repo, ctx, path):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   269
        if path in headmf:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   270
            fctx = last[path]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   271
            flags = fctx.flags()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   272
            mctx = context.memfilectx(fctx.path(), fctx.data(),
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   273
                                      islink='l' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   274
                                      isexec='x' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   275
                                      copied=copied.get(path))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   276
            return mctx
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   277
        raise IOError()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   278
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   279
    if commitopts.get('message'):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   280
        message = commitopts['message']
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   281
    else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   282
        message = first.description()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   283
    user = commitopts.get('user')
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   284
    date = commitopts.get('date')
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   285
    extra = commitopts.get('extra')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   286
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   287
    parents = (first.p1().node(), first.p2().node())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   288
    new = context.memctx(repo,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   289
                         parents=parents,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   290
                         text=message,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   291
                         files=files,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   292
                         filectxfn=filectxfn,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   293
                         user=user,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   294
                         date=date,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   295
                         extra=extra)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   296
    new._text = cmdutil.commitforceeditor(repo, new, [])
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   297
    return repo.commitctx(new)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   298
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   299
def pick(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   300
    oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   301
    if oldctx.parents()[0] == ctx:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   302
        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
   303
        return oldctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   304
    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
   305
    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
   306
    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
   307
        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
   308
                                           'hg histedit --continue'))
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   309
    # 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
   310
    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
   311
    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
   312
               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
   313
    if n is None:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   314
        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
   315
                     % 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
   316
        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
   317
    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
   318
    return new, [(oldctx.node(), (n,))]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   319
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   320
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   321
def edit(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   322
    oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   323
    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
   324
    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
   325
    raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
   326
        _('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
   327
          '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
   328
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   329
def fold(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   330
    oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   331
    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
   332
    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
   333
    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
   334
        raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
   335
            _('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
   336
    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
   337
                    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
   338
    if n is None:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   339
        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
   340
                     % 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
   341
        return ctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   342
    return finishfold(ui, repo, ctx, oldctx, n, opts, [])
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   343
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   344
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
   345
    parent = ctx.parents()[0].node()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   346
    hg.update(repo, parent)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   347
    ### prepare new commit data
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   348
    commitopts = opts.copy()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   349
    # username
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   350
    if ctx.user() == oldctx.user():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   351
        username = ctx.user()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   352
    else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   353
        username = ui.username()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   354
    commitopts['user'] = username
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   355
    # commit message
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   356
    newmessage = '\n***\n'.join(
17066
baf8887d40e2 histedit: fix most check-code violations
Augie Fackler <raf@durin42.com>
parents: 17064
diff changeset
   357
        [ctx.description()] +
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   358
        [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
   359
        [oldctx.description()]) + '\n'
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   360
    commitopts['message'] = newmessage
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   361
    # date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   362
    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
   363
    extra = ctx.extra().copy()
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   364
    # histedit_source
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   365
    # 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
   366
    #       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
   367
    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
   368
    commitopts['extra'] = extra
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   369
    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
   370
    try:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   371
        phasemin = max(ctx.phase(), oldctx.phase())
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   372
        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
   373
        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
   374
    finally:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   375
        repo.ui.restoreconfig(phasebackup)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   376
    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
   377
        return ctx, []
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   378
    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
   379
    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
   380
                     (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
   381
                     (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
   382
                    ]
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
    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
   384
        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
   385
    return repo[n], replacements
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   386
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   387
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
   388
    return ctx, [(repo[ha].node(), ())]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   389
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   390
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   391
def message(ui, repo, ctx, ha, opts):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   392
    oldctx = repo[ha]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   393
    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
   394
    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
   395
    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
   396
        raise error.InterventionRequired(
93f3a06b2035 histedit: switch from util.Abort to util.InterventionRequired where appropriate (bc)
Augie Fackler <raf@durin42.com>
parents: 18913
diff changeset
   397
            _('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
   398
    message = oldctx.description() + '\n'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   399
    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
   400
    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
   401
    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
   402
                 extra=oldctx.extra())
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   403
    newctx = repo[new]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   404
    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
   405
        return newctx, [(oldctx.node(), (new,))]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   406
    # 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
   407
    return newctx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   408
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   409
def findoutgoing(ui, repo, remote=None, force=False, opts={}):
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   410
    """utility function to find the first outgoing changeset
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   411
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   412
    Used by initialisation code"""
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   413
    dest = ui.expandpath(remote or 'default-push', remote or 'default')
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   414
    dest, revs = hg.parseurl(dest, None)[:2]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   415
    ui.status(_('comparing with %s\n') % util.hidepassword(dest))
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   416
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   417
    revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   418
    other = hg.peer(repo, opts, dest)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   419
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   420
    if revs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   421
        revs = [repo.lookup(rev) for rev in revs]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   422
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   423
    outgoing = discovery.findcommonoutgoing(repo, other, revs, force=force)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   424
    if not outgoing.missing:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   425
        raise util.Abort(_('no outgoing ancestors'))
19841
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   426
    roots = list(repo.revs("roots(%ln)", outgoing.missing))
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   427
    if 1 < len(roots):
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   428
        msg = _('there are ambiguous outgoing revisions')
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   429
        hint = _('see "hg help histedit" for more detail')
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   430
        raise util.Abort(msg, hint=hint)
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   431
    return repo.lookup(roots[0])
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   432
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   433
actiontable = {'p': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   434
               'pick': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   435
               'e': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   436
               'edit': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   437
               'f': fold,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   438
               'fold': fold,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   439
               'd': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   440
               'drop': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   441
               'm': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   442
               'mess': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   443
               }
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   444
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   445
@command('histedit',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   446
    [('', 'commands', '',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   447
      _('Read history edits from the specified file.')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   448
     ('c', 'continue', False, _('continue an edit already in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   449
     ('k', 'keep', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   450
      _("don't strip old nodes after edit is complete")),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   451
     ('', 'abort', False, _('abort an edit in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   452
     ('o', 'outgoing', False, _('changesets not found in destination')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   453
     ('f', 'force', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   454
      _('force outgoing even for unrelated repositories')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   455
     ('r', 'rev', [], _('first revision to be edited'))],
19622
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   456
     _("ANCESTOR | --outgoing [URL]"))
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
   457
def histedit(ui, repo, *freeargs, **opts):
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   458
    """interactively edit changeset history
19621
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   459
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   460
    This command edits changesets between ANCESTOR and the parent of
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   461
    the working directory.
19622
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   462
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   463
    With --outgoing, this edits changesets not found in the
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   464
    destination repository. If URL of the destination is omitted, the
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   465
    'default-push' (or 'default') path will be used.
19842
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   466
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   467
    For safety, this command is aborted, also if there are ambiguous
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   468
    outgoing revisions which may confuse users: for example, there are
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   469
    multiple branches containing outgoing revisions.
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   470
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   471
    Use "min(outgoing() and ::.)" or similar revset specification
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   472
    instead of --outgoing to specify edit target revision exactly in
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   473
    such ambiguous situation. See :hg:`help revsets` for detail about
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   474
    selecting revisions.
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   475
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   476
    Returns 0 on success, 1 if user intervention is required (not only
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   477
    for intentional "edit" command, but also for resolving unexpected
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   478
    conflicts).
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   479
    """
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   480
    lock = wlock = None
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   481
    try:
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   482
        wlock = repo.wlock()
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   483
        lock = repo.lock()
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   484
        _histedit(ui, repo, *freeargs, **opts)
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   485
    finally:
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   486
        release(lock, wlock)
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   487
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   488
def _histedit(ui, repo, *freeargs, **opts):
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   489
    # 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
   490
    # blanket if mq patches are applied somewhere
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   491
    mq = getattr(repo, 'mq', None)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   492
    if mq and mq.applied:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   493
        raise util.Abort(_('source has mq patches applied'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   494
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
   495
    # 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
   496
    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
   497
    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
   498
    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
   499
    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
   500
    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
   501
    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
   502
    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
   503
    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
   504
        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
   505
    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
   506
        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
   507
            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
   508
        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
   509
    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
   510
        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
   511
            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
   512
        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
   513
    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
   514
        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
   515
            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
   516
                               '--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
   517
        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
   518
            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
   519
                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
   520
            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
   521
                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
   522
                    _('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
   523
        else:
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   524
            revs.extend(freeargs)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   525
            if len(revs) != 1:
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
   526
                raise util.Abort(
19621
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   527
                    _('histedit requires exactly one ancestor revision'))
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
   528
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   529
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
   530
    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
   531
        (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   532
        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
   533
        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
   534
        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
   535
    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
   536
        (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
   537
        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
   538
        ui.debug('restore wc to old parent %s\n' % node.short(topmost))
19519
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   539
        # check whether we should update away
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   540
        parentnodes = [c.node() for c in repo[None].parents()]
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   541
        for n in leafs | set([parentctxnode]):
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   542
            if n in parentnodes:
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   543
                hg.clean(repo, topmost)
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   544
                break
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   545
        else:
c2a479a058d0 histedit: don't clobber working copy on --abort if not on histedit cset
Matt Mackall <mpm@selenic.com>
parents: 19496
diff changeset
   546
            pass
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
   547
        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
   548
        cleanupnode(ui, repo, 'temp', leafs)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   549
        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
   550
        return
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   551
    else:
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
   552
        cmdutil.checkunfinished(repo)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   553
        cmdutil.bailifchanged(repo)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   554
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
   555
        topmost, empty = repo.dirstate.parents()
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   556
        if outg:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   557
            if freeargs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   558
                remote = freeargs[0]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   559
            else:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   560
                remote = None
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   561
            root = findoutgoing(ui, repo, remote, force, opts)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   562
        else:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   563
            root = revs[0]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   564
            root = scmutil.revsingle(repo, root).node()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   565
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   566
        keep = opts.get('keep', False)
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   567
        revs = between(repo, root, 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
   568
        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
   569
            raise util.Abort(_('%s is not an ancestor of working directory') %
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   570
                             node.short(root))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   571
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   572
        ctxs = [repo[r] for r in revs]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   573
        if not rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   574
            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
   575
            rules += '\n\n'
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   576
            rules += editcomment % (node.short(root), node.short(topmost))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   577
            rules = ui.edit(rules, ui.username())
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   578
            # 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
   579
            # 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
   580
            # surprising happens.
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   581
            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
   582
            f.write(rules)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   583
            f.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   584
        else:
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   585
            if rules == '-':
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   586
                f = sys.stdin
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   587
            else:
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   588
                f = open(rules)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   589
            rules = f.read()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   590
            f.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   591
        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
   592
                 if l and not l[0] == '#']
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   593
        rules = verifyrules(rules, repo, ctxs)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   594
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   595
        parentctx = repo[root].parents()[0]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   596
        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
   597
        replacements = []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   598
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   599
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   600
    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
   601
        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
   602
        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
   603
        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
   604
        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
   605
        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
   606
        replacements.extend(replacement_)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   607
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   608
    hg.update(repo, parentctx.node())
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   609
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
   610
    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
   611
    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
   612
        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
   613
            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
   614
                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
   615
            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
   616
                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
   617
                    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
   618
                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
   619
                    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
   620
                    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
   621
                        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
   622
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   623
    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
   624
        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
   625
            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
   626
            # TODO update mq state
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   627
        if obsolete._enabled:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   628
            markers = []
17771
dcfa526b180b histedit: create obsolescence markers in deterministic order
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17769
diff changeset
   629
            # 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
   630
            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
   631
                succs = mapping[prec]
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   632
                markers.append((repo[prec],
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   633
                                tuple(repo[s] for s in succs)))
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   634
            if markers:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   635
                obsolete.createmarkers(repo, markers)
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   636
        else:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   637
            cleanupnode(ui, repo, 'replaced', mapping)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   638
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   639
    cleanupnode(ui, repo, 'temp', tmpnodes)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   640
    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
   641
    if os.path.exists(repo.sjoin('undo')):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   642
        os.unlink(repo.sjoin('undo'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   643
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   644
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
   645
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
   646
    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
   647
    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
   648
    # 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
   649
    #
40601f2b7608 histedit: simplify computation of `newchildren` during --continue
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17666
diff changeset
   650
    # 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
   651
    #       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
   652
    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
   653
    if parentctx.node() != node.nullid:
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
   654
        if not newchildren:
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
   655
            # `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
   656
            # 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
   657
            msg = _('%s is not an ancestor of working directory')
19847
45c3086880c7 histedit: suggest "histedit --abort" for inconsistent histedit state
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19842
diff changeset
   658
            hint = _('use "histedit --abort" to clear broken state')
18913
79580b3140cd histedit: support editing of the first commit (issue3767)
Bryan O'Sullivan <bryano@fb.com>
parents: 18644
diff changeset
   659
            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
   660
        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
   661
    # 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
   662
    new = None
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
   663
    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
   664
    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
   665
        # 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
   666
        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
   667
            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
   668
        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
   669
            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
   670
        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
   671
            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
   672
        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
   673
            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
   674
        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
   675
        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
   676
                     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
   677
                     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
   678
        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
   679
            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
   680
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
    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
   682
    # 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
   683
    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
   684
        # 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
   685
        # 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
   686
        # 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
   687
        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
   688
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
   689
    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
   690
        if newchildren:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   691
            # 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
   692
            if new is None:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   693
                new = newchildren[-1]
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   694
            else:
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   695
                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
   696
            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
   697
                                         newchildren)
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   698
            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
   699
        else:
19017
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   700
            # 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
   701
            # 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
   702
            # merge.
c5c8613f265e histedit: properly handle --continue on empty fold
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18995
diff changeset
   703
            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
   704
    elif newchildren:
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
   705
        # 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
   706
        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
   707
    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
   708
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
   709
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
   710
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
   711
    """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
   712
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
   713
    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
   714
    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
   715
    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
   716
        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
   717
            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
   718
            raise util.Abort(_('cannot edit history that would orphan nodes'))
19473
10a0ae668fe6 histedit: refuse to edit history that contains merges (issue3962)
Augie Fackler <raf@durin42.com>
parents: 19393
diff changeset
   719
        if repo.revs('(%ld) and merge()', ctxs):
10a0ae668fe6 histedit: refuse to edit history that contains merges (issue3962)
Augie Fackler <raf@durin42.com>
parents: 19393
diff changeset
   720
            raise util.Abort(_('cannot edit history that contains merges'))
17767
a787e46d3b94 histedit: do not use "min" on ctx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17766
diff changeset
   721
        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
   722
        if not root.phase():
57f27cbfc5bb histedit: refuse to edit public changeset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17761
diff changeset
   723
            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
   724
    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
   725
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
   726
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
   727
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
   728
    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
   729
    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
   730
    fp.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   731
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   732
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
   733
    """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
   734
    """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   735
    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
   736
    return pickle.load(fp)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   737
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   738
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   739
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
   740
    """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
   741
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   742
    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
   743
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   744
      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
   745
    """
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   746
    summary = ''
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   747
    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
   748
        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
   749
    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
   750
    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
   751
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   752
def verifyrules(rules, repo, ctxs):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   753
    """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
   754
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   755
    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
   756
    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
   757
    """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   758
    parsed = []
19046
36adbbe960ca histedit: track short hash instead of changectx object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19045
diff changeset
   759
    expected = set(str(c) for c in ctxs)
19047
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
   760
    seen = set()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   761
    for r in rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   762
        if ' ' not in r:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   763
            raise util.Abort(_('malformed line "%s"') % r)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   764
        action, rest = r.split(' ', 1)
19039
41669a18a7d6 histedit: handle multiple spaces between action and hash (issue3893)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19021
diff changeset
   765
        ha = rest.strip().split(' ', 1)[0]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   766
        try:
19045
080b801c34f1 histedit: ensure rules return short hex at all time
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19039
diff changeset
   767
            ha = str(repo[ha])  # ensure its a short hash
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   768
        except error.RepoError:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   769
            raise util.Abort(_('unknown changeset %s listed') % ha)
19046
36adbbe960ca histedit: track short hash instead of changectx object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19045
diff changeset
   770
        if ha not in expected:
19045
080b801c34f1 histedit: ensure rules return short hex at all time
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19039
diff changeset
   771
            raise util.Abort(
080b801c34f1 histedit: ensure rules return short hex at all time
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19039
diff changeset
   772
                _('may not use changesets other than the ones listed'))
19047
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
   773
        if ha in seen:
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
   774
            raise util.Abort(_('duplicated command for changeset %s') % ha)
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
   775
        seen.add(ha)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   776
        if action not in actiontable:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   777
            raise util.Abort(_('unknown action "%s"') % action)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   778
        parsed.append([action, ha])
19048
1163ff06ce89 histedit: more precise user message when changeset is missing
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19047
diff changeset
   779
    missing = sorted(expected - seen)  # sort to stabilize output
1163ff06ce89 histedit: more precise user message when changeset is missing
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19047
diff changeset
   780
    if missing:
1163ff06ce89 histedit: more precise user message when changeset is missing
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19047
diff changeset
   781
        raise util.Abort(_('missing rules for changeset %s') % missing[0],
1163ff06ce89 histedit: more precise user message when changeset is missing
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19047
diff changeset
   782
                         hint=_('do you want to use the drop action?'))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   783
    return parsed
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
   784
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
   785
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
   786
    """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
   787
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
    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
   789
    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
   790
    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
   791
    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
   792
    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
   793
    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
   794
    # 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
   795
    # 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
   796
    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
   797
        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
   798
        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
   799
        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
   800
    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
   801
    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
   802
    # 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
   803
    # 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
   804
    # 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
   805
    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
   806
    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
   807
    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
   808
        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
   809
            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
   810
            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
   811
                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
   812
                    # 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
   813
                    # 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
   814
                    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
   815
                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
   816
                    # 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
   817
                    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
   818
                    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
   819
            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
   820
                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
   821
                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
   822
    # 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
   823
    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
   824
        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
   825
    # 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
   826
    # 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
   827
    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
   828
    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
   829
        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
   830
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
   831
    # 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
   832
    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
   833
        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
   834
    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
   835
        # 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
   836
        # 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
   837
        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
   838
    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
   839
        # 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
   840
        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
   841
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
   842
    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
   843
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
   844
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
   845
    """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
   846
    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
   847
        # 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
   848
        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
   849
    moves = []
18370
c605e12dd622 histedit: process bookmarks in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18324
diff changeset
   850
    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
   851
        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
   852
            # 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
   853
            #
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
   854
            # 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
   855
            # 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
   856
            # 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
   857
            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
   858
            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
   859
        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
   860
        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
   861
        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
   862
            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
   863
        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
   864
            # 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
   865
            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
   866
            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
   867
            # 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
   868
        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
   869
    if moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
   870
        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
   871
        for mark, new in moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
   872
            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
   873
            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
   874
                    % (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
   875
            marks[mark] = new
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
   876
        marks.write()
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   877
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   878
def cleanupnode(ui, repo, name, nodes):
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   879
    """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
   880
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   881
    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
   882
    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
   883
             (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
   884
    lock = None
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   885
    try:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   886
        lock = repo.lock()
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   887
        # 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
   888
        # (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
   889
        nm = repo.changelog.nodemap
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   890
        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
   891
        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
   892
        for c in roots:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   893
            # 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
   894
            # 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
   895
            # This would reduce bundle overhead
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   896
            repair.strip(ui, repo, c)
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   897
    finally:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
   898
        lockmod.release(lock)
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   899
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   900
def summaryhook(ui, repo):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   901
    if not os.path.exists(repo.join('histedit-state')):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   902
        return
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   903
    (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   904
    if rules:
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   905
        # i18n: column positioning for "hg summary"
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   906
        ui.write(_('hist:   %s (histedit --continue)\n') %
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   907
                 (ui.label(_('%d remaining'), 'histedit.remaining') %
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   908
                  len(rules)))
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   909
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   910
def extsetup(ui):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
   911
    cmdutil.summaryhooks.add('histedit', summaryhook)
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
   912
    cmdutil.unfinishedstates.append(
19496
607191a45f8c checkunfinished: accommodate histedit quirk
Matt Mackall <mpm@selenic.com>
parents: 19479
diff changeset
   913
        ['histedit-state', False, True, _('histedit in progress'),
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
   914
         _("use 'hg histedit --continue' or 'hg histedit --abort'")])