hgext/histedit.py
author Siddharth Agarwal <sid0@fb.com>
Sun, 11 Oct 2015 20:04:40 -0700
changeset 26610 f9f82c444ff7
parent 26587 56b2bcea2529
child 26696 78aa4392c261
permissions -rw-r--r--
filemerge: only copy to backup during premerge step The premerge might leave the original file in an unclean state. Therefore it's important to only copy the file in the beginning.
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
 #
20503
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
    33
 # Commits are listed from least to most recent
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
    34
 #
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    35
 # Commands:
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    36
 #  p, pick = use commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    37
 #  e, edit = use commit, but stop for amending
20511
5840da876235 histedit: shorten new fold message
Matt Mackall <mpm@selenic.com>
parents: 20503
diff changeset
    38
 #  f, fold = use commit, but combine it with the one above
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
    39
 #  r, roll = like fold, but discard this commit's description
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    40
 #  d, drop = remove commit from history
26100
5706d130ec16 histedit: improve discoverability of edit commit message
timeless@mozdev.org
parents: 26098
diff changeset
    41
 #  m, mess = edit commit message without changing commit content
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    42
 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    43
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    44
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
    45
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
    46
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
    47
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
    48
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    49
 pick 030b686bedc4 Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    50
 pick c561b4e977df Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    51
 fold 7c2fd3b9020c Add delta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    52
18322
e819c12a8bd0 histedit: correct changeset IDs in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17771
diff changeset
    53
 # Edit history between c561b4e977df and 7c2fd3b9020c
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    54
 #
20503
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
    55
 # Commits are listed from least to most recent
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
    56
 #
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    57
 # Commands:
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    58
 #  p, pick = use commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    59
 #  e, edit = use commit, but stop for amending
20511
5840da876235 histedit: shorten new fold message
Matt Mackall <mpm@selenic.com>
parents: 20503
diff changeset
    60
 #  f, fold = use commit, but combine it with the one above
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
    61
 #  r, roll = like fold, but discard this commit's description
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    62
 #  d, drop = remove commit from history
26100
5706d130ec16 histedit: improve discoverability of edit commit message
timeless@mozdev.org
parents: 26098
diff changeset
    63
 #  m, mess = edit commit message without changing commit content
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    64
 #
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
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
    67
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
    68
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
    69
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    70
 Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    71
 ***
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    72
 Add delta
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    73
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    74
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
    75
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
    76
``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
    77
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
    78
like this::
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
 @  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
    81
 |    Add beta and delta.
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
 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
    84
 |    Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    85
 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    86
 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
    87
      Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    88
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    89
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
    90
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
    91
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
    92
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
    93
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
    94
revisions by passing the ``--keep`` flag.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    95
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    96
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
    97
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
    98
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
    99
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
   100
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
   101
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
   102
original message for the ``edit`` ed revision.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   103
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   104
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
   105
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
   106
``edit`` immediately followed by `hg histedit --continue``.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   107
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   108
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
   109
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
   110
``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
   111
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
   112
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
   113
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
   114
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
   115
history.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   116
18323
7648b87e76db histedit: correct the number of added revisions in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18322
diff changeset
   117
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
   118
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
   119
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   120
   @  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
   121
   |    Add theta
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  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
   124
   |    Add eta
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  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
   127
   |    Add zeta
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  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
   130
   |    Add epsilon
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  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
   133
   |    Add beta and delta.
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
   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
   136
   |    Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   137
   |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   138
   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
   139
        Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   140
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   141
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
   142
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
   143
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
   144
repo, you can add a ``--force`` option.
24199
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
   145
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
   146
Histedit rule lines are truncated to 80 characters by default. You
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   147
can customize this behavior by setting a different length in your
24869
95a67d687903 histedit: fix reST syntax problem of example code in help document
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24831
diff changeset
   148
configuration file::
24199
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
   149
24869
95a67d687903 histedit: fix reST syntax problem of example code in help document
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24831
diff changeset
   150
  [histedit]
95a67d687903 histedit: fix reST syntax problem of example code in help document
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24831
diff changeset
   151
  linelen = 120      # truncate rule lines at 120 characters
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   152
"""
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   153
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   154
try:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   155
    import cPickle as pickle
19284
87bb53367633 histedit: raise ImportError when demandloading is enabled
Simon Heimberg <simohe@besonet.ch>
parents: 19048
diff changeset
   156
    pickle.dump # import now
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   157
except ImportError:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   158
    import pickle
22368
802dffd62de5 histedit: abort gracefully on --continue/--abort with no state
Siddharth Agarwal <sid0@fb.com>
parents: 22147
diff changeset
   159
import errno
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   160
import os
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   161
import sys
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   162
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   163
from mercurial import cmdutil
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   164
from mercurial import discovery
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   165
from mercurial import error
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   166
from mercurial import changegroup
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   167
from mercurial import copies
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   168
from mercurial import context
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   169
from mercurial import exchange
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
   170
from mercurial import extensions
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   171
from mercurial import hg
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   172
from mercurial import node
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   173
from mercurial import repair
21950
af44c7a1e55e histedit: respect revsetalias entries (issue4311)
Augie Fackler <raf@durin42.com>
parents: 21858
diff changeset
   174
from mercurial import scmutil
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   175
from mercurial import util
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   176
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
   177
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
   178
from mercurial.lock import release
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   179
from mercurial.i18n import _
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   180
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   181
cmdtable = {}
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   182
command = cmdutil.command(cmdtable)
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   183
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 25149
diff changeset
   184
# Note for extension authors: ONLY specify testedwith = 'internal' for
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 25149
diff changeset
   185
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 25149
diff changeset
   186
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 25149
diff changeset
   187
# leave the attribute unspecified.
17069
2b1c78674230 histedit: mark as a first party extension
Augie Fackler <raf@durin42.com>
parents: 17068
diff changeset
   188
testedwith = 'internal'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   189
17337
474ae9720aa5 histedit, i18n: warn translators about edit command names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17326
diff changeset
   190
# 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
   191
editcomment = _("""# Edit history between %s and %s
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   192
#
20503
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
   193
# Commits are listed from least to most recent
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
   194
#
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   195
# Commands:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   196
#  p, pick = use commit
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   197
#  e, edit = use commit, but stop for amending
20511
5840da876235 histedit: shorten new fold message
Matt Mackall <mpm@selenic.com>
parents: 20503
diff changeset
   198
#  f, fold = use commit, but combine it with the one above
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   199
#  r, roll = like fold, but discard this commit's description
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   200
#  d, drop = remove commit from history
26100
5706d130ec16 histedit: improve discoverability of edit commit message
timeless@mozdev.org
parents: 26098
diff changeset
   201
#  m, mess = edit commit message without changing commit content
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   202
#
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
   203
""")
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   204
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   205
class histeditstate(object):
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   206
    def __init__(self, repo, parentctxnode=None, rules=None, keep=None,
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   207
            topmost=None, replacements=None, lock=None, wlock=None):
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   208
        self.repo = repo
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   209
        self.rules = rules
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   210
        self.keep = keep
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   211
        self.topmost = topmost
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   212
        self.parentctxnode = parentctxnode
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   213
        self.lock = lock
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   214
        self.wlock = wlock
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   215
        self.backupfile = None
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   216
        if replacements is None:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   217
            self.replacements = []
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   218
        else:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   219
            self.replacements = replacements
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   220
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   221
    def read(self):
22986
7b93b49286d0 histedit: update docstring on histeditstate.read()
Augie Fackler <raf@durin42.com>
parents: 22985
diff changeset
   222
        """Load histedit state from disk and set fields appropriately."""
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   223
        try:
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   224
            fp = self.repo.vfs('histedit-state', 'r')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25452
diff changeset
   225
        except IOError as err:
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   226
            if err.errno != errno.ENOENT:
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   227
                raise
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   228
            raise error.Abort(_('no histedit in progress'))
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   229
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   230
        try:
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   231
            data = pickle.load(fp)
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   232
            parentctxnode, rules, keep, topmost, replacements = data
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   233
            backupfile = None
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   234
        except pickle.UnpicklingError:
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   235
            data = self._load()
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   236
            parentctxnode, rules, keep, topmost, replacements, backupfile = data
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   237
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   238
        self.parentctxnode = parentctxnode
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   239
        self.rules = rules
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   240
        self.keep = keep
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   241
        self.topmost = topmost
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   242
        self.replacements = replacements
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   243
        self.backupfile = backupfile
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   244
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   245
    def write(self):
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   246
        fp = self.repo.vfs('histedit-state', 'w')
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   247
        fp.write('v1\n')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   248
        fp.write('%s\n' % node.hex(self.parentctxnode))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   249
        fp.write('%s\n' % node.hex(self.topmost))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   250
        fp.write('%s\n' % self.keep)
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   251
        fp.write('%d\n' % len(self.rules))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   252
        for rule in self.rules:
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   253
            fp.write('%s\n' % rule[0]) # action
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   254
            fp.write('%s\n' % rule[1]) # remainder
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   255
        fp.write('%d\n' % len(self.replacements))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   256
        for replacement in self.replacements:
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   257
            fp.write('%s%s\n' % (node.hex(replacement[0]), ''.join(node.hex(r)
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   258
                for r in replacement[1])))
24958
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   259
        backupfile = self.backupfile
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   260
        if not backupfile:
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   261
            backupfile = ''
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   262
        fp.write('%s\n' % backupfile)
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   263
        fp.close()
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   264
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   265
    def _load(self):
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   266
        fp = self.repo.vfs('histedit-state', 'r')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   267
        lines = [l[:-1] for l in fp.readlines()]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   268
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   269
        index = 0
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   270
        lines[index] # version number
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   271
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   272
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   273
        parentctxnode = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   274
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   275
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   276
        topmost = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   277
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   278
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   279
        keep = lines[index] == 'True'
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   280
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   281
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   282
        # Rules
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   283
        rules = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   284
        rulelen = int(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   285
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   286
        for i in xrange(rulelen):
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   287
            ruleaction = lines[index]
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   288
            index += 1
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   289
            rule = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   290
            index += 1
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   291
            rules.append((ruleaction, rule))
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   292
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   293
        # Replacements
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   294
        replacements = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   295
        replacementlen = int(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   296
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   297
        for i in xrange(replacementlen):
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   298
            replacement = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   299
            original = node.bin(replacement[:40])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   300
            succ = [node.bin(replacement[i:i + 40]) for i in
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   301
                    range(40, len(replacement), 40)]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   302
            replacements.append((original, succ))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   303
            index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   304
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   305
        backupfile = lines[index]
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   306
        index += 1
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   307
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   308
        fp.close()
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   309
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   310
        return parentctxnode, rules, keep, topmost, replacements, backupfile
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   311
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
   312
    def clear(self):
26583
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   313
        if self.inprogress():
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   314
            self.repo.vfs.unlink('histedit-state')
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
   315
26582
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   316
    def inprogress(self):
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   317
        return self.repo.vfs.exists('histedit-state')
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   318
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   319
class histeditaction(object):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   320
    def __init__(self, state, node):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   321
        self.state = state
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   322
        self.repo = state.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   323
        self.node = node
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   324
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   325
    @classmethod
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   326
    def fromrule(cls, state, rule):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   327
        """Parses the given rule, returning an instance of the histeditaction.
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   328
        """
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   329
        repo = state.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   330
        rulehash = rule.strip().split(' ', 1)[0]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   331
        try:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   332
            node = repo[rulehash].node()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   333
        except error.RepoError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   334
            raise error.Abort(_('unknown changeset %s listed') % rulehash[:12])
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   335
        return cls(state, node)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   336
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   337
    def run(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   338
        """Runs the action. The default behavior is simply apply the action's
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   339
        rulectx onto the current parentctx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   340
        self.applychange()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   341
        self.continuedirty()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   342
        return self.continueclean()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   343
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   344
    def applychange(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   345
        """Applies the changes from this action's rulectx onto the current
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   346
        parentctx, but does not commit them."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   347
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   348
        rulectx = repo[self.node]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   349
        hg.update(repo, self.state.parentctxnode)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   350
        stats = applychanges(repo.ui, repo, rulectx, {})
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   351
        if stats and stats[3] > 0:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   352
            raise error.InterventionRequired(_('Fix up the change and run '
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   353
                                            'hg histedit --continue'))
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   354
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   355
    def continuedirty(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   356
        """Continues the action when changes have been applied to the working
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   357
        copy. The default behavior is to commit the dirty changes."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   358
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   359
        rulectx = repo[self.node]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   360
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   361
        editor = self.commiteditor()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   362
        commit = commitfuncfor(repo, rulectx)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   363
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   364
        commit(text=rulectx.description(), user=rulectx.user(),
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   365
               date=rulectx.date(), extra=rulectx.extra(), editor=editor)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   366
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   367
    def commiteditor(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   368
        """The editor to be used to edit the commit message."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   369
        return False
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   370
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   371
    def continueclean(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   372
        """Continues the action when the working copy is clean. The default
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   373
        behavior is to accept the current commit as the new version of the
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   374
        rulectx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   375
        ctx = self.repo['.']
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   376
        if ctx.node() == self.state.parentctxnode:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   377
            self.repo.ui.warn(_('%s: empty changeset\n') %
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   378
                              node.short(self.node))
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   379
            return ctx, [(self.node, tuple())]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   380
        if ctx.node() == self.node:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   381
            # Nothing changed
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   382
            return ctx, []
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   383
        return ctx, [(self.node, (ctx.node(),))]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   384
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   385
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
   386
    """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
   387
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
   388
    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
   389
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   390
    - 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
   391
25450
7e36c3000ead histedit: copyedit docstring wording problem I noticed while here
Augie Fackler <augie@google.com>
parents: 25412
diff changeset
   392
    Note that fold has its own separated logic because its handling is a bit
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   393
    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
   394
    """
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   395
    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
   396
    def commitfunc(**kwargs):
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   397
        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
   398
        try:
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20773
diff changeset
   399
            repo.ui.setconfig('phases', 'new-commit', phasemin,
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20773
diff changeset
   400
                              'histedit')
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   401
            extra = kwargs.get('extra', {}).copy()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   402
            extra['histedit_source'] = src.hex()
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   403
            kwargs['extra'] = extra
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   404
            return repo.commit(**kwargs)
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   405
        finally:
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   406
            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
   407
    return commitfunc
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   408
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   409
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
   410
    """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
   411
    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
   412
    if ctx.p1().node() == wcpar:
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   413
        # edits are "in place" we do not need to make any merge,
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   414
        # 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
   415
        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
   416
        stats = None
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   417
    else:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   418
        try:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   419
            # ui.forcemerge is an internal variable, do not document
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20773
diff changeset
   420
            repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20773
diff changeset
   421
                              'histedit')
22904
baa3cfa03a83 histedit: use merge.graft
Matt Mackall <mpm@selenic.com>
parents: 22901
diff changeset
   422
            stats = mergemod.graft(repo, ctx, ctx.p1(), ['local', 'histedit'])
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   423
        finally:
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20773
diff changeset
   424
            repo.ui.setconfig('ui', 'forcemerge', '', 'histedit')
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   425
    return stats
17407
31c123a2f273 histedit: factored out diff/patch logic
Leah Xue <leahxue@fb.com>
parents: 17340
diff changeset
   426
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   427
def collapse(repo, first, last, commitopts, skipprompt=False):
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   428
    """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
   429
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   430
    Expected commit options are:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   431
        - message
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   432
        - date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   433
        - username
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17666
diff changeset
   434
    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
   435
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   436
    This function works in memory."""
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   437
    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
   438
    if not ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   439
        return None
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   440
    for c in ctxs:
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   441
        if not c.mutable():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   442
            raise error.Abort(
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   443
                _("cannot fold into public change %s") % node.short(c.node()))
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   444
    base = first.parents()[0]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   445
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   446
    # 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
   447
    # collect all files which might be affected
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   448
    files = set()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   449
    for ctx in ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   450
        files.update(ctx.files())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   451
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   452
    # 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
   453
    copied = copies.pathcopies(base, last)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   454
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   455
    # 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
   456
    def samefile(f):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   457
        if f in last.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   458
            a = last.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   459
            if f in base.manifest():
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   460
                b = base.filectx(f)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   461
                return (a.data() == b.data()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   462
                        and a.flags() == b.flags())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   463
            else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   464
                return False
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   465
        else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   466
            return f not in base.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   467
    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
   468
    # 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
   469
    headmf = last.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   470
    def filectxfn(repo, ctx, path):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   471
        if path in headmf:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   472
            fctx = last[path]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   473
            flags = fctx.flags()
21689
503bb3af70fe memfilectx: call super.__init__ instead of duplicating code
Sean Farley <sean.michael.farley@gmail.com>
parents: 21409
diff changeset
   474
            mctx = context.memfilectx(repo,
503bb3af70fe memfilectx: call super.__init__ instead of duplicating code
Sean Farley <sean.michael.farley@gmail.com>
parents: 21409
diff changeset
   475
                                      fctx.path(), fctx.data(),
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   476
                                      islink='l' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   477
                                      isexec='x' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   478
                                      copied=copied.get(path))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   479
            return mctx
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 22280
diff changeset
   480
        return None
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   481
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   482
    if commitopts.get('message'):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   483
        message = commitopts['message']
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   484
    else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   485
        message = first.description()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   486
    user = commitopts.get('user')
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   487
    date = commitopts.get('date')
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   488
    extra = commitopts.get('extra')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   489
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   490
    parents = (first.p1().node(), first.p2().node())
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   491
    editor = None
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   492
    if not skipprompt:
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   493
        editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   494
    new = context.memctx(repo,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   495
                         parents=parents,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   496
                         text=message,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   497
                         files=files,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   498
                         filectxfn=filectxfn,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   499
                         user=user,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   500
                         date=date,
21239
19d98da5c018 histedit: pass "editor" argument to "memctx.__init__()" for "collapse" command
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21233
diff changeset
   501
                         extra=extra,
22002
a44b7b6f3cd7 histedit: pass 'editform' argument to 'cmdutil.getcommiteditor'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21950
diff changeset
   502
                         editor=editor)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   503
    return repo.commitctx(new)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   504
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   505
class pick(histeditaction):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   506
    def run(self):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   507
        rulectx = self.repo[self.node]
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   508
        if rulectx.parents()[0].node() == self.state.parentctxnode:
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   509
            self.repo.ui.debug('node %s unchanged\n' % node.short(self.node))
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   510
            return rulectx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   511
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   512
        return super(pick, self).run()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   513
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   514
class edit(histeditaction):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   515
    def run(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   516
        repo = self.repo
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   517
        rulectx = repo[self.node]
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   518
        hg.update(repo, self.state.parentctxnode)
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   519
        applychanges(repo.ui, repo, rulectx, {})
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   520
        raise error.InterventionRequired(
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   521
            _('Make changes as needed, you may commit or record as needed '
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   522
              'now.\nWhen you are finished, run hg histedit --continue to '
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   523
              'resume.'))
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   524
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   525
    def commiteditor(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   526
        return cmdutil.getcommiteditor(edit=True, editform='histedit.edit')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   527
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   528
class fold(histeditaction):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   529
    def continuedirty(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   530
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   531
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   532
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   533
        commit = commitfuncfor(repo, rulectx)
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   534
        commit(text='fold-temp-revision %s' % node.short(self.node),
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   535
               user=rulectx.user(), date=rulectx.date(),
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   536
               extra=rulectx.extra())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   537
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   538
    def continueclean(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   539
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   540
        ctx = repo['.']
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   541
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   542
        parentctxnode = self.state.parentctxnode
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   543
        if ctx.node() == parentctxnode:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   544
            repo.ui.warn(_('%s: empty changeset\n') %
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   545
                              node.short(self.node))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   546
            return ctx, [(self.node, (parentctxnode,))]
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   547
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   548
        parentctx = repo[parentctxnode]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   549
        newcommits = set(c.node() for c in repo.set('(%d::. - %d)', parentctx,
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   550
                                                 parentctx))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   551
        if not newcommits:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   552
            repo.ui.warn(_('%s: cannot fold - working copy is not a '
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   553
                           'descendant of previous commit %s\n') %
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   554
                           (node.short(self.node), node.short(parentctxnode)))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   555
            return ctx, [(self.node, (ctx.node(),))]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   556
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   557
        middlecommits = newcommits.copy()
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   558
        middlecommits.discard(ctx.node())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   559
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   560
        return self.finishfold(repo.ui, repo, parentctx, rulectx, ctx.node(),
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   561
                               middlecommits)
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   562
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   563
    def skipprompt(self):
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   564
        """Returns true if the rule should skip the message editor.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   565
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   566
        For example, 'fold' wants to show an editor, but 'rollup'
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   567
        doesn't want to.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   568
        """
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   569
        return False
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   570
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   571
    def mergedescs(self):
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   572
        """Returns true if the rule should merge messages of multiple changes.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   573
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   574
        This exists mainly so that 'rollup' rules can be a subclass of
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   575
        'fold'.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   576
        """
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   577
        return True
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   578
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   579
    def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges):
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   580
        parent = ctx.parents()[0].node()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   581
        hg.update(repo, parent)
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   582
        ### prepare new commit data
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   583
        commitopts = {}
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   584
        commitopts['user'] = ctx.user()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   585
        # commit message
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   586
        if not self.mergedescs():
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   587
            newmessage = ctx.description()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   588
        else:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   589
            newmessage = '\n***\n'.join(
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   590
                [ctx.description()] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   591
                [repo[r].description() for r in internalchanges] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   592
                [oldctx.description()]) + '\n'
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   593
        commitopts['message'] = newmessage
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   594
        # date
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   595
        commitopts['date'] = max(ctx.date(), oldctx.date())
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   596
        extra = ctx.extra().copy()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   597
        # histedit_source
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   598
        # note: ctx is likely a temporary commit but that the best we can do
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   599
        #       here. This is sufficient to solve issue3681 anyway.
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   600
        extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex())
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   601
        commitopts['extra'] = extra
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   602
        phasebackup = repo.ui.backupconfig('phases', 'new-commit')
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   603
        try:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   604
            phasemin = max(ctx.phase(), oldctx.phase())
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   605
            repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit')
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   606
            n = collapse(repo, ctx, repo[newnode], commitopts,
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   607
                         skipprompt=self.skipprompt())
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   608
        finally:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   609
            repo.ui.restoreconfig(phasebackup)
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   610
        if n is None:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   611
            return ctx, []
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   612
        hg.update(repo, n)
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   613
        replacements = [(oldctx.node(), (newnode,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   614
                        (ctx.node(), (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   615
                        (newnode, (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   616
                       ]
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   617
        for ich in internalchanges:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   618
            replacements.append((ich, (n,)))
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   619
        return repo[n], replacements
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   620
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   621
class _multifold(fold):
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   622
    """fold subclass used for when multiple folds happen in a row
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   623
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   624
    We only want to fire the editor for the folded message once when
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   625
    (say) four changes are folded down into a single change. This is
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   626
    similar to rollup, but we should preserve both messages so that
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   627
    when the last fold operation runs we can show the user all the
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   628
    commit messages in their editor.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   629
    """
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   630
    def skipprompt(self):
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   631
        return True
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   632
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   633
class rollup(fold):
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   634
    def mergedescs(self):
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   635
        return False
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   636
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   637
    def skipprompt(self):
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   638
        return True
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   639
24768
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   640
class drop(histeditaction):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   641
    def run(self):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   642
        parentctx = self.repo[self.state.parentctxnode]
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   643
        return parentctx, [(self.node, tuple())]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   644
24769
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   645
class message(histeditaction):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   646
    def commiteditor(self):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   647
        return cmdutil.getcommiteditor(edit=True, editform='histedit.mess')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   648
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   649
def findoutgoing(ui, repo, remote=None, force=False, opts=None):
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   650
    """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
   651
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   652
    Used by initialization code"""
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   653
    if opts is None:
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   654
        opts = {}
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   655
    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
   656
    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
   657
    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
   658
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   659
    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
   660
    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
   661
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   662
    if revs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   663
        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
   664
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   665
    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
   666
    if not outgoing.missing:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   667
        raise error.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
   668
    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
   669
    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
   670
        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
   671
        hint = _('see "hg help histedit" for more detail')
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   672
        raise error.Abort(msg, hint=hint)
19841
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   673
    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
   674
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   675
actiontable = {'p': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   676
               'pick': pick,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   677
               'e': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   678
               'edit': edit,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   679
               'f': fold,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   680
               'fold': fold,
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   681
               '_multifold': _multifold,
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   682
               'r': rollup,
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   683
               'roll': rollup,
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   684
               'd': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   685
               'drop': drop,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   686
               'm': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   687
               'mess': message,
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   688
               }
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   689
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   690
@command('histedit',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   691
    [('', 'commands', '',
24232
f9e8739018d5 histedit: use better meta-variable names than VALUE in help text
Anton Shestakov <engored@ya.ru>
parents: 24231
diff changeset
   692
      _('read history edits from the specified file'), _('FILE')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   693
     ('c', 'continue', False, _('continue an edit already in progress')),
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   694
     ('', 'edit-plan', False, _('edit remaining actions list')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   695
     ('k', 'keep', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   696
      _("don't strip old nodes after edit is complete")),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   697
     ('', 'abort', False, _('abort an edit in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   698
     ('o', 'outgoing', False, _('changesets not found in destination')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   699
     ('f', 'force', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   700
      _('force outgoing even for unrelated repositories')),
24232
f9e8739018d5 histedit: use better meta-variable names than VALUE in help text
Anton Shestakov <engored@ya.ru>
parents: 24231
diff changeset
   701
     ('r', 'rev', [], _('first revision to be edited'), _('REV'))],
19622
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   702
     _("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
   703
def histedit(ui, repo, *freeargs, **opts):
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   704
    """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
   705
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   706
    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
   707
    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
   708
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
   709
    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
   710
    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
   711
    '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
   712
26096
b237a68bfea3 histedit: fix grammar for help for safety aborts
timeless@mozdev.org
parents: 26039
diff changeset
   713
    For safety, this command is also aborted if there are ambiguous
b237a68bfea3 histedit: fix grammar for help for safety aborts
timeless@mozdev.org
parents: 26039
diff changeset
   714
    outgoing revisions which may confuse users: for example, if there
b237a68bfea3 histedit: fix grammar for help for safety aborts
timeless@mozdev.org
parents: 26039
diff changeset
   715
    are multiple branches containing outgoing revisions.
19842
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   716
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   717
    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
   718
    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
   719
    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
   720
    selecting revisions.
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   721
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   722
    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
   723
    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
   724
    conflicts).
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   725
    """
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   726
    state = histeditstate(repo)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   727
    try:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   728
        state.wlock = repo.wlock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   729
        state.lock = repo.lock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   730
        _histedit(ui, repo, state, *freeargs, **opts)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   731
    finally:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   732
        release(state.lock, state.wlock)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
   733
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   734
def _histedit(ui, repo, state, *freeargs, **opts):
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   735
    # 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
   736
    # blanket if mq patches are applied somewhere
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   737
    mq = getattr(repo, 'mq', None)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   738
    if mq and mq.applied:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   739
        raise error.Abort(_('source has mq patches applied'))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   740
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
   741
    # 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
   742
    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
   743
    cont = opts.get('continue')
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   744
    editplan = opts.get('edit_plan')
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
   745
    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
   746
    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
   747
    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
   748
    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
   749
    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
   750
    if force and not outg:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   751
        raise error.Abort(_('--force only allowed with --outgoing'))
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
   752
    if cont:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
   753
        if any((outg, abort, revs, freeargs, rules, editplan)):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   754
            raise error.Abort(_('no arguments allowed with --continue'))
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
   755
        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
   756
    elif abort:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
   757
        if any((outg, revs, freeargs, rules, editplan)):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   758
            raise error.Abort(_('no arguments allowed with --abort'))
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
   759
        goal = 'abort'
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   760
    elif editplan:
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
   761
        if any((outg, revs, freeargs)):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   762
            raise error.Abort(_('only --commands argument allowed with '
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   763
                               '--edit-plan'))
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   764
        goal = 'edit-plan'
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
   765
    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
   766
        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   767
            raise error.Abort(_('history edit already in progress, try '
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
   768
                               '--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
   769
        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
   770
            if revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   771
                raise error.Abort(_('no revisions allowed with --outgoing'))
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
   772
            if len(freeargs) > 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   773
                raise error.Abort(
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
   774
                    _('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
   775
        else:
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   776
            revs.extend(freeargs)
24009
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
   777
            if len(revs) == 0:
25824
8e77e8338cae histedit: mark defaultrev option experimental
Matt Mackall <mpm@selenic.com>
parents: 25809
diff changeset
   778
                # experimental config: histedit.defaultrev
24009
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
   779
                histeditdefault = ui.config('histedit', 'defaultrev')
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
   780
                if histeditdefault:
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
   781
                    revs.append(histeditdefault)
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   782
            if len(revs) != 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   783
                raise error.Abort(
19621
11de0651d3b6 histedit: add description about basic histedit function to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19519
diff changeset
   784
                    _('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
   785
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   786
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   787
    replacements = []
25330
8594d0b3018e histedit: fix keep during --continue
Durham Goode <durham@fb.com>
parents: 24959
diff changeset
   788
    state.keep = opts.get('keep', False)
25808
425839c8ec79 histedit: minor refactoring of createmarkers check
Laurent Charignon <lcharignon@fb.com>
parents: 25660
diff changeset
   789
    supportsmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   790
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   791
    # rebuild state
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
   792
    if goal == 'continue':
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   793
        state.read()
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
   794
        state = bootstrapcontinue(ui, state, opts)
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   795
    elif goal == 'edit-plan':
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   796
        state.read()
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   797
        if not rules:
24920
b5eb01500696 histedit: fix --edit-plan
Durham Goode <durham@fb.com>
parents: 24869
diff changeset
   798
            comment = editcomment % (node.short(state.parentctxnode),
b5eb01500696 histedit: fix --edit-plan
Durham Goode <durham@fb.com>
parents: 24869
diff changeset
   799
                                     node.short(state.topmost))
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   800
            rules = ruleeditor(repo, ui, state.rules, comment)
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   801
        else:
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   802
            if rules == '-':
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   803
                f = sys.stdin
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   804
            else:
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   805
                f = open(rules)
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   806
            rules = f.read()
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   807
            f.close()
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   808
        rules = [l for l in (r.strip() for r in rules.splitlines())
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   809
                 if l and not l.startswith('#')]
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   810
        rules = verifyrules(rules, repo, [repo[c] for [_a, c] in state.rules])
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   811
        state.rules = rules
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   812
        state.write()
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   813
        return
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
   814
    elif goal == 'abort':
26584
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   815
        try:
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   816
            state.read()
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   817
            tmpnodes, leafs = newnodestoabort(state)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   818
            ui.debug('restore wc to old parent %s\n'
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   819
                    % node.short(state.topmost))
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   820
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   821
            # Recover our old commits if necessary
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   822
            if not state.topmost in repo and state.backupfile:
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   823
                backupfile = repo.join(state.backupfile)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   824
                f = hg.openpath(ui, backupfile)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   825
                gen = exchange.readbundle(ui, f, backupfile)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   826
                changegroup.addchangegroup(repo, gen, 'histedit',
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   827
                                        'bundle:' + backupfile)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   828
                os.remove(backupfile)
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   829
26584
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   830
            # check whether we should update away
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   831
            if repo.unfiltered().revs('parents() and (%n  or %ln::)',
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   832
                                    state.parentctxnode, leafs | tmpnodes):
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   833
                hg.clean(repo, state.topmost)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   834
            cleanupnode(ui, repo, 'created', tmpnodes)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   835
            cleanupnode(ui, repo, 'temp', leafs)
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   836
        except Exception:
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   837
            if state.inprogress():
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   838
                ui.warn(_('warning: encountered an exception during histedit '
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   839
                    '--abort; the repository may not have been completely '
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   840
                    'cleaned up\n'))
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   841
            raise
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   842
        finally:
e28102403d1b histedit: delete histedit statefile on any exception during abort
Christian Delahousse <cdelahousse@fb.com>
parents: 26583
diff changeset
   843
                state.clear()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   844
        return
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   845
    else:
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
   846
        cmdutil.checkunfinished(repo)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   847
        cmdutil.bailifchanged(repo)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   848
17665
b65533958b85 histedit: rename `tip` to `topmost`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17664
diff changeset
   849
        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
   850
        if outg:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   851
            if freeargs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   852
                remote = freeargs[0]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   853
            else:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   854
                remote = None
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   855
            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
   856
        else:
21950
af44c7a1e55e histedit: respect revsetalias entries (issue4311)
Augie Fackler <raf@durin42.com>
parents: 21858
diff changeset
   857
            rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
af44c7a1e55e histedit: respect revsetalias entries (issue4311)
Augie Fackler <raf@durin42.com>
parents: 21858
diff changeset
   858
            if len(rr) != 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   859
                raise error.Abort(_('The specified revisions must have '
20806
d66862b87ae6 histedit: select the lowest rev when looking for a root in a revset (bc)
David Soria Parra <davidsp@fb.com>
parents: 20790
diff changeset
   860
                    'exactly one common root'))
21950
af44c7a1e55e histedit: respect revsetalias entries (issue4311)
Augie Fackler <raf@durin42.com>
parents: 21858
diff changeset
   861
            root = rr[0].node()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   862
25330
8594d0b3018e histedit: fix keep during --continue
Durham Goode <durham@fb.com>
parents: 24959
diff changeset
   863
        revs = between(repo, root, topmost, state.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
   864
        if not revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   865
            raise error.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
   866
                             node.short(root))
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   867
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   868
        ctxs = [repo[r] for r in revs]
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   869
        if not rules:
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   870
            comment = editcomment % (node.short(root), node.short(topmost))
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
   871
            rules = ruleeditor(repo, ui, [['pick', c] for c in ctxs], comment)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   872
        else:
19018
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   873
            if rules == '-':
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   874
                f = sys.stdin
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   875
            else:
730614b9b352 histedit: allow "-" as a command file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19017
diff changeset
   876
                f = open(rules)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   877
            rules = f.read()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   878
            f.close()
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   879
        rules = [l for l in (r.strip() for r in rules.splitlines())
22280
7eef5a87ce3f histedit: use str.startswith to check for comments in action list
Mike Edgar <adgar@google.com>
parents: 22279
diff changeset
   880
                 if l and not l.startswith('#')]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   881
        rules = verifyrules(rules, repo, ctxs)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   882
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   883
        parentctxnode = repo[root].parents()[0].node()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   884
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   885
        state.parentctxnode = parentctxnode
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   886
        state.rules = rules
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   887
        state.topmost = topmost
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   888
        state.replacements = replacements
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   889
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   890
        # Create a backup so we can always abort completely.
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   891
        backupfile = None
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   892
        if not obsolete.isenabled(repo, obsolete.createmarkersopt):
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   893
            backupfile = repair._bundle(repo, [parentctxnode], [topmost], root,
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   894
                                        'histedit')
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   895
        state.backupfile = backupfile
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   896
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   897
    # preprocess rules so that we can hide inner folds from the user
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   898
    # and only show one editor
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   899
    rules = state.rules[:]
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   900
    for idx, ((action, ha), (nextact, unused)) in enumerate(
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   901
            zip(rules, rules[1:] + [(None, None)])):
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   902
        if action == 'fold' and nextact == 'fold':
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   903
            state.rules[idx] = '_multifold', ha
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   904
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   905
    while state.rules:
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   906
        state.write()
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   907
        action, ha = state.rules.pop(0)
24002
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
   908
        ui.debug('histedit: processing %s %s\n' % (action, ha[:12]))
24774
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
   909
        actobj = actiontable[action].fromrule(state, ha)
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
   910
        parentctx, replacement_ = actobj.run()
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   911
        state.parentctxnode = parentctx.node()
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   912
        state.replacements.extend(replacement_)
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
   913
    state.write()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   914
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   915
    hg.update(repo, state.parentctxnode)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   916
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
   917
    mapping, tmpnodes, created, ntm = processreplacement(state)
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
   918
    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
   919
        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
   920
            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
   921
                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
   922
            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
   923
                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
   924
                    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
   925
                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
   926
                    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
   927
                    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
   928
                        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
   929
25330
8594d0b3018e histedit: fix keep during --continue
Durham Goode <durham@fb.com>
parents: 24959
diff changeset
   930
    if not state.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
   931
        if mapping:
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
   932
            movebookmarks(ui, repo, mapping, state.topmost, ntm)
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
   933
            # TODO update mq state
25808
425839c8ec79 histedit: minor refactoring of createmarkers check
Laurent Charignon <lcharignon@fb.com>
parents: 25660
diff changeset
   934
        if supportsmarkers:
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   935
            markers = []
17771
dcfa526b180b histedit: create obsolescence markers in deterministic order
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17769
diff changeset
   936
            # 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
   937
            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
   938
                succs = mapping[prec]
17759
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   939
                markers.append((repo[prec],
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   940
                                tuple(repo[s] for s in succs)))
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   941
            if markers:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   942
                obsolete.createmarkers(repo, markers)
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   943
        else:
9c7497cd39fd histedit: add obsolete support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17758
diff changeset
   944
            cleanupnode(ui, repo, 'replaced', mapping)
25894
54f9561088c7 histedit: backout ebb5bb9bc32e
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25824
diff changeset
   945
54f9561088c7 histedit: backout ebb5bb9bc32e
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25824
diff changeset
   946
    cleanupnode(ui, repo, 'temp', tmpnodes)
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
   947
    state.clear()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   948
    if os.path.exists(repo.sjoin('undo')):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   949
        os.unlink(repo.sjoin('undo'))
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   950
24774
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
   951
def bootstrapcontinue(ui, state, opts):
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
   952
    repo = state.repo
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   953
    if state.rules:
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   954
        action, currentnode = state.rules.pop(0)
20648
0838bd2f600f histedit: move logic for finding child nodes to new function
Olle Lundberg <geek@nerd.sh>
parents: 20647
diff changeset
   955
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   956
        actobj = actiontable[action].fromrule(state, currentnode)
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   957
24774
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
   958
        s = repo.status()
24766
cfb8f5e3ca49 histedit: integrate action class into flow
Durham Goode <durham@fb.com>
parents: 24765
diff changeset
   959
        if s.modified or s.added or s.removed or s.deleted:
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   960
            actobj.continuedirty()
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   961
            s = repo.status()
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   962
            if s.modified or s.added or s.removed or s.deleted:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   963
                raise error.Abort(_("working copy still dirty"))
24766
cfb8f5e3ca49 histedit: integrate action class into flow
Durham Goode <durham@fb.com>
parents: 24765
diff changeset
   964
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   965
        parentctx, replacements = actobj.continueclean()
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
   966
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   967
        state.parentctxnode = parentctx.node()
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
   968
        state.replacements.extend(replacements)
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
   969
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
   970
    return state
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
   971
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
   972
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
   973
    """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
   974
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
   975
    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
   976
    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
   977
    if ctxs and not keep:
22952
8792ac090e3b obsolete: add allowunstable option
Durham Goode <durham@fb.com>
parents: 22951
diff changeset
   978
        if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and
18270
48deb483a8f8 clfilter: drop unnecessary explicit filtering on histedit
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18165
diff changeset
   979
            repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   980
            raise error.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
   981
        if repo.revs('(%ld) and merge()', ctxs):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   982
            raise error.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
   983
        root = ctxs[0] # list is already sorted by repo.set
22416
810d37485e85 histedit: check mutability of contexts correctly
Augie Fackler <raf@durin42.com>
parents: 22405
diff changeset
   984
        if not root.mutable():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
   985
            raise error.Abort(_('cannot edit public changeset: %s') % root,
25412
443d4635e630 phases: add `hg help phases` hint to failures to edit public commits
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25411
diff changeset
   986
                             hint=_('see "hg help phases" for details'))
17765
ef7760f0be87 histedit: rename `revs` in `ctxs` inside the `between` function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17762
diff changeset
   987
    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
   988
24141
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   989
def makedesc(repo, action, rev):
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   990
    """build a initial action line for a ctx
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   991
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   992
    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
   993
24141
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   994
      <action> <hash> <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
   995
    """
24141
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   996
    ctx = repo[rev]
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
   997
    summary = ''
24141
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   998
    if ctx.description():
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
   999
        summary = ctx.description().splitlines()[0]
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
  1000
    line = '%s %s %d %s' % (action, ctx, ctx.rev(), summary)
21858
50fd3a36d166 histedit: use 'util.ellipsis' to trim description of each changesets
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21689
diff changeset
  1001
    # trim to 80 columns so it's not stupidly wide in my editor
24199
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
  1002
    maxlen = repo.ui.configint('histedit', 'linelen', default=80)
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
  1003
    maxlen = max(maxlen, 22) # avoid truncating hash
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
  1004
    return util.ellipsis(line, maxlen)
17643
64e0f0cfb569 histedit: move makedesc function near other rules related function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17642
diff changeset
  1005
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1006
def ruleeditor(repo, ui, rules, editcomment=""):
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1007
    """open an editor to edit rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1008
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1009
    rules are in the format [ [act, ctx], ...] like in state.rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1010
    """
24141
671da7d34804 histedit: generalize makedesc
Mateusz Kwapich <mitrandir@fb.com>
parents: 24140
diff changeset
  1011
    rules = '\n'.join([makedesc(repo, act, rev) for [act, rev] in rules])
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1012
    rules += '\n\n'
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1013
    rules += editcomment
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1014
    rules = ui.edit(rules, ui.username())
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1015
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1016
    # Save edit rules in .hg/histedit-last-edit.txt in case
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1017
    # the user needs to ask for help after something
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1018
    # surprising happens.
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1019
    f = open(repo.join('histedit-last-edit.txt'), 'w')
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1020
    f.write(rules)
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1021
    f.close()
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1022
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1023
    return rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1024
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1025
def verifyrules(rules, repo, ctxs):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1026
    """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
  1027
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1028
    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
  1029
    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
  1030
    """
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1031
    parsed = []
24002
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
  1032
    expected = set(c.hex() for c in ctxs)
19047
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
  1033
    seen = set()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1034
    for r in rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1035
        if ' ' not in r:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1036
            raise error.Abort(_('malformed line "%s"') % r)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1037
        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
  1038
        ha = rest.strip().split(' ', 1)[0]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1039
        try:
24002
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
  1040
            ha = repo[ha].hex()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1041
        except error.RepoError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1042
            raise error.Abort(_('unknown changeset %s listed') % ha[:12])
19046
36adbbe960ca histedit: track short hash instead of changectx object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19045
diff changeset
  1043
        if ha not in expected:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1044
            raise error.Abort(
19045
080b801c34f1 histedit: ensure rules return short hex at all time
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19039
diff changeset
  1045
                _('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
  1046
        if ha in seen:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1047
            raise error.Abort(_('duplicated command for changeset %s') %
24002
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
  1048
                    ha[:12])
19047
81de87f8b480 histedit: protect against duplicated entries
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19046
diff changeset
  1049
        seen.add(ha)
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
  1050
        if action not in actiontable or action.startswith('_'):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1051
            raise error.Abort(_('unknown action "%s"') % action)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1052
        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
  1053
    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
  1054
    if missing:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1055
        raise error.Abort(_('missing rules for changeset %s') %
24002
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
  1056
                missing[0][:12],
96d130697f07 histedit: store full node hash in rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 22987
diff changeset
  1057
                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
  1058
    return parsed
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
  1059
25898
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1060
def newnodestoabort(state):
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1061
    """process the list of replacements to return
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1062
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1063
    1) the list of final node
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1064
    2) the list of temporary node
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1065
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1066
    This meant to be used on abort as less data are required in this case.
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1067
    """
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1068
    replacements = state.replacements
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1069
    allsuccs = set()
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1070
    replaced = set()
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1071
    for rep in replacements:
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1072
        allsuccs.update(rep[1])
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1073
        replaced.add(rep[0])
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1074
    newnodes = allsuccs - replaced
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1075
    tmpnodes = allsuccs & replaced
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1076
    return newnodes, tmpnodes
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1077
4dcc9b5d786a histedit: extract a simpler function to process replacement on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25894
diff changeset
  1078
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1079
def processreplacement(state):
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
  1080
    """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
  1081
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  1082
    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
  1083
    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
  1084
    3) the list of new commit created by histedit"""
22981
aa1ad9594dde histedit: pass state to processreplacement
David Soria Parra <davidsp@fb.com>
parents: 22980
diff changeset
  1085
    replacements = state.replacements
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
  1086
    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
  1087
    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
  1088
    fullmapping = {}
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1089
    # initialize basic set
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1090
    # fullmapping records all operations recorded in replacement
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
  1091
    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
  1092
        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
  1093
        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
  1094
        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
  1095
    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
  1096
    tmpnodes = allsuccs & replaced
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1097
    # Reduce content fullmapping into direct relation between original 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
  1098
    # 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
  1099
    # 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
  1100
    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
  1101
    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
  1102
    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
  1103
        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
  1104
            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
  1105
            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
  1106
                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
  1107
                    # 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
  1108
                    # 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
  1109
                    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
  1110
                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
  1111
                    # 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
  1112
                    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
  1113
                    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
  1114
            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
  1115
                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
  1116
                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
  1117
    # 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
  1118
    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
  1119
        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
  1120
    # 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
  1121
    # turn `final` into list (topologically sorted)
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1122
    nm = state.repo.changelog.nodemap
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
  1123
    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
  1124
        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
  1125
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
  1126
    # 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
  1127
    if new:
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1128
        newtopmost = sorted(new, key=state.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
  1129
    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
  1130
        # 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
  1131
        # 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
  1132
        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
  1133
    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
  1134
        # every body died. The newtopmost is the parent of the root.
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1135
        r = state.repo.changelog.rev
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1136
        newtopmost = state.repo[sorted(final, key=r)[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
  1137
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  1138
    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
  1139
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
  1140
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
  1141
    """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
  1142
    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
  1143
        # 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
  1144
        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
  1145
    moves = []
18370
c605e12dd622 histedit: process bookmarks in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18324
diff changeset
  1146
    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
  1147
        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
  1148
            # 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
  1149
            #
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  1150
            # 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
  1151
            # 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
  1152
            # 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
  1153
            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
  1154
            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
  1155
        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
  1156
        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
  1157
        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
  1158
            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
  1159
        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
  1160
            # 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
  1161
            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
  1162
            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
  1163
            # 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
  1164
        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
  1165
    if moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
  1166
        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
  1167
        for mark, new in moves:
17922
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
  1168
            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
  1169
            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
  1170
                    % (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
  1171
            marks[mark] = new
7f5dab94e48c bookmarks: introduce a bmstore to manage bookmark persistence
Augie Fackler <raf@durin42.com>
parents: 17771
diff changeset
  1172
        marks.write()
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1173
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1174
def cleanupnode(ui, repo, name, nodes):
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1175
    """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
  1176
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1177
    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
  1178
    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
  1179
             (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
  1180
    lock = None
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1181
    try:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1182
        lock = repo.lock()
25906
5d0e1e95e30f histedit: make cleanupnode more robust
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25898
diff changeset
  1183
        # do not let filtering get in the way of the cleanse
26203
b764f3c61bc7 histedit: fix grammar in cleanupnode comment
timeless@mozdev.org
parents: 26171
diff changeset
  1184
        # we should probably get rid of obsolescence marker created during the
25906
5d0e1e95e30f histedit: make cleanupnode more robust
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25898
diff changeset
  1185
        # histedit, but we currently do not have such information.
5d0e1e95e30f histedit: make cleanupnode more robust
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25898
diff changeset
  1186
        repo = repo.unfiltered()
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
  1187
        # Find all nodes that need to be stripped
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
  1188
        # (we use %lr instead of %ln to silently ignore unknown items)
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1189
        nm = repo.changelog.nodemap
22873
9fe8e1e80841 histedit: stabilise the order nodes that are stripped
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22416
diff changeset
  1190
        nodes = sorted(n for n in nodes if n in nm)
17664
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1191
        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
  1192
        for c in roots:
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1193
            # 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
  1194
            # 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
  1195
            # This would reduce bundle overhead
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1196
            repair.strip(ui, repo, c)
4eb13b619785 histedit: factorise node stripping logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17663
diff changeset
  1197
    finally:
20647
70d02abff434 histedit: clean up lock imports
Olle Lundberg <geek@nerd.sh>
parents: 20511
diff changeset
  1198
        release(lock)
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1199
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1200
def stripwrapper(orig, ui, repo, nodelist, *args, **kwargs):
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1201
    if isinstance(nodelist, str):
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1202
        nodelist = [nodelist]
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1203
    if os.path.exists(os.path.join(repo.path, 'histedit-state')):
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1204
        state = histeditstate(repo)
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1205
        state.read()
24626
e767f5aba810 histedit: fix preventing strips during histedit
Durham Goode <durham@fb.com>
parents: 24267
diff changeset
  1206
        histedit_nodes = set([repo[rulehash].node() for (action, rulehash)
e767f5aba810 histedit: fix preventing strips during histedit
Durham Goode <durham@fb.com>
parents: 24267
diff changeset
  1207
                             in state.rules if rulehash in repo])
e767f5aba810 histedit: fix preventing strips during histedit
Durham Goode <durham@fb.com>
parents: 24267
diff changeset
  1208
        strip_nodes = set([repo[n].node() for n in nodelist])
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1209
        common_nodes = histedit_nodes & strip_nodes
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1210
        if common_nodes:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1211
            raise error.Abort(_("histedit in progress, can't strip %s")
24196
c3d13202144d histedit: fix style of new error message
Matt Mackall <mpm@selenic.com>
parents: 24142
diff changeset
  1212
                             % ', '.join(node.short(x) for x in common_nodes))
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1213
    return orig(ui, repo, nodelist, *args, **kwargs)
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1214
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1215
extensions.wrapfunction(repair, 'strip', stripwrapper)
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1216
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1217
def summaryhook(ui, repo):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1218
    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
  1219
        return
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1220
    state = histeditstate(repo)
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1221
    state.read()
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
  1222
    if state.rules:
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1223
        # i18n: column positioning for "hg summary"
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1224
        ui.write(_('hist:   %s (histedit --continue)\n') %
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1225
                 (ui.label(_('%d remaining'), 'histedit.remaining') %
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
  1226
                  len(state.rules)))
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1227
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1228
def extsetup(ui):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1229
    cmdutil.summaryhooks.add('histedit', summaryhook)
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  1230
    cmdutil.unfinishedstates.append(
19496
607191a45f8c checkunfinished: accommodate histedit quirk
Matt Mackall <mpm@selenic.com>
parents: 19479
diff changeset
  1231
        ['histedit-state', False, True, _('histedit in progress'),
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  1232
         _("use 'hg histedit --continue' or 'hg histedit --abort'")])