hgext/histedit.py
author Matt Harbison <matt_harbison@yahoo.com>
Sun, 16 Dec 2018 17:36:51 -0500
changeset 40975 2465e0b27a0d
parent 40652 291080871f50
child 41103 86f0ed7ac688
permissions -rw-r--r--
run-tests: alias hg to hg.exe on Windows To enable legacy stdio mode on Windows, hg.exe needs to be updated. But before that, we actually have to use it when running the tests. I *think* what was happening before was when MSYS invoked `hg`, it looked at the shbang line and ran python.exe found there. The test harness must be updating $PATH to include the python used to launch it, and therefore it ran py3. As a side note, this also fixed `py -3 run-tests.py` (without --local), which complained about the space in the shbang line before this. This should also help in WSL, because the explicit '.exe' is needed to invoke a Windows app instead of invoking the Linux app. I have no idea why this change capitalizes Lib in the tests, as it was previously lowercase for both py2 and py3.
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
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
    39
 #  r, roll = like fold, but discard this commit's description and date
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
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
    42
 #  b, base = checkout changeset and apply further changesets from there
17131
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
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    45
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
    46
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
    47
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
    48
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
    49
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    50
 pick 030b686bedc4 Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    51
 pick c561b4e977df Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    52
 fold 7c2fd3b9020c Add delta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    53
18322
e819c12a8bd0 histedit: correct changeset IDs in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17771
diff changeset
    54
 # Edit history between c561b4e977df and 7c2fd3b9020c
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    55
 #
20503
23dc77874191 histedit: clarify description of fold command
Adrian Zgorzałek <adek@fb.com>
parents: 20071
diff changeset
    56
 # 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
    57
 #
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    58
 # Commands:
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    59
 #  p, pick = use commit
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    60
 #  e, edit = use commit, but stop for amending
20511
5840da876235 histedit: shorten new fold message
Matt Mackall <mpm@selenic.com>
parents: 20503
diff changeset
    61
 #  f, fold = use commit, but combine it with the one above
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
    62
 #  r, roll = like fold, but discard this commit's description and date
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    63
 #  d, drop = remove commit from history
26100
5706d130ec16 histedit: improve discoverability of edit commit message
timeless@mozdev.org
parents: 26098
diff changeset
    64
 #  m, mess = edit commit message without changing commit content
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
    65
 #  b, base = checkout changeset and apply further changesets from there
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    66
 #
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    67
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    68
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
    69
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
    70
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
    71
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    72
 Add beta
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    73
 ***
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    74
 Add delta
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
    75
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
    76
Edit the commit message to your liking, then close the editor. The date used
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
    77
for the commit will be the later of the two commits' dates. For this example,
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
    78
let's assume that the commit message was changed to ``Add beta and delta.``
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
    79
After histedit has run and had a chance to remove any old or temporary
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
    80
revisions it needed, the history looks like this::
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    81
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    82
 @  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
    83
 |    Add beta and delta.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    84
 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    85
 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
    86
 |    Add gamma
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    87
 |
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    88
 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
    89
      Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    90
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    91
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
    92
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
    93
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
    94
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
    95
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
    96
revisions by passing the ``--keep`` flag.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    97
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
    98
The ``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
    99
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
   100
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
   101
uncommitted changes will be committed as well. When done, run ``hg
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   102
histedit --continue`` to finish this step. If there are uncommitted
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   103
changes, you'll be prompted for a new commit message, but the default
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   104
commit message will be the original message for the ``edit`` ed
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   105
revision, and the date of the original commit will be preserved.
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   106
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   107
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
   108
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
   109
``edit`` immediately followed by `hg histedit --continue``.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   110
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   111
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
   112
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
   113
``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
   114
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
   115
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
   116
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
   117
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
   118
history.
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   119
18323
7648b87e76db histedit: correct the number of added revisions in online help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18322
diff changeset
   120
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
   121
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
   122
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   123
   @  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
   124
   |    Add theta
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  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
   127
   |    Add eta
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  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
   130
   |    Add zeta
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  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
   133
   |    Add epsilon
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  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
   136
   |    Add beta and delta.
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  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
   139
   |    Add gamma
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
   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
   142
        Add alpha
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   143
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   144
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
   145
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
   146
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
   147
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
   148
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   149
Config
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   150
------
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   151
24199
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
   152
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
   153
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
   154
configuration file::
24199
4047982904f8 histedit: add a config allowing changing histedit rule line length limit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24196
diff changeset
   155
24869
95a67d687903 histedit: fix reST syntax problem of example code in help document
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24831
diff changeset
   156
  [histedit]
95a67d687903 histedit: fix reST syntax problem of example code in help document
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24831
diff changeset
   157
  linelen = 120      # truncate rule lines at 120 characters
27262
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   158
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   159
``hg histedit`` attempts to automatically choose an appropriate base
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   160
revision to use. To change which base revision is used, define a
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   161
revset in your configuration file::
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   162
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   163
  [histedit]
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   164
  defaultrev = only(.) & draft()
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   165
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   166
By default each edited revision needs to be present in histedit commands.
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   167
To remove revision you need to use ``drop`` operation. You can configure
27957
c54f017fcd52 doc: prevent literal text block from being treated as non-literal one
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27956
diff changeset
   168
the drop to be implicit for missing commits by adding::
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   169
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   170
  [histedit]
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   171
  dropmissing = True
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
   172
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   173
By default, histedit will close the transaction after each action. For
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   174
performance purposes, you can configure histedit to use a single transaction
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   175
across the entire histedit. WARNING: This setting introduces a significant risk
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   176
of losing the work you've done in a histedit if the histedit aborts
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   177
unexpectedly::
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   178
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   179
  [histedit]
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   180
  singletransaction = True
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
   181
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   182
"""
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   183
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   184
from __future__ import absolute_import
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   185
40652
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   186
# chistedit dependencies that are not available everywhere
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   187
try:
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   188
    import fcntl
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   189
    import termios
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   190
except ImportError:
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   191
    fcntl = None
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   192
    termios = None
291080871f50 histedit: conditionalize the imports of 'fcntl' and 'termios'
Matt Harbison <matt_harbison@yahoo.com>
parents: 40602
diff changeset
   193
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   194
import functools
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   195
import os
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   196
import struct
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 29126
diff changeset
   197
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 29126
diff changeset
   198
from mercurial.i18n import _
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   199
from mercurial import (
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   200
    bundle2,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   201
    cmdutil,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   202
    context,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   203
    copies,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   204
    destutil,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   205
    discovery,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   206
    error,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   207
    exchange,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   208
    extensions,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   209
    hg,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   210
    lock,
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   211
    logcmdutil,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   212
    merge as mergemod,
32057
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
   213
    mergeutil,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   214
    node,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   215
    obsolete,
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
   216
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32327
diff changeset
   217
    registrar,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   218
    repair,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   219
    scmutil,
38506
18f348e035fb histedit: add a stateobj variable to histeditstate class
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38505
diff changeset
   220
    state as statemod,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   221
    util,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   222
)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37016
diff changeset
   223
from mercurial.utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37016
diff changeset
   224
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37016
diff changeset
   225
)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   226
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29214
diff changeset
   227
pickle = util.pickle
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   228
release = lock.release
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   229
cmdtable = {}
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32327
diff changeset
   230
command = registrar.command(cmdtable)
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   231
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   232
configtable = {}
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   233
configitem = registrar.configitem(configtable)
34474
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   234
configitem('experimental', 'histedit.autoverb',
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   235
    default=False,
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   236
)
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   237
configitem('histedit', 'defaultrev',
37003
2987726085c6 histedit: use the new stack definition for histedit
Boris Feld <boris.feld@octobus.net>
parents: 36413
diff changeset
   238
    default=None,
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   239
)
34471
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   240
configitem('histedit', 'dropmissing',
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   241
    default=False,
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   242
)
34472
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   243
configitem('histedit', 'linelen',
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   244
    default=80,
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   245
)
34473
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   246
configitem('histedit', 'singletransaction',
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   247
    default=False,
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   248
)
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   249
configitem('ui', 'interface.histedit',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   250
    default=None,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   251
)
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   252
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29820
diff changeset
   253
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 25149
diff changeset
   254
# 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
   255
# 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
   256
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29820
diff changeset
   257
testedwith = 'ships-with-hg-core'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   258
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   259
actiontable = {}
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   260
primaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   261
secondaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   262
tertiaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   263
internalactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   264
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   265
def geteditcomment(ui, first, last):
27673
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   266
    """ construct the editor comment
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   267
    The comment includes::
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   268
     - an intro
27674
78d86664e3a2 histedit: prefer edit commit, edit message, use commit
timeless <timeless@mozdev.org>
parents: 27673
diff changeset
   269
     - sorted primary commands
78d86664e3a2 histedit: prefer edit commit, edit message, use commit
timeless <timeless@mozdev.org>
parents: 27673
diff changeset
   270
     - sorted short commands
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   271
     - sorted long commands
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   272
     - additional hints
27673
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   273
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   274
    Commands are only included once.
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   275
    """
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   276
    intro = _("""Edit history between %s and %s
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   277
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   278
Commits are listed from least to most recent
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   279
28396
5490b04e6132 histedit: adds hint how to reorder changesets at editor (issue3766)
liscju <piotr.listkiewicz@gmail.com>
parents: 28340
diff changeset
   280
You can reorder changesets by reordering the lines
5490b04e6132 histedit: adds hint how to reorder changesets at editor (issue3766)
liscju <piotr.listkiewicz@gmail.com>
parents: 28340
diff changeset
   281
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   282
Commands:
17315
f320d7ed912f histedit: make comment part of the file describing rules as translatable
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17285
diff changeset
   283
""")
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   284
    actions = []
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   285
    def addverb(v):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   286
        a = actiontable[v]
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   287
        lines = a.message.split("\n")
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   288
        if len(a.verbs):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   289
            v = ', '.join(sorted(a.verbs, key=lambda v: len(v)))
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   290
        actions.append(" %s = %s" % (v, lines[0]))
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   291
        actions.extend(['  %s' for l in lines[1:]])
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   292
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   293
    for v in (
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   294
         sorted(primaryactions) +
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   295
         sorted(secondaryactions) +
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   296
         sorted(tertiaryactions)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   297
        ):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   298
        addverb(v)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   299
    actions.append('')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   300
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   301
    hints = []
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   302
    if ui.configbool('histedit', 'dropmissing'):
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   303
        hints.append("Deleting a changeset from the list "
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   304
                     "will DISCARD it from the edited history!")
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   305
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   306
    lines = (intro % (first, last)).split('\n') + actions + hints
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   307
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   308
    return ''.join(['# %s\n' % l if l else '#\n' for l in lines])
27673
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   309
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   310
class histeditstate(object):
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   311
    def __init__(self, repo, parentctxnode=None, actions=None, keep=None,
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   312
            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
   313
        self.repo = repo
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   314
        self.actions = actions
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   315
        self.keep = keep
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   316
        self.topmost = topmost
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   317
        self.parentctxnode = parentctxnode
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   318
        self.lock = lock
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   319
        self.wlock = wlock
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   320
        self.backupfile = None
38506
18f348e035fb histedit: add a stateobj variable to histeditstate class
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38505
diff changeset
   321
        self.stateobj = statemod.cmdstate(repo, 'histedit-state')
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   322
        if replacements is None:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   323
            self.replacements = []
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   324
        else:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   325
            self.replacements = replacements
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   326
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   327
    def read(self):
22986
7b93b49286d0 histedit: update docstring on histeditstate.read()
Augie Fackler <raf@durin42.com>
parents: 22985
diff changeset
   328
        """Load histedit state from disk and set fields appropriately."""
38507
03e7ec8180f0 histedit: use self.stateobj to check whether interrupted histedit exists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38506
diff changeset
   329
        if not self.stateobj.exists():
28123
6c1b7f80f90f histedit: suggest the correct tool to continue (not histedit)
timeless <timeless@mozdev.org>
parents: 28077
diff changeset
   330
            cmdutil.wrongtooltocontinue(self.repo, _('histedit'))
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   331
38507
03e7ec8180f0 histedit: use self.stateobj to check whether interrupted histedit exists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38506
diff changeset
   332
        data = self._read()
38505
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   333
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   334
        self.parentctxnode = data['parentctxnode']
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   335
        actions = parserules(data['rules'], self)
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   336
        self.actions = actions
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   337
        self.keep = data['keep']
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   338
        self.topmost = data['topmost']
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   339
        self.replacements = data['replacements']
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   340
        self.backupfile = data['backupfile']
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   341
38507
03e7ec8180f0 histedit: use self.stateobj to check whether interrupted histedit exists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38506
diff changeset
   342
    def _read(self):
03e7ec8180f0 histedit: use self.stateobj to check whether interrupted histedit exists
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38506
diff changeset
   343
        fp = self.repo.vfs.read('histedit-state')
38505
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   344
        if fp.startswith('v1\n'):
27527
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   345
            data = self._load()
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   346
            parentctxnode, rules, keep, topmost, replacements, backupfile = data
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   347
        else:
38505
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   348
            data = pickle.loads(fp)
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   349
            parentctxnode, rules, keep, topmost, replacements = data
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   350
            backupfile = None
38505
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   351
        rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules])
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   352
38505
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   353
        return {'parentctxnode': parentctxnode, "rules": rules, "keep": keep,
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   354
                "topmost": topmost, "replacements": replacements,
c6a2ce82e60b histedit: factor out logic of processing state data in separate fn
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38504
diff changeset
   355
                "backupfile": backupfile}
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   356
31511
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   357
    def write(self, tr=None):
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   358
        if tr:
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   359
            tr.addfilegenerator('histedit-state', ('histedit-state',),
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   360
                                self._write, location='plain')
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   361
        else:
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   362
            with self.repo.vfs("histedit-state", "w") as f:
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   363
                self._write(f)
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   364
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   365
    def _write(self, fp):
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   366
        fp.write('v1\n')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   367
        fp.write('%s\n' % node.hex(self.parentctxnode))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   368
        fp.write('%s\n' % node.hex(self.topmost))
36167
73621823a1ac histedit: convert bool to bytestring manually
Augie Fackler <augie@google.com>
parents: 35490
diff changeset
   369
        fp.write('%s\n' % ('True' if self.keep else 'False'))
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   370
        fp.write('%d\n' % len(self.actions))
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   371
        for action in self.actions:
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   372
            fp.write('%s\n' % action.tostate())
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   373
        fp.write('%d\n' % len(self.replacements))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   374
        for replacement in self.replacements:
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   375
            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
   376
                for r in replacement[1])))
24958
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   377
        backupfile = self.backupfile
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   378
        if not backupfile:
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   379
            backupfile = ''
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   380
        fp.write('%s\n' % backupfile)
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   381
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   382
    def _load(self):
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   383
        fp = self.repo.vfs('histedit-state', 'r')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   384
        lines = [l[:-1] for l in fp.readlines()]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   385
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   386
        index = 0
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   387
        lines[index] # version number
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   388
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   389
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   390
        parentctxnode = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   391
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   392
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   393
        topmost = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   394
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   395
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   396
        keep = lines[index] == 'True'
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   397
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   398
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   399
        # Rules
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   400
        rules = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   401
        rulelen = int(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   402
        index += 1
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38738
diff changeset
   403
        for i in pycompat.xrange(rulelen):
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   404
            ruleaction = lines[index]
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   405
            index += 1
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   406
            rule = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   407
            index += 1
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   408
            rules.append((ruleaction, rule))
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   409
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   410
        # Replacements
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   411
        replacements = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   412
        replacementlen = int(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   413
        index += 1
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38738
diff changeset
   414
        for i in pycompat.xrange(replacementlen):
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   415
            replacement = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   416
            original = node.bin(replacement[:40])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   417
            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
   418
                    range(40, len(replacement), 40)]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   419
            replacements.append((original, succ))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   420
            index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   421
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   422
        backupfile = lines[index]
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   423
        index += 1
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   424
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   425
        fp.close()
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   426
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   427
        return parentctxnode, rules, keep, topmost, replacements, backupfile
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   428
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
   429
    def clear(self):
26583
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   430
        if self.inprogress():
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   431
            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
   432
26582
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   433
    def inprogress(self):
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   434
        return self.repo.vfs.exists('histedit-state')
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   435
27200
62b9a87a365e histedit: add actions property to histedit state
Mateusz Kwapich <mitrandir@fb.com>
parents: 27171
diff changeset
   436
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   437
class histeditaction(object):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   438
    def __init__(self, state, node):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   439
        self.state = state
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   440
        self.repo = state.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   441
        self.node = node
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   442
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   443
    @classmethod
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   444
    def fromrule(cls, state, rule):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   445
        """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
   446
        """
37106
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   447
        ruleid = rule.strip().split(' ', 1)[0]
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   448
        # ruleid can be anything from rev numbers, hashes, "bookmarks" etc
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   449
        # Check for validation of rule ids and get the rulehash
27547
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   450
        try:
37106
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   451
            rev = node.bin(ruleid)
36238
f574cc00831a node: make bin() be a wrapper instead of just an alias
Augie Fackler <augie@google.com>
parents: 36175
diff changeset
   452
        except TypeError:
37106
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   453
            try:
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   454
                _ctx = scmutil.revsingle(state.repo, ruleid)
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   455
                rulehash = _ctx.hex()
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   456
                rev = node.bin(rulehash)
3d3cff1f6bde histedit: make histedit's commands accept revsets (issue5746)
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37084
diff changeset
   457
            except error.RepoLookupError:
37268
a53b87e20132 histedit: make errror message translatable
Sangeet Kumar Mishra <mail2sangeetmishra@gmail.com>
parents: 37261
diff changeset
   458
                raise error.ParseError(_("invalid changeset %s") % ruleid)
27547
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   459
        return cls(state, rev)
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   460
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
   461
    def verify(self, prev, expected, seen):
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   462
        """ Verifies semantic correctness of the rule"""
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   463
        repo = self.repo
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   464
        ha = node.hex(self.node)
37678
5f8f013e7d52 scmutil: rename resolvepartialhexnodeid() to resolvehexnodeidprefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37506
diff changeset
   465
        self.node = scmutil.resolvehexnodeidprefix(repo, ha)
37506
c4131138eadb histedit: look up partial nodeid as partial nodeid
Martin von Zweigbergk <martinvonz@google.com>
parents: 37505
diff changeset
   466
        if self.node is None:
c4131138eadb histedit: look up partial nodeid as partial nodeid
Martin von Zweigbergk <martinvonz@google.com>
parents: 37505
diff changeset
   467
            raise error.ParseError(_('unknown changeset %s listed') % ha[:12])
37505
966061b8826d histedit: drop unnecessary check for "self.node is not None"
Martin von Zweigbergk <martinvonz@google.com>
parents: 37314
diff changeset
   468
        self._verifynodeconstraints(prev, expected, seen)
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
   469
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   470
    def _verifynodeconstraints(self, prev, expected, seen):
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   471
        # by default command need a node in the edited list
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   472
        if self.node not in expected:
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   473
            raise error.ParseError(_('%s "%s" changeset was not a candidate')
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   474
                                   % (self.verb, node.short(self.node)),
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   475
                                   hint=_('only use listed changesets'))
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   476
        # and only one command per node
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   477
        if self.node in seen:
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   478
            raise error.ParseError(_('duplicated command for changeset %s') %
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   479
                                   node.short(self.node))
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   480
29466
a0efbfbba7b5 histedit: remove unneeded initial parameter
Sean Farley <sean@farley.io>
parents: 29465
diff changeset
   481
    def torule(self):
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   482
        """build a histedit rule line for an action
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   483
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   484
        by default lines are in the form:
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   485
        <hash> <rev> <summary>
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   486
        """
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   487
        ctx = self.repo[self.node]
29468
04b68ce5e964 histedit: use _getsummary in torule
Sean Farley <sean@farley.io>
parents: 29467
diff changeset
   488
        summary = _getsummary(ctx)
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   489
        line = '%s %s %d %s' % (self.verb, ctx, ctx.rev(), summary)
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   490
        # trim to 75 columns by default so it's not stupidly wide in my editor
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   491
        # (the 5 more are left for verb)
34472
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   492
        maxlen = self.repo.ui.configint('histedit', 'linelen')
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   493
        maxlen = max(maxlen, 22) # avoid truncating hash
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37016
diff changeset
   494
        return stringutil.ellipsis(line, maxlen)
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   495
27206
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   496
    def tostate(self):
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   497
        """Print an action in format used by histedit state files
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   498
           (the first line is a verb, the remainder is the second)
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   499
        """
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   500
        return "%s\n%s" % (self.verb, node.hex(self.node))
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   501
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   502
    def run(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   503
        """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
   504
        rulectx onto the current parentctx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   505
        self.applychange()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   506
        self.continuedirty()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   507
        return self.continueclean()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   508
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   509
    def applychange(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   510
        """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
   511
        parentctx, but does not commit them."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   512
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   513
        rulectx = repo[self.node]
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   514
        repo.ui.pushbuffer(error=True, labeled=True)
27405
5837ca674da9 histedit: omit useless message from update (histeditaction)
timeless <timeless@mozdev.org>
parents: 27403
diff changeset
   515
        hg.update(repo, self.state.parentctxnode, quietempty=True)
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   516
        stats = applychanges(repo.ui, repo, rulectx, {})
35390
7b73bf1a48d4 histedit: preserve active branch while histediting
Boris Feld <boris.feld@octobus.net>
parents: 34917
diff changeset
   517
        repo.dirstate.setbranch(rulectx.branch())
37125
6f570c501e3e merge: deprecate accessing update results by index
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37108
diff changeset
   518
        if stats.unresolvedcount:
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   519
            buf = repo.ui.popbuffer()
36170
28830ba50687 histedit: fix silly bug that was unpacking a bytestr before writing it
Augie Fackler <augie@google.com>
parents: 36168
diff changeset
   520
            repo.ui.write(buf)
27629
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   521
            raise error.InterventionRequired(
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   522
                _('Fix up the change (%s %s)') %
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   523
                (self.verb, node.short(self.node)),
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   524
                hint=_('hg histedit --continue to resume'))
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   525
        else:
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   526
            repo.ui.popbuffer()
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   527
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   528
    def continuedirty(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   529
        """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
   530
        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
   531
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   532
        rulectx = repo[self.node]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   533
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   534
        editor = self.commiteditor()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   535
        commit = commitfuncfor(repo, rulectx)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   536
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   537
        commit(text=rulectx.description(), user=rulectx.user(),
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   538
               date=rulectx.date(), extra=rulectx.extra(), editor=editor)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   539
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   540
    def commiteditor(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   541
        """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
   542
        return False
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   543
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   544
    def continueclean(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   545
        """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
   546
        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
   547
        rulectx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   548
        ctx = self.repo['.']
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   549
        if ctx.node() == self.state.parentctxnode:
28340
c100dbd593e2 histedit: reword message when a changeset produces no changes
timeless <timeless@mozdev.org>
parents: 28294
diff changeset
   550
            self.repo.ui.warn(_('%s: skipping changeset (no changes)\n') %
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   551
                              node.short(self.node))
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   552
            return ctx, [(self.node, tuple())]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   553
        if ctx.node() == self.node:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   554
            # Nothing changed
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   555
            return ctx, []
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   556
        return ctx, [(self.node, (ctx.node(),))]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   557
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   558
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
   559
    """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
   560
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
   561
    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
   562
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   563
    - 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
   564
25450
7e36c3000ead histedit: copyedit docstring wording problem I noticed while here
Augie Fackler <augie@google.com>
parents: 25412
diff changeset
   565
    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
   566
    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
   567
    """
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   568
    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
   569
    def commitfunc(**kwargs):
31459
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   570
        overrides = {('phases', 'new-commit'): phasemin}
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   571
        with repo.ui.configoverride(overrides, 'histedit'):
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
   572
            extra = kwargs.get(r'extra', {}).copy()
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   573
            extra['histedit_source'] = src.hex()
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
   574
            kwargs[r'extra'] = extra
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   575
            return repo.commit(**kwargs)
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   576
    return commitfunc
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   577
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   578
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
   579
    """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
   580
    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
   581
    if ctx.p1().node() == wcpar:
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   582
        # edits are "in place" we do not need to make any merge,
27603
8a87627d263a histedit: fix comment in applychanges
timeless <timeless@mozdev.org>
parents: 27600
diff changeset
   583
        # just applies changes on parent for editing
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   584
        cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
37108
0351fb0153ba histedit: always define update results
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37106
diff changeset
   585
        stats = mergemod.updateresult(0, 0, 0, 0)
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   586
    else:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   587
        try:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   588
            # 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
   589
            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
   590
                              'histedit')
22904
baa3cfa03a83 histedit: use merge.graft
Matt Mackall <mpm@selenic.com>
parents: 22901
diff changeset
   591
            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
   592
        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
   593
            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
   594
    return stats
17407
31c123a2f273 histedit: factored out diff/patch logic
Leah Xue <leahxue@fb.com>
parents: 17340
diff changeset
   595
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   596
def collapse(repo, firstctx, lastctx, commitopts, skipprompt=False):
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   597
    """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
   598
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   599
    Expected commit options are:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   600
        - message
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   601
        - date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   602
        - username
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17666
diff changeset
   603
    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
   604
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   605
    This function works in memory."""
36404
6905c4ec312c histedit: use ctx.rev() instead of %d % ctx
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   606
    ctxs = list(repo.set('%d::%d', firstctx.rev(), lastctx.rev()))
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   607
    if not ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   608
        return None
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   609
    for c in ctxs:
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   610
        if not c.mutable():
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
   611
            raise error.ParseError(
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   612
                _("cannot fold into public change %s") % node.short(c.node()))
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   613
    base = firstctx.parents()[0]
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   614
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   615
    # 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
   616
    # collect all files which might be affected
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   617
    files = set()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   618
    for ctx in ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   619
        files.update(ctx.files())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   620
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   621
    # Recompute copies (avoid recording a -> b -> a)
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   622
    copied = copies.pathcopies(base, lastctx)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   623
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   624
    # prune files which were reverted by the updates
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   625
    files = [f for f in files if not cmdutil.samefile(f, lastctx, base)]
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   626
    # commit version of these files as defined by head
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   627
    headmf = lastctx.manifest()
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   628
    def filectxfn(repo, ctx, path):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   629
        if path in headmf:
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   630
            fctx = lastctx[path]
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   631
            flags = fctx.flags()
35400
8a0cac20a1ad memfilectx: make changectx argument mandatory in constructor (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 35126
diff changeset
   632
            mctx = context.memfilectx(repo, ctx,
21689
503bb3af70fe memfilectx: call super.__init__ instead of duplicating code
Sean Farley <sean.michael.farley@gmail.com>
parents: 21409
diff changeset
   633
                                      fctx.path(), fctx.data(),
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   634
                                      islink='l' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   635
                                      isexec='x' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   636
                                      copied=copied.get(path))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   637
            return mctx
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 22280
diff changeset
   638
        return None
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   639
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   640
    if commitopts.get('message'):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   641
        message = commitopts['message']
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   642
    else:
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   643
        message = firstctx.description()
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   644
    user = commitopts.get('user')
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   645
    date = commitopts.get('date')
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   646
    extra = commitopts.get('extra')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   647
36403
10de411d7207 histedit: rename variables so they have "ctx" in them
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36238
diff changeset
   648
    parents = (firstctx.p1().node(), firstctx.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
   649
    editor = None
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   650
    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
   651
        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
   652
    new = context.memctx(repo,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   653
                         parents=parents,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   654
                         text=message,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   655
                         files=files,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   656
                         filectxfn=filectxfn,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   657
                         user=user,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   658
                         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
   659
                         extra=extra,
22002
a44b7b6f3cd7 histedit: pass 'editform' argument to 'cmdutil.getcommiteditor'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21950
diff changeset
   660
                         editor=editor)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   661
    return repo.commitctx(new)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   662
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   663
def _isdirtywc(repo):
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   664
    return repo[None].dirty(missing=True)
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   665
27084
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   666
def abortdirty():
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   667
    raise error.Abort(_('working copy has pending changes'),
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   668
        hint=_('amend, commit, or revert them and run histedit '
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   669
            '--continue, or abort with histedit --abort'))
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   670
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   671
def action(verbs, message, priority=False, internal=False):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   672
    def wrap(cls):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   673
        assert not priority or not internal
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   674
        verb = verbs[0]
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   675
        if priority:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   676
            primaryactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   677
        elif internal:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   678
            internalactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   679
        elif len(verbs) > 1:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   680
            secondaryactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   681
        else:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   682
            tertiaryactions.add(verb)
27201
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   683
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   684
        cls.verb = verb
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   685
        cls.verbs = verbs
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   686
        cls.message = message
27201
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   687
        for verb in verbs:
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   688
            actiontable[verb] = cls
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   689
        return cls
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   690
    return wrap
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   691
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   692
@action(['pick', 'p'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   693
        _('use commit'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   694
        priority=True)
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   695
class pick(histeditaction):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   696
    def run(self):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   697
        rulectx = self.repo[self.node]
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   698
        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
   699
            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
   700
            return rulectx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   701
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   702
        return super(pick, self).run()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   703
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   704
@action(['edit', 'e'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   705
        _('use commit, but stop for amending'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   706
        priority=True)
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   707
class edit(histeditaction):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   708
    def run(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   709
        repo = self.repo
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   710
        rulectx = repo[self.node]
27407
bf4d5d8dc2aa histedit: omit useless message from update (edit)
timeless <timeless@mozdev.org>
parents: 27406
diff changeset
   711
        hg.update(repo, self.state.parentctxnode, quietempty=True)
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   712
        applychanges(repo.ui, repo, rulectx, {})
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   713
        raise error.InterventionRequired(
27629
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   714
            _('Editing (%s), you may commit or record as needed now.')
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   715
            % node.short(self.node),
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   716
            hint=_('hg histedit --continue to resume'))
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   717
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   718
    def commiteditor(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   719
        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
   720
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   721
@action(['fold', 'f'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   722
        _('use commit, but combine it with the one above'))
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   723
class fold(histeditaction):
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
   724
    def verify(self, prev, expected, seen):
27542
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   725
        """ Verifies semantic correctness of the fold rule"""
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
   726
        super(fold, self).verify(prev, expected, seen)
27542
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   727
        repo = self.repo
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   728
        if not prev:
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   729
            c = repo[self.node].parents()[0]
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   730
        elif not prev.verb in ('pick', 'base'):
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   731
            return
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   732
        else:
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   733
            c = repo[prev.node]
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   734
        if not c.mutable():
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
   735
            raise error.ParseError(
27542
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   736
                _("cannot fold into public change %s") % node.short(c.node()))
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   737
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   738
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   739
    def continuedirty(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   740
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   741
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   742
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   743
        commit = commitfuncfor(repo, rulectx)
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   744
        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
   745
               user=rulectx.user(), date=rulectx.date(),
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   746
               extra=rulectx.extra())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   747
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   748
    def continueclean(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   749
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   750
        ctx = repo['.']
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   751
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   752
        parentctxnode = self.state.parentctxnode
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   753
        if ctx.node() == parentctxnode:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   754
            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
   755
                              node.short(self.node))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   756
            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
   757
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   758
        parentctx = repo[parentctxnode]
36404
6905c4ec312c histedit: use ctx.rev() instead of %d % ctx
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   759
        newcommits = set(c.node() for c in repo.set('(%d::. - %d)',
6905c4ec312c histedit: use ctx.rev() instead of %d % ctx
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   760
                                                    parentctx.rev(),
6905c4ec312c histedit: use ctx.rev() instead of %d % ctx
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36403
diff changeset
   761
                                                    parentctx.rev()))
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   762
        if not newcommits:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   763
            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
   764
                           'descendant of previous commit %s\n') %
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   765
                           (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
   766
            return ctx, [(self.node, (ctx.node(),))]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   767
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   768
        middlecommits = newcommits.copy()
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   769
        middlecommits.discard(ctx.node())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   770
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   771
        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
   772
                               middlecommits)
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   773
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   774
    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
   775
        """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
   776
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   777
        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
   778
        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
   779
        """
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   780
        return False
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   781
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   782
    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
   783
        """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
   784
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   785
        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
   786
        'fold'.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   787
        """
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   788
        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
   789
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   790
    def firstdate(self):
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   791
        """Returns true if the rule should preserve the date of the first
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   792
        change.
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   793
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   794
        This exists mainly so that 'rollup' rules can be a subclass of
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   795
        'fold'.
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   796
        """
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   797
        return False
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   798
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   799
    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
   800
        parent = ctx.parents()[0].node()
38508
39db5a01cd53 cleanup: pass in overwrite flag to hg.updaterepo() as named argument
Yuya Nishihara <yuya@tcha.org>
parents: 38507
diff changeset
   801
        hg.updaterepo(repo, parent, overwrite=False)
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   802
        ### prepare new commit data
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   803
        commitopts = {}
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   804
        commitopts['user'] = ctx.user()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   805
        # 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
   806
        if not self.mergedescs():
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   807
            newmessage = ctx.description()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   808
        else:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   809
            newmessage = '\n***\n'.join(
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   810
                [ctx.description()] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   811
                [repo[r].description() for r in internalchanges] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   812
                [oldctx.description()]) + '\n'
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   813
        commitopts['message'] = newmessage
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   814
        # date
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   815
        if self.firstdate():
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   816
            commitopts['date'] = ctx.date()
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   817
        else:
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   818
            commitopts['date'] = max(ctx.date(), oldctx.date())
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   819
        extra = ctx.extra().copy()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   820
        # histedit_source
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   821
        # 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
   822
        #       here. This is sufficient to solve issue3681 anyway.
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   823
        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
   824
        commitopts['extra'] = extra
31459
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   825
        phasemin = max(ctx.phase(), oldctx.phase())
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   826
        overrides = {('phases', 'new-commit'): phasemin}
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   827
        with repo.ui.configoverride(overrides, 'histedit'):
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   828
            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
   829
                         skipprompt=self.skipprompt())
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   830
        if n is None:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   831
            return ctx, []
38508
39db5a01cd53 cleanup: pass in overwrite flag to hg.updaterepo() as named argument
Yuya Nishihara <yuya@tcha.org>
parents: 38507
diff changeset
   832
        hg.updaterepo(repo, n, overwrite=False)
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   833
        replacements = [(oldctx.node(), (newnode,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   834
                        (ctx.node(), (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   835
                        (newnode, (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   836
                       ]
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   837
        for ich in internalchanges:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   838
            replacements.append((ich, (n,)))
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   839
        return repo[n], replacements
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   840
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
   841
@action(['base', 'b'],
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
   842
        _('checkout changeset and apply further changesets from there'))
27085
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   843
class base(histeditaction):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   844
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   845
    def run(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   846
        if self.repo['.'].node() != self.node:
40366
b14fdf1fb615 update: clarify update() call sites by specifying argument names
Martin von Zweigbergk <martinvonz@google.com>
parents: 40293
diff changeset
   847
            mergemod.update(self.repo, self.node, branchmerge=False, force=True)
27085
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   848
        return self.continueclean()
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   849
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   850
    def continuedirty(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   851
        abortdirty()
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   852
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   853
    def continueclean(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   854
        basectx = self.repo['.']
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   855
        return basectx, []
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   856
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   857
    def _verifynodeconstraints(self, prev, expected, seen):
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   858
        # base can only be use with a node not in the edited set
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   859
        if self.node in expected:
29887
6d66200bff3b histedit: correct output of error when 'base' is from the edit list
Augie Fackler <augie@google.com>
parents: 29881
diff changeset
   860
            msg = _('%s "%s" changeset was an edited list candidate')
6d66200bff3b histedit: correct output of error when 'base' is from the edit list
Augie Fackler <augie@google.com>
parents: 29881
diff changeset
   861
            raise error.ParseError(
6d66200bff3b histedit: correct output of error when 'base' is from the edit list
Augie Fackler <augie@google.com>
parents: 29881
diff changeset
   862
                msg % (self.verb, node.short(self.node)),
6d66200bff3b histedit: correct output of error when 'base' is from the edit list
Augie Fackler <augie@google.com>
parents: 29881
diff changeset
   863
                hint=_('base must only use unlisted changesets'))
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   864
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   865
@action(['_multifold'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   866
        _(
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   867
    """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
   868
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   869
    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
   870
    (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
   871
    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
   872
    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
   873
    commit messages in their editor.
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   874
    """),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   875
        internal=True)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   876
class _multifold(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
   877
    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
   878
        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
   879
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   880
@action(["roll", "r"],
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   881
        _("like fold, but discard this commit's description and date"))
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   882
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
   883
    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
   884
        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
   885
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   886
    def skipprompt(self):
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   887
        return True
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   888
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   889
    def firstdate(self):
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   890
        return True
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   891
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   892
@action(["drop", "d"],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   893
        _('remove commit from history'))
24768
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   894
class drop(histeditaction):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   895
    def run(self):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   896
        parentctx = self.repo[self.state.parentctxnode]
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   897
        return parentctx, [(self.node, tuple())]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   898
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   899
@action(["mess", "m"],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   900
        _('edit commit message without changing commit content'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   901
        priority=True)
24769
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   902
class message(histeditaction):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   903
    def commiteditor(self):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   904
        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
   905
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   906
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
   907
    """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
   908
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   909
    Used by initialization code"""
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   910
    if opts is None:
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   911
        opts = {}
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   912
    dest = ui.expandpath(remote or 'default-push', remote or 'default')
37261
3809eafedf2c parseurl: consistently call second output "branches"
Martin von Zweigbergk <martinvonz@google.com>
parents: 37125
diff changeset
   913
    dest, branches = hg.parseurl(dest, None)[:2]
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   914
    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
   915
37261
3809eafedf2c parseurl: consistently call second output "branches"
Martin von Zweigbergk <martinvonz@google.com>
parents: 37125
diff changeset
   916
    revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   917
    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
   918
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   919
    if revs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   920
        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
   921
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   922
    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
   923
    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
   924
        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
   925
    roots = list(repo.revs("roots(%ln)", outgoing.missing))
40029
e2697acd9381 cleanup: some Yoda conditions, this patch removes
Martin von Zweigbergk <martinvonz@google.com>
parents: 39914
diff changeset
   926
    if len(roots) > 1:
19841
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   927
        msg = _('there are ambiguous outgoing revisions')
29970
5ad164698626 histedit: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29887
diff changeset
   928
        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
   929
        raise error.Abort(msg, hint=hint)
37314
8474005fcfe2 histedit: avoid repo.lookup() for converting revnum to nodeid
Martin von Zweigbergk <martinvonz@google.com>
parents: 37268
diff changeset
   930
    return repo[roots[0]].node()
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   931
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   932
# Curses Support
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   933
try:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   934
    import curses
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   935
except ImportError:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   936
    curses = None
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   937
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   938
KEY_LIST = ['pick', 'edit', 'fold', 'drop', 'mess', 'roll']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   939
ACTION_LABELS = {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   940
    'fold': '^fold',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   941
    'roll': '^roll',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   942
}
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   943
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   944
COLOR_HELP, COLOR_SELECTED, COLOR_OK, COLOR_WARN  = 1, 2, 3, 4
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   945
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   946
E_QUIT, E_HISTEDIT = 1, 2
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   947
E_PAGEDOWN, E_PAGEUP, E_LINEUP, E_LINEDOWN, E_RESIZE = 3, 4, 5, 6, 7
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   948
MODE_INIT, MODE_PATCH, MODE_RULES, MODE_HELP = 0, 1, 2, 3
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   949
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   950
KEYTABLE = {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   951
    'global': {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   952
        'h':         'next-action',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   953
        'KEY_RIGHT': 'next-action',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   954
        'l':         'prev-action',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   955
        'KEY_LEFT':  'prev-action',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   956
        'q':         'quit',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   957
        'c':         'histedit',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   958
        'C':         'histedit',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   959
        'v':         'showpatch',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   960
        '?':         'help',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   961
    },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   962
    MODE_RULES: {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   963
        'd':         'action-drop',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   964
        'e':         'action-edit',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   965
        'f':         'action-fold',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   966
        'm':         'action-mess',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   967
        'p':         'action-pick',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   968
        'r':         'action-roll',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   969
        ' ':         'select',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   970
        'j':         'down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   971
        'k':         'up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   972
        'KEY_DOWN':  'down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   973
        'KEY_UP':    'up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   974
        'J':         'move-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   975
        'K':         'move-up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   976
        'KEY_NPAGE': 'move-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   977
        'KEY_PPAGE': 'move-up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   978
        '0':         'goto',  # Used for 0..9
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   979
    },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   980
    MODE_PATCH: {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   981
        ' ':         'page-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   982
        'KEY_NPAGE': 'page-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   983
        'KEY_PPAGE': 'page-up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   984
        'j':         'line-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   985
        'k':         'line-up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   986
        'KEY_DOWN':  'line-down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   987
        'KEY_UP':    'line-up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   988
        'J':         'down',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   989
        'K':         'up',
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   990
    },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   991
    MODE_HELP: {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   992
    },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   993
}
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   994
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   995
def screen_size():
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   996
    return struct.unpack('hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '    '))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   997
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   998
class histeditrule(object):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
   999
    def __init__(self, ctx, pos, action='pick'):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1000
        self.ctx = ctx
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1001
        self.action = action
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1002
        self.origpos = pos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1003
        self.pos = pos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1004
        self.conflicts = []
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1005
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1006
    def __str__(self):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1007
        # Some actions ('fold' and 'roll') combine a patch with a previous one.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1008
        # Add a marker showing which patch they apply to, and also omit the
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1009
        # description for 'roll' (since it will get discarded). Example display:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1010
        #
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1011
        #  #10 pick   316392:06a16c25c053   add option to skip tests
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1012
        #  #11 ^roll  316393:71313c964cc5
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1013
        #  #12 pick   316394:ab31f3973b0d   include mfbt for mozilla-config.h
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1014
        #  #13 ^fold  316395:14ce5803f4c3   fix warnings
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1015
        #
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1016
        # The carets point to the changeset being folded into ("roll this
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1017
        # changeset into the changeset above").
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1018
        action = ACTION_LABELS.get(self.action, self.action)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1019
        h = self.ctx.hex()[0:12]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1020
        r = self.ctx.rev()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1021
        desc = self.ctx.description().splitlines()[0].strip()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1022
        if self.action == 'roll':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1023
            desc = ''
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1024
        return "#{0:<2} {1:<6} {2}:{3}   {4}".format(
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1025
                self.origpos, action, r, h, desc)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1026
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1027
    def checkconflicts(self, other):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1028
        if other.pos > self.pos and other.origpos <= self.origpos:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1029
            if set(other.ctx.files()) & set(self.ctx.files()) != set():
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1030
                self.conflicts.append(other)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1031
                return self.conflicts
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1032
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1033
        if other in self.conflicts:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1034
            self.conflicts.remove(other)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1035
        return self.conflicts
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1036
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1037
# ============ EVENTS ===============
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1038
def movecursor(state, oldpos, newpos):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1039
    '''Change the rule/changeset that the cursor is pointing to, regardless of
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1040
    current mode (you can switch between patches from the view patch window).'''
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1041
    state['pos'] = newpos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1042
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1043
    mode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1044
    if mode == MODE_RULES:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1045
        # Scroll through the list by updating the view for MODE_RULES, so that
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1046
        # even if we are not currently viewing the rules, switching back will
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1047
        # result in the cursor's rule being visible.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1048
        modestate = state['modes'][MODE_RULES]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1049
        if newpos < modestate['line_offset']:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1050
            modestate['line_offset'] = newpos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1051
        elif newpos > modestate['line_offset'] + state['page_height'] - 1:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1052
            modestate['line_offset'] = newpos - state['page_height'] + 1
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1053
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1054
    # Reset the patch view region to the top of the new patch.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1055
    state['modes'][MODE_PATCH]['line_offset'] = 0
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1056
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1057
def changemode(state, mode):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1058
    curmode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1059
    state['mode'] = (mode, curmode)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1060
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1061
def makeselection(state, pos):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1062
    state['selected'] = pos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1063
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1064
def swap(state, oldpos, newpos):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1065
    """Swap two positions and calculate necessary conflicts in
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1066
    O(|newpos-oldpos|) time"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1067
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1068
    rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1069
    assert 0 <= oldpos < len(rules) and 0 <= newpos < len(rules)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1070
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1071
    rules[oldpos], rules[newpos] = rules[newpos], rules[oldpos]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1072
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1073
    # TODO: swap should not know about histeditrule's internals
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1074
    rules[newpos].pos = newpos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1075
    rules[oldpos].pos = oldpos
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1076
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1077
    start = min(oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1078
    end = max(oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1079
    for r in pycompat.xrange(start, end + 1):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1080
        rules[newpos].checkconflicts(rules[r])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1081
        rules[oldpos].checkconflicts(rules[r])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1082
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1083
    if state['selected']:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1084
        makeselection(state, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1085
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1086
def changeaction(state, pos, action):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1087
    """Change the action state on the given position to the new action"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1088
    rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1089
    assert 0 <= pos < len(rules)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1090
    rules[pos].action = action
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1091
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1092
def cycleaction(state, pos, next=False):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1093
    """Changes the action state the next or the previous action from
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1094
    the action list"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1095
    rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1096
    assert 0 <= pos < len(rules)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1097
    current = rules[pos].action
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1098
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1099
    assert current in KEY_LIST
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1100
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1101
    index = KEY_LIST.index(current)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1102
    if next:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1103
        index += 1
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1104
    else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1105
        index -= 1
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1106
    changeaction(state, pos, KEY_LIST[index % len(KEY_LIST)])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1107
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1108
def changeview(state, delta, unit):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1109
    '''Change the region of whatever is being viewed (a patch or the list of
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1110
    changesets). 'delta' is an amount (+/- 1) and 'unit' is 'page' or 'line'.'''
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1111
    mode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1112
    if mode != MODE_PATCH:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1113
        return
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1114
    mode_state = state['modes'][mode]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1115
    num_lines = len(patchcontents(state))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1116
    page_height = state['page_height']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1117
    unit = page_height if unit == 'page' else 1
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1118
    num_pages = 1 + (num_lines - 1) / page_height
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1119
    max_offset = (num_pages - 1) * page_height
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1120
    newline = mode_state['line_offset'] + delta * unit
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1121
    mode_state['line_offset'] = max(0, min(max_offset, newline))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1122
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1123
def event(state, ch):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1124
    """Change state based on the current character input
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1125
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1126
    This takes the current state and based on the current character input from
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1127
    the user we change the state.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1128
    """
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1129
    selected = state['selected']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1130
    oldpos = state['pos']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1131
    rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1132
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1133
    if ch in (curses.KEY_RESIZE, "KEY_RESIZE"):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1134
        return E_RESIZE
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1135
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1136
    lookup_ch = ch
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1137
    if '0' <= ch <= '9':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1138
        lookup_ch = '0'
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1139
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1140
    curmode, prevmode = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1141
    action = KEYTABLE[curmode].get(lookup_ch, KEYTABLE['global'].get(lookup_ch))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1142
    if action is None:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1143
        return
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1144
    if action in ('down', 'move-down'):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1145
        newpos = min(oldpos + 1, len(rules) - 1)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1146
        movecursor(state, oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1147
        if selected is not None or action == 'move-down':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1148
            swap(state, oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1149
    elif action in ('up', 'move-up'):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1150
        newpos = max(0, oldpos - 1)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1151
        movecursor(state, oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1152
        if selected is not None or action == 'move-up':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1153
            swap(state, oldpos, newpos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1154
    elif action == 'next-action':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1155
        cycleaction(state, oldpos, next=True)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1156
    elif action == 'prev-action':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1157
        cycleaction(state, oldpos, next=False)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1158
    elif action == 'select':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1159
        selected = oldpos if selected is None else None
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1160
        makeselection(state, selected)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1161
    elif action == 'goto' and int(ch) < len(rules) and len(rules) <= 10:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1162
        newrule = next((r for r in rules if r.origpos == int(ch)))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1163
        movecursor(state, oldpos, newrule.pos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1164
        if selected is not None:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1165
            swap(state, oldpos, newrule.pos)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1166
    elif action.startswith('action-'):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1167
        changeaction(state, oldpos, action[7:])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1168
    elif action == 'showpatch':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1169
        changemode(state, MODE_PATCH if curmode != MODE_PATCH else prevmode)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1170
    elif action == 'help':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1171
        changemode(state, MODE_HELP if curmode != MODE_HELP else prevmode)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1172
    elif action == 'quit':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1173
        return E_QUIT
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1174
    elif action == 'histedit':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1175
        return E_HISTEDIT
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1176
    elif action == 'page-down':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1177
        return E_PAGEDOWN
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1178
    elif action == 'page-up':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1179
        return E_PAGEUP
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1180
    elif action == 'line-down':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1181
        return E_LINEDOWN
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1182
    elif action == 'line-up':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1183
        return E_LINEUP
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1184
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1185
def makecommands(rules):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1186
    """Returns a list of commands consumable by histedit --commands based on
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1187
    our list of rules"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1188
    commands = []
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1189
    for rules in rules:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1190
        commands.append("{0} {1}\n".format(rules.action, rules.ctx))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1191
    return commands
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1192
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1193
def addln(win, y, x, line, color=None):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1194
    """Add a line to the given window left padding but 100% filled with
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1195
    whitespace characters, so that the color appears on the whole line"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1196
    maxy, maxx = win.getmaxyx()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1197
    length = maxx - 1 - x
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1198
    line = ("{0:<%d}" % length).format(str(line).strip())[:length]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1199
    if y < 0:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1200
        y = maxy + y
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1201
    if x < 0:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1202
        x = maxx + x
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1203
    if color:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1204
        win.addstr(y, x, line, color)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1205
    else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1206
        win.addstr(y, x, line)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1207
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1208
def patchcontents(state):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1209
    repo = state['repo']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1210
    rule = state['rules'][state['pos']]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1211
    displayer = logcmdutil.changesetdisplayer(repo.ui, repo, {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1212
        'patch': True, 'verbose': True
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1213
    }, buffered=True)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1214
    displayer.show(rule.ctx)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1215
    displayer.close()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1216
    return displayer.hunk[rule.ctx.rev()].splitlines()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1217
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1218
def _chisteditmain(repo, rules, stdscr):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1219
    # initialize color pattern
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1220
    curses.init_pair(COLOR_HELP, curses.COLOR_WHITE, curses.COLOR_BLUE)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1221
    curses.init_pair(COLOR_SELECTED, curses.COLOR_BLACK, curses.COLOR_WHITE)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1222
    curses.init_pair(COLOR_WARN, curses.COLOR_BLACK, curses.COLOR_YELLOW)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1223
    curses.init_pair(COLOR_OK, curses.COLOR_BLACK, curses.COLOR_GREEN)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1224
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1225
    # don't display the cursor
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1226
    try:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1227
        curses.curs_set(0)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1228
    except curses.error:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1229
        pass
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1230
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1231
    def rendercommit(win, state):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1232
        """Renders the commit window that shows the log of the current selected
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1233
        commit"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1234
        pos = state['pos']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1235
        rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1236
        rule = rules[pos]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1237
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1238
        ctx = rule.ctx
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1239
        win.box()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1240
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1241
        maxy, maxx = win.getmaxyx()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1242
        length = maxx - 3
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1243
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1244
        line = "changeset: {0}:{1:<12}".format(ctx.rev(), ctx)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1245
        win.addstr(1, 1, line[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1246
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1247
        line = "user:      {0}".format(stringutil.shortuser(ctx.user()))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1248
        win.addstr(2, 1, line[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1249
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1250
        bms = repo.nodebookmarks(ctx.node())
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1251
        line = "bookmark:  {0}".format(' '.join(bms))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1252
        win.addstr(3, 1, line[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1253
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1254
        line = "files:     {0}".format(','.join(ctx.files()))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1255
        win.addstr(4, 1, line[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1256
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1257
        line = "summary:   {0}".format(ctx.description().splitlines()[0])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1258
        win.addstr(5, 1, line[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1259
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1260
        conflicts = rule.conflicts
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1261
        if len(conflicts) > 0:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1262
            conflictstr = ','.join(map(lambda r: str(r.ctx), conflicts))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1263
            conflictstr = "changed files overlap with {0}".format(conflictstr)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1264
        else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1265
            conflictstr = 'no overlap'
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1266
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1267
        win.addstr(6, 1, conflictstr[:length])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1268
        win.noutrefresh()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1269
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1270
    def helplines(mode):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1271
        if mode == MODE_PATCH:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1272
            help = """\
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1273
?: help, k/up: line up, j/down: line down, v: stop viewing patch
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1274
pgup: prev page, space/pgdn: next page, c: commit, q: abort
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1275
"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1276
        else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1277
            help = """\
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1278
?: help, k/up: move up, j/down: move down, space: select, v: view patch
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1279
d: drop, e: edit, f: fold, m: mess, p: pick, r: roll
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1280
pgup/K: move patch up, pgdn/J: move patch down, c: commit, q: abort
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1281
"""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1282
        return help.splitlines()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1283
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1284
    def renderhelp(win, state):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1285
        maxy, maxx = win.getmaxyx()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1286
        mode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1287
        for y, line in enumerate(helplines(mode)):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1288
            if y >= maxy:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1289
                break
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1290
            addln(win, y, 0, line, curses.color_pair(COLOR_HELP))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1291
        win.noutrefresh()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1292
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1293
    def renderrules(rulesscr, state):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1294
        rules = state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1295
        pos = state['pos']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1296
        selected = state['selected']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1297
        start = state['modes'][MODE_RULES]['line_offset']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1298
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1299
        conflicts = [r.ctx for r in rules if r.conflicts]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1300
        if len(conflicts) > 0:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1301
            line = "potential conflict in %s" % ','.join(map(str, conflicts))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1302
            addln(rulesscr, -1, 0, line, curses.color_pair(COLOR_WARN))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1303
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1304
        for y, rule in enumerate(rules[start:]):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1305
            if y >= state['page_height']:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1306
                break
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1307
            if len(rule.conflicts) > 0:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1308
                rulesscr.addstr(y, 0, " ", curses.color_pair(COLOR_WARN))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1309
            else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1310
                rulesscr.addstr(y, 0, " ", curses.COLOR_BLACK)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1311
            if y + start == selected:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1312
                addln(rulesscr, y, 2, rule, curses.color_pair(COLOR_SELECTED))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1313
            elif y + start == pos:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1314
                addln(rulesscr, y, 2, rule, curses.A_BOLD)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1315
            else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1316
                addln(rulesscr, y, 2, rule)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1317
        rulesscr.noutrefresh()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1318
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1319
    def renderstring(win, state, output):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1320
        maxy, maxx = win.getmaxyx()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1321
        length = min(maxy - 1, len(output))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1322
        for y in range(0, length):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1323
            win.addstr(y, 0, output[y])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1324
        win.noutrefresh()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1325
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1326
    def renderpatch(win, state):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1327
        start = state['modes'][MODE_PATCH]['line_offset']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1328
        renderstring(win, state, patchcontents(state)[start:])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1329
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1330
    def layout(mode):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1331
        maxy, maxx = stdscr.getmaxyx()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1332
        helplen = len(helplines(mode))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1333
        return {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1334
            'commit': (8, maxx),
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1335
            'help': (helplen, maxx),
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1336
            'main': (maxy - helplen - 8, maxx),
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1337
        }
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1338
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1339
    def drawvertwin(size, y, x):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1340
        win = curses.newwin(size[0], size[1], y, x)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1341
        y += size[0]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1342
        return win, y, x
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1343
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1344
    state = {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1345
        'pos': 0,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1346
        'rules': rules,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1347
        'selected': None,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1348
        'mode': (MODE_INIT, MODE_INIT),
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1349
        'page_height': None,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1350
        'modes': {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1351
            MODE_RULES: {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1352
                'line_offset': 0,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1353
            },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1354
            MODE_PATCH: {
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1355
                'line_offset': 0,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1356
            }
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1357
        },
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1358
        'repo': repo,
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1359
    }
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1360
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1361
    # eventloop
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1362
    ch = None
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1363
    stdscr.clear()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1364
    stdscr.refresh()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1365
    while True:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1366
        try:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1367
            oldmode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1368
            if oldmode == MODE_INIT:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1369
                changemode(state, MODE_RULES)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1370
            e = event(state, ch)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1371
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1372
            if e == E_QUIT:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1373
                return False
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1374
            if e == E_HISTEDIT:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1375
                return state['rules']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1376
            else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1377
                if e == E_RESIZE:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1378
                    size = screen_size()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1379
                    if size != stdscr.getmaxyx():
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1380
                        curses.resizeterm(*size)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1381
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1382
                curmode, _ = state['mode']
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1383
                sizes = layout(curmode)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1384
                if curmode != oldmode:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1385
                    state['page_height'] = sizes['main'][0]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1386
                    # Adjust the view to fit the current screen size.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1387
                    movecursor(state, state['pos'], state['pos'])
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1388
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1389
                # Pack the windows against the top, each pane spread across the
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1390
                # full width of the screen.
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1391
                y, x = (0, 0)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1392
                helpwin, y, x = drawvertwin(sizes['help'], y, x)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1393
                mainwin, y, x = drawvertwin(sizes['main'], y, x)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1394
                commitwin, y, x = drawvertwin(sizes['commit'], y, x)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1395
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1396
                if e in (E_PAGEDOWN, E_PAGEUP, E_LINEDOWN, E_LINEUP):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1397
                    if e == E_PAGEDOWN:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1398
                        changeview(state, +1, 'page')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1399
                    elif e == E_PAGEUP:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1400
                        changeview(state, -1, 'page')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1401
                    elif e == E_LINEDOWN:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1402
                        changeview(state, +1, 'line')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1403
                    elif e == E_LINEUP:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1404
                        changeview(state, -1, 'line')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1405
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1406
                # start rendering
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1407
                commitwin.erase()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1408
                helpwin.erase()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1409
                mainwin.erase()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1410
                if curmode == MODE_PATCH:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1411
                    renderpatch(mainwin, state)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1412
                elif curmode == MODE_HELP:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1413
                    renderstring(mainwin, state, __doc__.strip().splitlines())
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1414
                else:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1415
                    renderrules(mainwin, state)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1416
                    rendercommit(commitwin, state)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1417
                renderhelp(helpwin, state)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1418
                curses.doupdate()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1419
                # done rendering
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1420
                ch = stdscr.getkey()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1421
        except curses.error:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1422
            pass
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1423
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1424
def _chistedit(ui, repo, *freeargs, **opts):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1425
    """interactively edit changeset history via a curses interface
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1426
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1427
    Provides a ncurses interface to histedit. Press ? in chistedit mode
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1428
    to see an extensive help. Requires python-curses to be installed."""
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1429
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1430
    if curses is None:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1431
        raise error.Abort(_("Python curses library required"))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1432
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1433
    # disable color
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1434
    ui._colormode = None
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1435
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1436
    try:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1437
        keep = opts.get('keep')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1438
        revs = opts.get('rev', [])[:]
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1439
        cmdutil.checkunfinished(repo)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1440
        cmdutil.bailifchanged(repo)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1441
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1442
        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1443
            raise error.Abort(_('history edit already in progress, try '
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1444
                               '--continue or --abort'))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1445
        revs.extend(freeargs)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1446
        if not revs:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1447
            defaultrev = destutil.desthistedit(ui, repo)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1448
            if defaultrev is not None:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1449
                revs.append(defaultrev)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1450
        if len(revs) != 1:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1451
            raise error.Abort(
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1452
                _('histedit requires exactly one ancestor revision'))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1453
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1454
        rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1455
        if len(rr) != 1:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1456
            raise error.Abort(_('The specified revisions must have '
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1457
                'exactly one common root'))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1458
        root = rr[0].node()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1459
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1460
        topmost, empty = repo.dirstate.parents()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1461
        revs = between(repo, root, topmost, keep)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1462
        if not revs:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1463
            raise error.Abort(_('%s is not an ancestor of working directory') %
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1464
                             node.short(root))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1465
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1466
        ctxs = []
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1467
        for i, r in enumerate(revs):
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1468
            ctxs.append(histeditrule(repo[r], i))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1469
        rc = curses.wrapper(functools.partial(_chisteditmain, repo, ctxs))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1470
        curses.echo()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1471
        curses.endwin()
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1472
        if rc is False:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1473
            ui.write(_("chistedit aborted\n"))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1474
            return 0
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1475
        if type(rc) is list:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1476
            ui.status(_("running histedit\n"))
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1477
            rules = makecommands(rc)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1478
            filename = repo.vfs.join('chistedit')
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1479
            with open(filename, 'w+') as fp:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1480
                for r in rules:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1481
                    fp.write(r)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1482
            opts['commands'] = filename
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1483
            return _texthistedit(ui, repo, *freeargs, **opts)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1484
    except KeyboardInterrupt:
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1485
        pass
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1486
    return -1
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1487
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1488
@command('histedit',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1489
    [('', 'commands', '',
24232
f9e8739018d5 histedit: use better meta-variable names than VALUE in help text
Anton Shestakov <engored@ya.ru>
parents: 24231
diff changeset
  1490
      _('read history edits from the specified file'), _('FILE')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1491
     ('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
  1492
     ('', 'edit-plan', False, _('edit remaining actions list')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1493
     ('k', 'keep', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1494
      _("don't strip old nodes after edit is complete")),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1495
     ('', 'abort', False, _('abort an edit in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1496
     ('o', 'outgoing', False, _('changesets not found in destination')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1497
     ('f', 'force', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
  1498
      _('force outgoing even for unrelated repositories')),
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1499
     ('r', 'rev', [], _('first revision to be edited'), _('REV'))] +
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1500
    cmdutil.formatteropts,
40293
c303d65d2e34 help: assigning categories to existing commands
rdamazio@google.com
parents: 40029
diff changeset
  1501
     _("[OPTIONS] ([ANCESTOR] | --outgoing [URL])"),
c303d65d2e34 help: assigning categories to existing commands
rdamazio@google.com
parents: 40029
diff changeset
  1502
    helpcategory=command.CATEGORY_CHANGE_MANAGEMENT)
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
  1503
def histedit(ui, repo, *freeargs, **opts):
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
  1504
    """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
  1505
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1506
    This command lets you edit a linear series of changesets (up to
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1507
    and including the working directory, which should be clean).
27956
f3eb98b8fe12 doc: prevent non-literal text block from being treated as literal one
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27955
diff changeset
  1508
    You can:
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1509
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1510
    - `pick` to [re]order a changeset
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1511
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1512
    - `drop` to omit changeset
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1513
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1514
    - `mess` to reword the changeset commit message
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1515
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
  1516
    - `fold` to combine it with the preceding changeset (using the later date)
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1517
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
  1518
    - `roll` like fold, but discarding this commit's description and date
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
  1519
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
  1520
    - `edit` to edit this changeset (preserving date)
19622
3d0ece7523c8 histedit: add description about "histedit --outgoing" to command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19621
diff changeset
  1521
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
  1522
    - `base` to checkout changeset and apply further changesets from there
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
  1523
27972
92a61d7618ac histedit: fix typo in documentation
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 27958
diff changeset
  1524
    There are a number of ways to select the root changeset:
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1525
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1526
    - Specify ANCESTOR directly
27262
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1527
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1528
    - Use --outgoing -- it will be the first linear changeset not
28077
27ae22a4f9f9 doc: describe full help document hierarchy to create a valid link in HTML
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28004
diff changeset
  1529
      included in destination. (See :hg:`help config.paths.default-push`)
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1530
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1531
    - Otherwise, the value from the "histedit.defaultrev" config option
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1532
      is used as a revset to select the base revision when ANCESTOR is not
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1533
      specified. The first revision returned by the revset is used. By
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1534
      default, this selects the editable history that is unique to the
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
  1535
      ancestry of the working directory.
19842
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
  1536
27630
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1537
    .. container:: verbose
19842
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
  1538
27630
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1539
       If you use --outgoing, this command will abort if there are ambiguous
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1540
       outgoing revisions. For example, if there are multiple branches
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1541
       containing outgoing revisions.
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1542
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1543
       Use "min(outgoing() and ::.)" or similar revset specification
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1544
       instead of --outgoing to specify edit target revision exactly in
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1545
       such ambiguous situation. See :hg:`help revsets` for detail about
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
  1546
       selecting revisions.
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
  1547
27145
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1548
    .. container:: verbose
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1549
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1550
       Examples:
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1551
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1552
         - A number of changes have been made.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1553
           Revision 3 is no longer needed.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1554
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1555
           Start history editing from revision 3::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1556
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1557
             hg histedit -r 3
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1558
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1559
           An editor opens, containing the list of revisions,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1560
           with specific actions specified::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1561
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1562
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1563
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1564
             pick 0a9639fcda9d 5 Morgify the cromulancy
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1565
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1566
           Additional information about the possible actions
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1567
           to take appears below the list of revisions.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1568
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1569
           To remove revision 3 from the history,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1570
           its action (at the beginning of the relevant line)
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1571
           is changed to 'drop'::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1572
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1573
             drop 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1574
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1575
             pick 0a9639fcda9d 5 Morgify the cromulancy
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1576
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1577
         - A number of changes have been made.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1578
           Revision 2 and 4 need to be swapped.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1579
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1580
           Start history editing from revision 2::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1581
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1582
             hg histedit -r 2
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1583
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1584
           An editor opens, containing the list of revisions,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1585
           with specific actions specified::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1586
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1587
             pick 252a1af424ad 2 Blorb a morgwazzle
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1588
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1589
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1590
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1591
           To swap revision 2 and 4, its lines are swapped
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1592
           in the editor::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1593
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1594
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1595
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1596
             pick 252a1af424ad 2 Blorb a morgwazzle
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1597
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
  1598
    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
  1599
    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
  1600
    conflicts).
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1601
    """
40602
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1602
    if ui.interface('histedit') == 'curses':
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1603
        return _chistedit(ui, repo, *freeargs, **opts)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1604
    return _texthistedit(ui, repo, *freeargs, **opts)
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1605
c36175456350 histedit: import chistedit curses UI from hg-experimental
Augie Fackler <augie@google.com>
parents: 40366
diff changeset
  1606
def _texthistedit(ui, repo, *freeargs, **opts):
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1607
    state = histeditstate(repo)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
  1608
    try:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1609
        state.wlock = repo.wlock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1610
        state.lock = repo.lock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1611
        _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
  1612
    finally:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1613
        release(state.lock, state.wlock)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
  1614
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1615
goalcontinue = 'continue'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1616
goalabort = 'abort'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1617
goaleditplan = 'edit-plan'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1618
goalnew = 'new'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1619
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1620
def _getgoal(opts):
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1621
    if opts.get('continue'):
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1622
        return goalcontinue
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1623
    if opts.get('abort'):
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1624
        return goalabort
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1625
    if opts.get('edit_plan'):
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1626
        return goaleditplan
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1627
    return goalnew
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1628
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1629
def _readfile(ui, path):
28550
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1630
    if path == '-':
30983
d4825798818b histedit: log the time taken to read in the commands list
Simon Farnsworth <simonfar@fb.com>
parents: 30848
diff changeset
  1631
        with ui.timeblockedsection('histedit'):
d4825798818b histedit: log the time taken to read in the commands list
Simon Farnsworth <simonfar@fb.com>
parents: 30848
diff changeset
  1632
            return ui.fin.read()
28550
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1633
    else:
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1634
        with open(path, 'rb') as f:
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1635
            return f.read()
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1636
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1637
def _validateargs(ui, repo, state, freeargs, opts, goal, rules, revs):
27169
dd214130a4f6 histedit: improve grammar for _histedit comment
timeless <timeless@mozdev.org>
parents: 27154
diff changeset
  1638
    # TODO only abort if we try to histedit mq patches, not just
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1639
    # blanket if mq patches are applied somewhere
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1640
    mq = getattr(repo, 'mq', None)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1641
    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
  1642
        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
  1643
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
  1644
    # 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
  1645
    outg = opts.get('outgoing')
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
  1646
    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
  1647
    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
  1648
    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
  1649
    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
  1650
        raise error.Abort(_('--force only allowed with --outgoing'))
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1651
    if goal == 'continue':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1652
        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
  1653
            raise error.Abort(_('no arguments allowed with --continue'))
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1654
    elif goal == 'abort':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1655
        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
  1656
            raise error.Abort(_('no arguments allowed with --abort'))
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1657
    elif goal == 'edit-plan':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1658
        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
  1659
            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
  1660
                               '--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
  1661
    else:
38786
28d8b5f49b4d histedit: avoid repeating name of state file in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 38783
diff changeset
  1662
        if state.inprogress():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1663
            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
  1664
                               '--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
  1665
        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
  1666
            if revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1667
                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
  1668
            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
  1669
                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
  1670
                    _('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
  1671
        else:
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
  1672
            revs.extend(freeargs)
24009
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
  1673
            if len(revs) == 0:
27262
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1674
                defaultrev = destutil.desthistedit(ui, repo)
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1675
                if defaultrev is not None:
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1676
                    revs.append(defaultrev)
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1677
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
  1678
            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
  1679
                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
  1680
                    _('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
  1681
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1682
def _histedit(ui, repo, state, *freeargs, **opts):
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
  1683
    opts = pycompat.byteskwargs(opts)
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1684
    fm = ui.formatter('histedit', opts)
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1685
    fm.startitem()
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1686
    goal = _getgoal(opts)
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1687
    revs = opts.get('rev', [])
38733
c2586a6e5884 histedit: add history-editing-backup config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38549
diff changeset
  1688
    # experimental config: ui.history-editing-backup
38738
faea9b1980d9 histedit: drop --no-backup option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38733
diff changeset
  1689
    nobackup = not ui.configbool('ui', 'history-editing-backup')
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1690
    rules = opts.get('commands', '')
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1691
    state.keep = opts.get('keep', False)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1692
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1693
    _validateargs(ui, repo, state, freeargs, opts, goal, rules, revs)
22977
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
  1694
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
  1695
    # rebuild state
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1696
    if goal == goalcontinue:
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1697
        state.read()
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1698
        state = bootstrapcontinue(ui, state, opts)
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1699
    elif goal == goaleditplan:
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1700
        _edithisteditplan(ui, repo, state, rules)
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
  1701
        return
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1702
    elif goal == goalabort:
38548
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  1703
        _aborthistedit(ui, repo, state, nobackup=nobackup)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1704
        return
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1705
    else:
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1706
        # goal == goalnew
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1707
        _newhistedit(ui, repo, state, revs, freeargs, opts)
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
  1708
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1709
    _continuehistedit(ui, repo, state)
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1710
    _finishhistedit(ui, repo, state, fm)
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1711
    fm.end()
28133
8fc55388ece5 histedit: break _histedit function into smaller pieces (add _continueaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28132
diff changeset
  1712
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1713
def _continuehistedit(ui, repo, state):
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1714
    """This function runs after either:
28133
8fc55388ece5 histedit: break _histedit function into smaller pieces (add _continueaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28132
diff changeset
  1715
    - bootstrapcontinue (if the goal is 'continue')
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1716
    - _newhistedit (if the goal is 'new')
28133
8fc55388ece5 histedit: break _histedit function into smaller pieces (add _continueaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28132
diff changeset
  1717
    """
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
  1718
    # 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
  1719
    # and only show one editor
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1720
    actions = state.actions[:]
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1721
    for idx, (action, nextact) in enumerate(
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1722
            zip(actions, actions[1:] + [None])):
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1723
        if action.verb == 'fold' and nextact and nextact.verb == 'fold':
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1724
            state.actions[idx].__class__ = _multifold
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
  1725
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1726
    # Force an initial state file write, so the user can run --abort/continue
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1727
    # even if there's an exception before the first transaction serialize.
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1728
    state.write()
33445
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1729
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1730
    tr = None
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1731
    # Don't use singletransaction by default since it rolls the entire
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1732
    # transaction back if an unexpected exception happens (like a
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1733
    # pretxncommit hook throws, or the user aborts the commit msg editor).
34473
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
  1734
    if ui.configbool("histedit", "singletransaction"):
33445
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1735
        # Don't use a 'with' for the transaction, since actions may close
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1736
        # and reopen a transaction. For example, if the action executes an
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1737
        # external process it may choose to commit the transaction first.
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1738
        tr = repo.transaction('histedit')
38378
e5d87c69bbcb histedit: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37678
diff changeset
  1739
    progress = ui.makeprogress(_("editing"), unit=_('changes'),
e5d87c69bbcb histedit: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37678
diff changeset
  1740
                               total=len(state.actions))
e5d87c69bbcb histedit: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37678
diff changeset
  1741
    with progress, util.acceptintervention(tr):
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1742
        while state.actions:
33444
c4e39512a661 histedit: remove transaction from state object
Martin von Zweigbergk <martinvonz@google.com>
parents: 33351
diff changeset
  1743
            state.write(tr=tr)
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1744
            actobj = state.actions[0]
38378
e5d87c69bbcb histedit: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37678
diff changeset
  1745
            progress.increment(item=actobj.torule())
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1746
            ui.debug('histedit: processing %s %s\n' % (actobj.verb,\
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1747
                                                       actobj.torule()))
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1748
            parentctx, replacement_ = actobj.run()
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1749
            state.parentctxnode = parentctx.node()
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1750
            state.replacements.extend(replacement_)
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1751
            state.actions.pop(0)
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1752
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1753
    state.write()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1754
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1755
def _finishhistedit(ui, repo, state, fm):
28153
17c474fdb225 histedit: break _histedit into smaller pieces (add _finishaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28144
diff changeset
  1756
    """This action runs when histedit is finishing its session"""
38508
39db5a01cd53 cleanup: pass in overwrite flag to hg.updaterepo() as named argument
Yuya Nishihara <yuya@tcha.org>
parents: 38507
diff changeset
  1757
    hg.updaterepo(repo, state.parentctxnode, overwrite=False)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1758
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1759
    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
  1760
    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
  1761
        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
  1762
            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
  1763
                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
  1764
            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
  1765
                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
  1766
                    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
  1767
                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
  1768
                    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
  1769
                    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
  1770
                        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
  1771
25330
8594d0b3018e histedit: fix keep during --continue
Durham Goode <durham@fb.com>
parents: 24959
diff changeset
  1772
    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
  1773
        if mapping:
33351
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1774
            movetopmostbookmarks(repo, 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
  1775
            # TODO update mq state
33350
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1776
    else:
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1777
        mapping = {}
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1778
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1779
    for n in tmpnodes:
39914
b153ca77a52b histedit: don't cleanup nodes already disposed of
Boris Feld <boris.feld@octobus.net>
parents: 38786
diff changeset
  1780
        if n in repo:
b153ca77a52b histedit: don't cleanup nodes already disposed of
Boris Feld <boris.feld@octobus.net>
parents: 38786
diff changeset
  1781
            mapping[n] = ()
33350
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1782
33351
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1783
    # remove entries about unknown nodes
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1784
    nodemap = repo.unfiltered().changelog.nodemap
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1785
    mapping = {k: v for k, v in mapping.items()
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1786
               if k in nodemap and all(n in nodemap for n in v)}
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1787
    scmutil.cleanupnodes(repo, mapping, 'histedit')
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1788
    hf = fm.hexfunc
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1789
    fl = fm.formatlist
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1790
    fd = fm.formatdict
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1791
    nodechanges = fd({hf(oldn): fl([hf(n) for n in newn], name='node')
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1792
                      for oldn, newn in mapping.iteritems()},
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1793
                     key="oldnode", value="newnodes")
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1794
    fm.data(nodechanges=nodechanges)
25894
54f9561088c7 histedit: backout ebb5bb9bc32e
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25824
diff changeset
  1795
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
  1796
    state.clear()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1797
    if os.path.exists(repo.sjoin('undo')):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1798
        os.unlink(repo.sjoin('undo'))
27546
c00924c54607 histedit: limit cleanup of histedit-last-edit.txt to success
timeless <timeless@mozdev.org>
parents: 27545
diff changeset
  1799
    if repo.vfs.exists('histedit-last-edit.txt'):
c00924c54607 histedit: limit cleanup of histedit-last-edit.txt to success
timeless <timeless@mozdev.org>
parents: 27545
diff changeset
  1800
        repo.vfs.unlink('histedit-last-edit.txt')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1801
38548
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  1802
def _aborthistedit(ui, repo, state, nobackup=False):
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1803
    try:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1804
        state.read()
28179
2e11f6756d9c histedit: unifying the way replacements are computed for abort and success
Kostia Balytskyi <ikostia@fb.com>
parents: 28154
diff changeset
  1805
        __, leafs, tmpnodes, __ = processreplacement(state)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1806
        ui.debug('restore wc to old parent %s\n'
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1807
                % node.short(state.topmost))
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1808
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1809
        # Recover our old commits if necessary
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1810
        if not state.topmost in repo and state.backupfile:
31329
6ce67d3941fc histedit: directly use repo.vfs.join
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31056
diff changeset
  1811
            backupfile = repo.vfs.join(state.backupfile)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1812
            f = hg.openpath(ui, backupfile)
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1813
            gen = exchange.readbundle(ui, f, backupfile)
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1814
            with repo.transaction('histedit.abort') as tr:
33043
18c2489ac96d bundle: make applybundle() delegate v1 bundles to applybundle1()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33039
diff changeset
  1815
                bundle2.applybundle(repo, gen, tr, source='histedit',
18c2489ac96d bundle: make applybundle() delegate v1 bundles to applybundle1()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33039
diff changeset
  1816
                                    url='bundle:' + backupfile)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1817
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1818
            os.remove(backupfile)
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1819
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1820
        # check whether we should update away
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1821
        if repo.unfiltered().revs('parents() and (%n  or %ln::)',
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1822
                                state.parentctxnode, leafs | tmpnodes):
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1823
            hg.clean(repo, state.topmost, show_stats=True, quietempty=True)
38548
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  1824
        cleanupnode(ui, repo, tmpnodes, nobackup=nobackup)
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  1825
        cleanupnode(ui, repo, leafs, nobackup=nobackup)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1826
    except Exception:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1827
        if state.inprogress():
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1828
            ui.warn(_('warning: encountered an exception during histedit '
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1829
                '--abort; the repository may not have been completely '
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1830
                'cleaned up\n'))
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1831
        raise
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1832
    finally:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1833
            state.clear()
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1834
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1835
def _edithisteditplan(ui, repo, state, rules):
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1836
    state.read()
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1837
    if not rules:
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
  1838
        comment = geteditcomment(ui,
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
  1839
                                 node.short(state.parentctxnode),
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1840
                                 node.short(state.topmost))
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1841
        rules = ruleeditor(repo, ui, state.actions, comment)
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1842
    else:
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1843
        rules = _readfile(ui, rules)
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1844
    actions = parserules(rules, state)
29874
0099e29fc95c histedit: drop the 'nodetoverify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29841
diff changeset
  1845
    ctxs = [repo[act.node] \
0099e29fc95c histedit: drop the 'nodetoverify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29841
diff changeset
  1846
            for act in state.actions if act.node]
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1847
    warnverifyactions(ui, repo, actions, state, ctxs)
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1848
    state.actions = actions
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1849
    state.write()
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1850
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1851
def _newhistedit(ui, repo, state, revs, freeargs, opts):
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1852
    outg = opts.get('outgoing')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1853
    rules = opts.get('commands', '')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1854
    force = opts.get('force')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1855
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1856
    cmdutil.checkunfinished(repo)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1857
    cmdutil.bailifchanged(repo)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1858
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1859
    topmost, empty = repo.dirstate.parents()
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1860
    if outg:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1861
        if freeargs:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1862
            remote = freeargs[0]
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1863
        else:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1864
            remote = None
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1865
        root = findoutgoing(ui, repo, remote, force, opts)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1866
    else:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1867
        rr = list(repo.set('roots(%ld)', scmutil.revrange(repo, revs)))
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1868
        if len(rr) != 1:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1869
            raise error.Abort(_('The specified revisions must have '
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1870
                'exactly one common root'))
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1871
        root = rr[0].node()
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1872
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1873
    revs = between(repo, root, topmost, state.keep)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1874
    if not revs:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1875
        raise error.Abort(_('%s is not an ancestor of working directory') %
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1876
                         node.short(root))
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1877
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1878
    ctxs = [repo[r] for r in revs]
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1879
    if not rules:
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
  1880
        comment = geteditcomment(ui, node.short(root), node.short(topmost))
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1881
        actions = [pick(state, r) for r in revs]
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1882
        rules = ruleeditor(repo, ui, actions, comment)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1883
    else:
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1884
        rules = _readfile(ui, rules)
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1885
    actions = parserules(rules, state)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1886
    warnverifyactions(ui, repo, actions, state, ctxs)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1887
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1888
    parentctxnode = repo[root].parents()[0].node()
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1889
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1890
    state.parentctxnode = parentctxnode
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1891
    state.actions = actions
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1892
    state.topmost = topmost
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1893
    state.replacements = []
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1894
35490
784a85c87c22 histedit: add ui.log for action count
Phil Cohen <phillco@fb.com>
parents: 35414
diff changeset
  1895
    ui.log("histedit", "%d actions to histedit", len(actions),
784a85c87c22 histedit: add ui.log for action count
Phil Cohen <phillco@fb.com>
parents: 35414
diff changeset
  1896
           histedit_num_actions=len(actions))
784a85c87c22 histedit: add ui.log for action count
Phil Cohen <phillco@fb.com>
parents: 35414
diff changeset
  1897
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1898
    # Create a backup so we can always abort completely.
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1899
    backupfile = None
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1900
    if not obsolete.isenabled(repo, obsolete.createmarkersopt):
37016
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37003
diff changeset
  1901
        backupfile = repair.backupbundle(repo, [parentctxnode],
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37003
diff changeset
  1902
                                         [topmost], root, 'histedit')
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1903
    state.backupfile = backupfile
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1904
29467
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1905
def _getsummary(ctx):
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1906
    # a common pattern is to extract the summary but default to the empty
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1907
    # string
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1908
    summary = ctx.description() or ''
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1909
    if summary:
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1910
        summary = summary.splitlines()[0]
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1911
    return summary
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1912
24774
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
  1913
def bootstrapcontinue(ui, state, opts):
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
  1914
    repo = state.repo
32057
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1915
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1916
    ms = mergemod.mergestate.read(repo)
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1917
    mergeutil.checkunresolved(ms)
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1918
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1919
    if state.actions:
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1920
        actobj = state.actions.pop(0)
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1921
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
  1922
        if _isdirtywc(repo):
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1923
            actobj.continuedirty()
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
  1924
            if _isdirtywc(repo):
27084
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
  1925
                abortdirty()
24766
cfb8f5e3ca49 histedit: integrate action class into flow
Durham Goode <durham@fb.com>
parents: 24765
diff changeset
  1926
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1927
        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
  1928
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1929
        state.parentctxnode = parentctx.node()
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1930
        state.replacements.extend(replacements)
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1931
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1932
    return state
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
  1933
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1934
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
  1935
    """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
  1936
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1937
    When keep is false, the specified set can't have children."""
36413
f493829b74dd histedit: use repo.revs() instead of repo.set() where revisions are needed
Yuya Nishihara <yuya@tcha.org>
parents: 36409
diff changeset
  1938
    revs = repo.revs('%n::%n', old, new)
f493829b74dd histedit: use repo.revs() instead of repo.set() where revisions are needed
Yuya Nishihara <yuya@tcha.org>
parents: 36409
diff changeset
  1939
    if revs and not keep:
22952
8792ac090e3b obsolete: add allowunstable option
Durham Goode <durham@fb.com>
parents: 22951
diff changeset
  1940
        if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and
36409
72da480db4a5 histedit: resolve revs before evaluating %ld revset
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36404
diff changeset
  1941
            repo.revs('(%ld::) - (%ld)', revs, revs)):
28294
89e04a33e958 histedit: improve error when run on nodes with children (issue5056)
liscju <piotr.listkiewicz@gmail.com>
parents: 28224
diff changeset
  1942
            raise error.Abort(_('can only histedit a changeset together '
89e04a33e958 histedit: improve error when run on nodes with children (issue5056)
liscju <piotr.listkiewicz@gmail.com>
parents: 28224
diff changeset
  1943
                                'with all its descendants'))
36409
72da480db4a5 histedit: resolve revs before evaluating %ld revset
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36404
diff changeset
  1944
        if repo.revs('(%ld) and merge()', revs):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1945
            raise error.Abort(_('cannot edit history that contains merges'))
36413
f493829b74dd histedit: use repo.revs() instead of repo.set() where revisions are needed
Yuya Nishihara <yuya@tcha.org>
parents: 36409
diff changeset
  1946
        root = repo[revs.first()]  # list is already sorted by repo.revs()
22416
810d37485e85 histedit: check mutability of contexts correctly
Augie Fackler <raf@durin42.com>
parents: 22405
diff changeset
  1947
        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
  1948
            raise error.Abort(_('cannot edit public changeset: %s') % root,
29970
5ad164698626 histedit: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29887
diff changeset
  1949
                             hint=_("see 'hg help phases' for details"))
36413
f493829b74dd histedit: use repo.revs() instead of repo.set() where revisions are needed
Yuya Nishihara <yuya@tcha.org>
parents: 36409
diff changeset
  1950
    return pycompat.maplist(repo.changelog.node, revs)
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1951
27204
6b77e749af4a histedit: use torule instead of makedesc in ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 27203
diff changeset
  1952
def ruleeditor(repo, ui, actions, editcomment=""):
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1953
    """open an editor to edit rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1954
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1955
    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
  1956
    """
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1957
    if repo.ui.configbool("experimental", "histedit.autoverb"):
29470
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1958
        newact = util.sortdict()
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1959
        for act in actions:
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1960
            ctx = repo[act.node]
29469
ffa194c3a83c histedit: use _getsummary in ruleeditor
Sean Farley <sean@farley.io>
parents: 29468
diff changeset
  1961
            summary = _getsummary(ctx)
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1962
            fword = summary.split(' ', 1)[0].lower()
29470
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1963
            added = False
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1964
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1965
            # if it doesn't end with the special character '!' just skip this
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1966
            if fword.endswith('!'):
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1967
                fword = fword[:-1]
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1968
                if fword in primaryactions | secondaryactions | tertiaryactions:
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1969
                    act.verb = fword
29470
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1970
                    # get the target summary
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1971
                    tsum = summary[len(fword) + 1:].lstrip()
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1972
                    # safe but slow: reverse iterate over the actions so we
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1973
                    # don't clash on two commits having the same summary
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1974
                    for na, l in reversed(list(newact.iteritems())):
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1975
                        actx = repo[na.node]
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1976
                        asum = _getsummary(actx)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1977
                        if asum == tsum:
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1978
                            added = True
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1979
                            l.append(act)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1980
                            break
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1981
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1982
            if not added:
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1983
                newact[act] = []
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1984
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1985
        # copy over and flatten the new list
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1986
        actions = []
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1987
        for na, l in newact.iteritems():
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1988
            actions.append(na)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1989
            actions += l
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1990
29466
a0efbfbba7b5 histedit: remove unneeded initial parameter
Sean Farley <sean@farley.io>
parents: 29465
diff changeset
  1991
    rules = '\n'.join([act.torule() for act in actions])
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1992
    rules += '\n\n'
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1993
    rules += editcomment
30837
f59ab1b752bd histedit: add tmpdir parameter to ui.edit call
Sean Farley <sean@farley.io>
parents: 30332
diff changeset
  1994
    rules = ui.edit(rules, ui.username(), {'prefix': 'histedit'},
34029
6e6452bc441d editor: use an unambiguous path suffix for editor files
Michael Bolin <mbolin@fb.com>
parents: 33762
diff changeset
  1995
                    repopath=repo.path, action='histedit')
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1996
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1997
    # 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
  1998
    # the user needs to ask for help after something
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1999
    # surprising happens.
36168
be73fa5b42d3 histedit: modernize write of histedit-last-edit file
Augie Fackler <augie@google.com>
parents: 36167
diff changeset
  2000
    with repo.vfs('histedit-last-edit.txt', 'wb') as f:
be73fa5b42d3 histedit: modernize write of histedit-last-edit file
Augie Fackler <augie@google.com>
parents: 36167
diff changeset
  2001
        f.write(rules)
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  2002
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  2003
    return rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  2004
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2005
def parserules(rules, state):
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2006
    """Read the histedit rules string and return list of action objects """
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2007
    rules = [l for l in (r.strip() for r in rules.splitlines())
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2008
                if l and not l.startswith('#')]
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2009
    actions = []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  2010
    for r in rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  2011
        if ' ' not in r:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  2012
            raise error.ParseError(_('malformed line "%s"') % r)
27082
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  2013
        verb, rest = r.split(' ', 1)
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  2014
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2015
        if verb not in actiontable:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  2016
            raise error.ParseError(_('unknown action "%s"') % verb)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2017
27082
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  2018
        action = actiontable[verb].fromrule(state, rest)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2019
        actions.append(action)
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2020
    return actions
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2021
27543
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2022
def warnverifyactions(ui, repo, actions, state, ctxs):
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2023
    try:
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2024
        verifyactions(actions, state, ctxs)
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  2025
    except error.ParseError:
27543
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2026
        if repo.vfs.exists('histedit-last-edit.txt'):
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2027
            ui.warn(_('warning: histedit rules saved '
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2028
                      'to: .hg/histedit-last-edit.txt\n'))
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2029
        raise
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  2030
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2031
def verifyactions(actions, state, ctxs):
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2032
    """Verify that there exists exactly one action per given changeset and
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2033
    other constraints.
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2034
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2035
    Will abort if there are to many or too few rules, a malformed rule,
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2036
    or a rule on a changeset outside of the user-given range.
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2037
    """
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  2038
    expected = set(c.node() for c in ctxs)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2039
    seen = set()
27541
69df2081aeb5 histedit: pass previous action to verify
timeless <timeless@mozdev.org>
parents: 27534
diff changeset
  2040
    prev = None
33762
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  2041
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  2042
    if actions and actions[0].verb in ['roll', 'fold']:
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  2043
        raise error.ParseError(_('first changeset cannot use verb "%s"') %
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  2044
                               actions[0].verb)
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  2045
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  2046
    for action in actions:
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
  2047
        action.verify(prev, expected, seen)
27541
69df2081aeb5 histedit: pass previous action to verify
timeless <timeless@mozdev.org>
parents: 27534
diff changeset
  2048
        prev = action
29876
034d38b5f6fb histedit: drop the 'nodetoverify' local variable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29875
diff changeset
  2049
        if action.node is not None:
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  2050
            seen.add(action.node)
19048
1163ff06ce89 histedit: more precise user message when changeset is missing
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19047
diff changeset
  2051
    missing = sorted(expected - seen)  # sort to stabilize output
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2052
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2053
    if state.repo.ui.configbool('histedit', 'dropmissing'):
28519
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  2054
        if len(actions) == 0:
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  2055
            raise error.ParseError(_('no rules provided'),
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  2056
                    hint=_('use strip extension to remove commits'))
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  2057
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  2058
        drops = [drop(state, n) for n in missing]
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2059
        # put the in the beginning so they execute immediately and
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2060
        # don't show in the edit-plan in the future
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2061
        actions[:0] = drops
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2062
    elif missing:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  2063
        raise error.ParseError(_('missing rules for changeset %s') %
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  2064
                node.short(missing[0]),
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  2065
                hint=_('use "drop %s" to discard, see also: '
29970
5ad164698626 histedit: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29887
diff changeset
  2066
                       "'hg help -e histedit.config'")
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  2067
                       % node.short(missing[0]))
17663
c6de8c696644 histedit: extract bookmark logic in a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17662
diff changeset
  2068
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2069
def adjustreplacementsfrommarkers(repo, oldreplacements):
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30262
diff changeset
  2070
    """Adjust replacements from obsolescence markers
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2071
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2072
    Replacements structure is originally generated based on
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2073
    histedit's state and does not account for changes that are
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2074
    not recorded there. This function fixes that by adding
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30262
diff changeset
  2075
    data read from obsolescence markers"""
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2076
    if not obsolete.isenabled(repo, obsolete.createmarkersopt):
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2077
        return oldreplacements
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2078
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2079
    unfi = repo.unfiltered()
28224
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2080
    nm = unfi.changelog.nodemap
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2081
    obsstore = repo.obsstore
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2082
    newreplacements = list(oldreplacements)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2083
    oldsuccs = [r[1] for r in oldreplacements]
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2084
    # successors that have already been added to succstocheck once
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2085
    seensuccs = set().union(*oldsuccs) # create a set from an iterable of tuples
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2086
    succstocheck = list(seensuccs)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2087
    while succstocheck:
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2088
        n = succstocheck.pop()
28224
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2089
        missing = nm.get(n) is None
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2090
        markers = obsstore.successors.get(n, ())
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2091
        if missing and not markers:
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2092
            # dead end, mark it as such
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2093
            newreplacements.append((n, ()))
28224
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2094
        for marker in markers:
8ec5478aa0d6 histedit: also handle locally missing nodes when reading obsolescence
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28216
diff changeset
  2095
            nsuccs = marker[1]
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2096
            newreplacements.append((n, nsuccs))
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2097
            for nsucc in nsuccs:
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2098
                if nsucc not in seensuccs:
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2099
                    seensuccs.add(nsucc)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2100
                    succstocheck.append(nsucc)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2101
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2102
    return newreplacements
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2103
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  2104
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
  2105
    """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
  2106
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  2107
    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
  2108
    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
  2109
    3) the list of new commit created by histedit"""
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  2110
    replacements = adjustreplacementsfrommarkers(state.repo, 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
  2111
    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
  2112
    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
  2113
    fullmapping = {}
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  2114
    # initialize basic set
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  2115
    # 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
  2116
    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
  2117
        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
  2118
        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
  2119
        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
  2120
    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
  2121
    tmpnodes = allsuccs & replaced
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  2122
    # 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
  2123
    # 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
  2124
    # 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
  2125
    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
  2126
    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
  2127
    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
  2128
        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
  2129
            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
  2130
            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
  2131
                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
  2132
                    # 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
  2133
                    # 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
  2134
                    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
  2135
                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
  2136
                    # 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
  2137
                    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
  2138
                    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
  2139
            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
  2140
                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
  2141
                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
  2142
    # 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
  2143
    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
  2144
        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
  2145
    # 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
  2146
    # 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
  2147
    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
  2148
    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
  2149
        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
  2150
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
  2151
    # 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
  2152
    if new:
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  2153
        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
  2154
    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
  2155
        # 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
  2156
        # 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
  2157
        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
  2158
    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
  2159
        # 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
  2160
        r = state.repo.changelog.rev
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  2161
        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
  2162
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  2163
    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
  2164
33346
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2165
def movetopmostbookmarks(repo, oldtopmost, newtopmost):
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2166
    """Move bookmark from oldtopmost to newly created topmost
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2167
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2168
    This is arguably a feature and we may only want that for the active
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2169
    bookmark. But the behavior is kept compatible with the old version for now.
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2170
    """
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2171
    if not oldtopmost or not newtopmost:
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2172
        return
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2173
    oldbmarks = repo.nodebookmarks(oldtopmost)
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2174
    if oldbmarks:
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2175
        with repo.lock(), repo.transaction('histedit') as tr:
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2176
            marks = repo._bookmarks
33486
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  2177
            changes = []
33346
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2178
            for name in oldbmarks:
33486
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  2179
                changes.append((name, newtopmost))
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  2180
            marks.applychanges(repo, tr, changes)
33346
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  2181
38548
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  2182
def cleanupnode(ui, repo, nodes, nobackup=False):
31637
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2183
    """strip a group of nodes from the repository
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2184
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2185
    The set of node to strip may contains unknown nodes."""
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2186
    with repo.lock():
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2187
        # do not let filtering get in the way of the cleanse
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2188
        # we should probably get rid of obsolescence marker created during the
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2189
        # histedit, but we currently do not have such information.
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2190
        repo = repo.unfiltered()
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2191
        # Find all nodes that need to be stripped
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2192
        # (we use %lr instead of %ln to silently ignore unknown items)
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2193
        nm = repo.changelog.nodemap
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2194
        nodes = sorted(n for n in nodes if n in nm)
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2195
        roots = [c.node() for c in repo.set("roots(%ln)", nodes)]
33349
28f75a1695fb histedit: pass multiple nodes to strip (BC)
Jun Wu <quark@fb.com>
parents: 33348
diff changeset
  2196
        if roots:
38548
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  2197
            backup = not nobackup
7b57b1ed5c0f histedit: add --no-backup option (issue5825)
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38508
diff changeset
  2198
            repair.strip(ui, repo, roots, backup=backup)
31637
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  2199
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  2200
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
  2201
    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
  2202
        nodelist = [nodelist]
38786
28d8b5f49b4d histedit: avoid repeating name of state file in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 38783
diff changeset
  2203
    state = histeditstate(repo)
28d8b5f49b4d histedit: avoid repeating name of state file in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 38783
diff changeset
  2204
    if state.inprogress():
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  2205
        state.read()
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32057
diff changeset
  2206
        histedit_nodes = {action.node for action
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32057
diff changeset
  2207
                          in state.actions if action.node}
30025
4d9999e43ff7 histedit: avoid converting nodeid to context and back again
Martin von Zweigbergk <martinvonz@google.com>
parents: 29970
diff changeset
  2208
        common_nodes = histedit_nodes & set(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
  2209
        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
  2210
            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
  2211
                             % ', '.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
  2212
    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
  2213
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  2214
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
  2215
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2216
def summaryhook(ui, repo):
38786
28d8b5f49b4d histedit: avoid repeating name of state file in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 38783
diff changeset
  2217
    state = histeditstate(repo)
28d8b5f49b4d histedit: avoid repeating name of state file in a few places
Martin von Zweigbergk <martinvonz@google.com>
parents: 38783
diff changeset
  2218
    if not state.inprogress():
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2219
        return
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  2220
    state.read()
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  2221
    if state.actions:
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2222
        # i18n: column positioning for "hg summary"
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2223
        ui.write(_('hist:   %s (histedit --continue)\n') %
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2224
                 (ui.label(_('%d remaining'), 'histedit.remaining') %
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  2225
                  len(state.actions)))
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2226
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2227
def extsetup(ui):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  2228
    cmdutil.summaryhooks.add('histedit', summaryhook)
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  2229
    cmdutil.unfinishedstates.append(
19496
607191a45f8c checkunfinished: accommodate histedit quirk
Matt Mackall <mpm@selenic.com>
parents: 19479
diff changeset
  2230
        ['histedit-state', False, True, _('histedit in progress'),
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  2231
         _("use 'hg histedit --continue' or 'hg histedit --abort'")])
27627
dcbba68e076f histedit: hook afterresolvedstates
timeless <timeless@mozdev.org>
parents: 27604
diff changeset
  2232
    cmdutil.afterresolvedstates.append(
dcbba68e076f histedit: hook afterresolvedstates
timeless <timeless@mozdev.org>
parents: 27604
diff changeset
  2233
        ['histedit-state', _('hg histedit --continue')])