hgext/histedit.py
author Martin von Zweigbergk <martinvonz@google.com>
Wed, 10 Jan 2018 10:32:16 -0800
changeset 35573 5574629d5d45
parent 35490 784a85c87c22
child 36167 73621823a1ac
permissions -rw-r--r--
obsolete: use context manager for lock in pushmarker() Differential Revision: https://phab.mercurial-scm.org/D1836
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
22368
802dffd62de5 histedit: abort gracefully on --continue/--abort with no state
Siddharth Agarwal <sid0@fb.com>
parents: 22147
diff changeset
   186
import errno
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   187
import os
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 29126
diff changeset
   188
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 29126
diff changeset
   189
from mercurial.i18n import _
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   190
from mercurial import (
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   191
    bundle2,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   192
    cmdutil,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   193
    context,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   194
    copies,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   195
    destutil,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   196
    discovery,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   197
    error,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   198
    exchange,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   199
    extensions,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   200
    hg,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   201
    lock,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   202
    merge as mergemod,
32057
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
   203
    mergeutil,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   204
    node,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   205
    obsolete,
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
   206
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32327
diff changeset
   207
    registrar,
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   208
    repair,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   209
    scmutil,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   210
    util,
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   211
)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   212
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29214
diff changeset
   213
pickle = util.pickle
29126
7dd5d19c9773 py3: make hgext/hisedit.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28592
diff changeset
   214
release = lock.release
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   215
cmdtable = {}
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32327
diff changeset
   216
command = registrar.command(cmdtable)
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   217
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   218
configtable = {}
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   219
configitem = registrar.configitem(configtable)
34474
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   220
configitem('experimental', 'histedit.autoverb',
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   221
    default=False,
b068a87e951d configitems: register the 'experimental.histedit.autoverb' config
Boris Feld <boris.feld@octobus.net>
parents: 34473
diff changeset
   222
)
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   223
configitem('histedit', 'defaultrev',
34917
ee9243715c59 registrar: host "dynamicdefault" constant by configitem object
Yuya Nishihara <yuya@tcha.org>
parents: 34788
diff changeset
   224
    default=configitem.dynamicdefault,
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   225
)
34471
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   226
configitem('histedit', 'dropmissing',
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   227
    default=False,
1e37cb4da6f8 configitems: register the 'histedit.dropmissing' config
Boris Feld <boris.feld@octobus.net>
parents: 34470
diff changeset
   228
)
34472
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   229
configitem('histedit', 'linelen',
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   230
    default=80,
12c068377273 configitems: register the 'histedit.linelen' config
Boris Feld <boris.feld@octobus.net>
parents: 34471
diff changeset
   231
)
34473
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   232
configitem('histedit', 'singletransaction',
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   233
    default=False,
a746472c3d09 configitems: register the 'histedit.singletransaction' config
Boris Feld <boris.feld@octobus.net>
parents: 34472
diff changeset
   234
)
34470
6567002ae87e configitems: register the 'histedit.defaultrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   235
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29820
diff changeset
   236
# 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
   237
# 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
   238
# 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
   239
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29820
diff changeset
   240
testedwith = 'ships-with-hg-core'
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   241
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   242
actiontable = {}
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   243
primaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   244
secondaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   245
tertiaryactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   246
internalactions = set()
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   247
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   248
def geteditcomment(ui, first, last):
27673
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   249
    """ construct the editor comment
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   250
    The comment includes::
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   251
     - an intro
27674
78d86664e3a2 histedit: prefer edit commit, edit message, use commit
timeless <timeless@mozdev.org>
parents: 27673
diff changeset
   252
     - sorted primary commands
78d86664e3a2 histedit: prefer edit commit, edit message, use commit
timeless <timeless@mozdev.org>
parents: 27673
diff changeset
   253
     - sorted short commands
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   254
     - 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
   255
     - additional hints
27673
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   256
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   257
    Commands are only included once.
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   258
    """
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   259
    intro = _("""Edit history between %s and %s
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   260
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   261
Commits are listed from least to most recent
d93d340dc6ee histedit: replace editcomment with a function
timeless <timeless@mozdev.org>
parents: 27630
diff changeset
   262
28396
5490b04e6132 histedit: adds hint how to reorder changesets at editor (issue3766)
liscju <piotr.listkiewicz@gmail.com>
parents: 28340
diff changeset
   263
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
   264
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   265
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
   266
""")
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   267
    actions = []
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   268
    def addverb(v):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   269
        a = actiontable[v]
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   270
        lines = a.message.split("\n")
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   271
        if len(a.verbs):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   272
            v = ', '.join(sorted(a.verbs, key=lambda v: len(v)))
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   273
        actions.append(" %s = %s" % (v, lines[0]))
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   274
        actions.extend(['  %s' for l in lines[1:]])
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   275
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   276
    for v in (
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   277
         sorted(primaryactions) +
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   278
         sorted(secondaryactions) +
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   279
         sorted(tertiaryactions)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   280
        ):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   281
        addverb(v)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   282
    actions.append('')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   283
28592
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   284
    hints = []
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   285
    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
   286
        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
   287
                     "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
   288
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   289
    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
   290
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
   291
    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
   292
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   293
class histeditstate(object):
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   294
    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
   295
            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
   296
        self.repo = repo
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   297
        self.actions = actions
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   298
        self.keep = keep
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   299
        self.topmost = topmost
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   300
        self.parentctxnode = parentctxnode
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   301
        self.lock = lock
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
   302
        self.wlock = wlock
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   303
        self.backupfile = None
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   304
        if replacements is None:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   305
            self.replacements = []
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   306
        else:
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   307
            self.replacements = replacements
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   308
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   309
    def read(self):
22986
7b93b49286d0 histedit: update docstring on histeditstate.read()
Augie Fackler <raf@durin42.com>
parents: 22985
diff changeset
   310
        """Load histedit state from disk and set fields appropriately."""
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   311
        try:
27527
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   312
            state = self.repo.vfs.read('histedit-state')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25452
diff changeset
   313
        except IOError as err:
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   314
            if err.errno != errno.ENOENT:
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   315
                raise
28123
6c1b7f80f90f histedit: suggest the correct tool to continue (not histedit)
timeless <timeless@mozdev.org>
parents: 28077
diff changeset
   316
            cmdutil.wrongtooltocontinue(self.repo, _('histedit'))
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   317
27527
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   318
        if state.startswith('v1\n'):
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   319
            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
   320
            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
   321
        else:
dbfaf361c062 histedit: only use pickle if not using the modern save format
Bryan O'Sullivan <bos@serpentine.com>
parents: 27451
diff changeset
   322
            data = pickle.loads(state)
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   323
            parentctxnode, rules, keep, topmost, replacements = data
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   324
            backupfile = None
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   325
24112
5d5ec4fb7ada histedit: switch state to store node instead of ctx
Mateusz Kwapich <mitrandir@fb.com>
parents: 24111
diff changeset
   326
        self.parentctxnode = parentctxnode
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   327
        rules = "\n".join(["%s %s" % (verb, rest) for [verb, rest] in rules])
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   328
        actions = parserules(rules, self)
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   329
        self.actions = actions
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   330
        self.keep = keep
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   331
        self.topmost = topmost
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   332
        self.replacements = replacements
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   333
        self.backupfile = backupfile
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
   334
31511
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   335
    def write(self, tr=None):
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   336
        if tr:
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   337
            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
   338
                                self._write, location='plain')
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   339
        else:
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   340
            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
   341
                self._write(f)
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   342
fa8aaff2001a histedit: add transaction support to writing the state file
Durham Goode <durham@fb.com>
parents: 31459
diff changeset
   343
    def _write(self, fp):
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   344
        fp.write('v1\n')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   345
        fp.write('%s\n' % node.hex(self.parentctxnode))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   346
        fp.write('%s\n' % node.hex(self.topmost))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   347
        fp.write('%s\n' % self.keep)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   348
        fp.write('%d\n' % len(self.actions))
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   349
        for action in self.actions:
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
   350
            fp.write('%s\n' % action.tostate())
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   351
        fp.write('%d\n' % len(self.replacements))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   352
        for replacement in self.replacements:
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   353
            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
   354
                for r in replacement[1])))
24958
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   355
        backupfile = self.backupfile
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   356
        if not backupfile:
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   357
            backupfile = ''
a920abf5a592 histedit: fix serializing of None backupfile
Durham Goode <durham@fb.com>
parents: 24920
diff changeset
   358
        fp.write('%s\n' % backupfile)
22976
886711722db6 histedit: add histedit state class
David Soria Parra <davidsp@fb.com>
parents: 22952
diff changeset
   359
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   360
    def _load(self):
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   361
        fp = self.repo.vfs('histedit-state', 'r')
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   362
        lines = [l[:-1] for l in fp.readlines()]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   363
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   364
        index = 0
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   365
        lines[index] # version number
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   366
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   367
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   368
        parentctxnode = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   369
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   370
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   371
        topmost = node.bin(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   372
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   373
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   374
        keep = lines[index] == 'True'
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   375
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   376
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   377
        # Rules
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   378
        rules = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   379
        rulelen = int(lines[index])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   380
        index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   381
        for i in xrange(rulelen):
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   382
            ruleaction = lines[index]
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   383
            index += 1
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   384
            rule = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   385
            index += 1
24810
f5416657e661 histedit: change state format to allow non-hash lines
Durham Goode <durham@fb.com>
parents: 24774
diff changeset
   386
            rules.append((ruleaction, rule))
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   387
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   388
        # Replacements
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   389
        replacements = []
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   390
        replacementlen = int(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
        for i in xrange(replacementlen):
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   393
            replacement = lines[index]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   394
            original = node.bin(replacement[:40])
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   395
            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
   396
                    range(40, len(replacement), 40)]
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   397
            replacements.append((original, succ))
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   398
            index += 1
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   399
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   400
        backupfile = lines[index]
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   401
        index += 1
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   402
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   403
        fp.close()
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   404
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
   405
        return parentctxnode, rules, keep, topmost, replacements, backupfile
24756
d71c2da01d0d histedit: replace pickle with custom serialization
Durham Goode <durham@fb.com>
parents: 24626
diff changeset
   406
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
   407
    def clear(self):
26583
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   408
        if self.inprogress():
49b568a4e539 histedit: check presence of statefile before deleting it
Christian Delahousse <cdelahousse@fb.com>
parents: 26582
diff changeset
   409
            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
   410
26582
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   411
    def inprogress(self):
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   412
        return self.repo.vfs.exists('histedit-state')
42b908673866 histedit: add inprogress method to state class
Christian Delahousse <cdelahousse@fb.com>
parents: 26335
diff changeset
   413
27200
62b9a87a365e histedit: add actions property to histedit state
Mateusz Kwapich <mitrandir@fb.com>
parents: 27171
diff changeset
   414
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   415
class histeditaction(object):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   416
    def __init__(self, state, node):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   417
        self.state = state
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   418
        self.repo = state.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   419
        self.node = node
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   420
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   421
    @classmethod
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   422
    def fromrule(cls, state, rule):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   423
        """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
   424
        """
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   425
        rulehash = rule.strip().split(' ', 1)[0]
27547
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   426
        try:
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   427
            rev = node.bin(rulehash)
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   428
        except TypeError:
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   429
            raise error.ParseError("invalid changeset %s" % rulehash)
1cbfeb1dc5aa histedit: handle exceptions from node.bin in fromrule
timeless <timeless@mozdev.org>
parents: 27546
diff changeset
   430
        return cls(state, rev)
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   431
29879
b566c5992e07 histedit: move constraint verification to the 'action.verify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29878
diff changeset
   432
    def verify(self, prev, expected, seen):
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   433
        """ Verifies semantic correctness of the rule"""
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   434
        repo = self.repo
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   435
        ha = node.hex(self.node)
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   436
        try:
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   437
            self.node = repo[ha].node()
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   438
        except error.RepoError:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
   439
            raise error.ParseError(_('unknown changeset %s listed')
27202
2226cd4f32ed histedit: add verify() to histeditaction
Mateusz Kwapich <mitrandir@fb.com>
parents: 27201
diff changeset
   440
                              % ha[:12])
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   441
        if self.node is not None:
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   442
            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
   443
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   444
    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
   445
        # 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
   446
        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
   447
            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
   448
                                   % (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
   449
                                   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
   450
        # 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
   451
        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
   452
            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
   453
                                   node.short(self.node))
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   454
29466
a0efbfbba7b5 histedit: remove unneeded initial parameter
Sean Farley <sean@farley.io>
parents: 29465
diff changeset
   455
    def torule(self):
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   456
        """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
   457
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   458
        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
   459
        <hash> <rev> <summary>
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   460
        """
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   461
        ctx = self.repo[self.node]
29468
04b68ce5e964 histedit: use _getsummary in torule
Sean Farley <sean@farley.io>
parents: 29467
diff changeset
   462
        summary = _getsummary(ctx)
27203
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   463
        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
   464
        # 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
   465
        # (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
   466
        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
   467
        maxlen = max(maxlen, 22) # avoid truncating hash
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   468
        return util.ellipsis(line, maxlen)
b6a0f0895a25 histedit: add torule method to histedit action objects
Mateusz Kwapich <mitrandir@fb.com>
parents: 27202
diff changeset
   469
27206
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   470
    def tostate(self):
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   471
        """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
   472
           (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
   473
        """
7a523b6d5265 histedit: add tostate method to histedit action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27205
diff changeset
   474
        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
   475
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   476
    def run(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   477
        """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
   478
        rulectx onto the current parentctx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   479
        self.applychange()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   480
        self.continuedirty()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   481
        return self.continueclean()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   482
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   483
    def applychange(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   484
        """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
   485
        parentctx, but does not commit them."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   486
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   487
        rulectx = repo[self.node]
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   488
        repo.ui.pushbuffer(error=True, labeled=True)
27405
5837ca674da9 histedit: omit useless message from update (histeditaction)
timeless <timeless@mozdev.org>
parents: 27403
diff changeset
   489
        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
   490
        stats = applychanges(repo.ui, repo, rulectx, {})
35390
7b73bf1a48d4 histedit: preserve active branch while histediting
Boris Feld <boris.feld@octobus.net>
parents: 34917
diff changeset
   491
        repo.dirstate.setbranch(rulectx.branch())
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   492
        if stats and stats[3] > 0:
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   493
            buf = repo.ui.popbuffer()
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   494
            repo.ui.write(*buf)
27629
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   495
            raise error.InterventionRequired(
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   496
                _('Fix up the change (%s %s)') %
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   497
                (self.verb, node.short(self.node)),
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   498
                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
   499
        else:
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   500
            repo.ui.popbuffer()
24765
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   501
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   502
    def continuedirty(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   503
        """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
   504
        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
   505
        repo = self.repo
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   506
        rulectx = repo[self.node]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   507
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   508
        editor = self.commiteditor()
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   509
        commit = commitfuncfor(repo, rulectx)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   510
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   511
        commit(text=rulectx.description(), user=rulectx.user(),
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   512
               date=rulectx.date(), extra=rulectx.extra(), editor=editor)
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   513
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   514
    def commiteditor(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   515
        """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
   516
        return False
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   517
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   518
    def continueclean(self):
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   519
        """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
   520
        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
   521
        rulectx."""
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   522
        ctx = self.repo['.']
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   523
        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
   524
            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
   525
                              node.short(self.node))
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   526
            return ctx, [(self.node, tuple())]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   527
        if ctx.node() == self.node:
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   528
            # Nothing changed
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   529
            return ctx, []
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   530
        return ctx, [(self.node, (ctx.node(),))]
bdf84cc2115b histedit: add a new histeditaction class
Durham Goode <durham@fb.com>
parents: 24764
diff changeset
   531
18436
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   532
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
   533
    """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
   534
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18609
diff changeset
   535
    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
   536
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   537
    - 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
   538
25450
7e36c3000ead histedit: copyedit docstring wording problem I noticed while here
Augie Fackler <augie@google.com>
parents: 25412
diff changeset
   539
    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
   540
    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
   541
    """
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   542
    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
   543
    def commitfunc(**kwargs):
31459
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   544
        overrides = {('phases', 'new-commit'): phasemin}
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   545
        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
   546
            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
   547
            extra['histedit_source'] = src.hex()
34999
c4b769bc86da py3: handle keyword arguments in hgext/histedit.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34917
diff changeset
   548
            kwargs[r'extra'] = extra
18440
35513c59f376 histedit: proper phase conservation (issue3724)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18437
diff changeset
   549
            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
   550
    return commitfunc
b38c10502af9 histedit: factor most commit creation in a function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18370
diff changeset
   551
17647
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   552
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
   553
    """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
   554
    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
   555
    if ctx.p1().node() == wcpar:
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   556
        # 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
   557
        # 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
   558
        cmdutil.revert(ui, repo, ctx, (wcpar, node.nullid), all=True)
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   559
        stats = None
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   560
    else:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   561
        try:
d34ba4991188 histedit: replaces patching logic by merges
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17645
diff changeset
   562
            # 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
   563
            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
   564
                              'histedit')
22904
baa3cfa03a83 histedit: use merge.graft
Matt Mackall <mpm@selenic.com>
parents: 22901
diff changeset
   565
            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
   566
        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
   567
            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
   568
    return stats
17407
31c123a2f273 histedit: factored out diff/patch logic
Leah Xue <leahxue@fb.com>
parents: 17340
diff changeset
   569
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   570
def collapse(repo, first, last, commitopts, skipprompt=False):
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   571
    """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
   572
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   573
    Expected commit options are:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   574
        - message
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   575
        - date
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   576
        - username
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17666
diff changeset
   577
    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
   578
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   579
    This function works in memory."""
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   580
    ctxs = list(repo.set('%d::%d', first, last))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   581
    if not ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   582
        return None
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   583
    for c in ctxs:
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   584
        if not c.mutable():
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
   585
            raise error.ParseError(
25452
43906060a3f4 histedit: abort rather than edit a public changeset (issue4704)
Augie Fackler <augie@google.com>
parents: 25450
diff changeset
   586
                _("cannot fold into public change %s") % node.short(c.node()))
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   587
    base = first.parents()[0]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   588
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   589
    # 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
   590
    # collect all files which might be affected
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   591
    files = set()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   592
    for ctx in ctxs:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   593
        files.update(ctx.files())
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   594
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   595
    # Recompute copies (avoid recording a -> b -> a)
19392
f6b047cf9272 histedit: use base for computing renames when folding (issue3729)
Martin Geisler <martin@geisler.net>
parents: 19284
diff changeset
   596
    copied = copies.pathcopies(base, last)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   597
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   598
    # prune files which were reverted by the updates
29820
e1a4015f5e34 histedit: use samefile function from cmdutil
Hannes Oldenburg <hannes.christian.oldenburg@gmail.com>
parents: 29470
diff changeset
   599
    files = [f for f in files if not cmdutil.samefile(f, last, base)]
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   600
    # commit version of these files as defined by head
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   601
    headmf = last.manifest()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   602
    def filectxfn(repo, ctx, path):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   603
        if path in headmf:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   604
            fctx = last[path]
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   605
            flags = fctx.flags()
35400
8a0cac20a1ad memfilectx: make changectx argument mandatory in constructor (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 35126
diff changeset
   606
            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
   607
                                      fctx.path(), fctx.data(),
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   608
                                      islink='l' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   609
                                      isexec='x' in flags,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   610
                                      copied=copied.get(path))
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   611
            return mctx
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 22280
diff changeset
   612
        return None
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   613
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   614
    if commitopts.get('message'):
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   615
        message = commitopts['message']
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   616
    else:
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   617
        message = first.description()
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   618
    user = commitopts.get('user')
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   619
    date = commitopts.get('date')
18437
358c23e8f1c6 histedit: record histedit source (issue3681)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18436
diff changeset
   620
    extra = commitopts.get('extra')
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   621
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   622
    parents = (first.p1().node(), first.p2().node())
22152
d2a5986cb89d histedit: add "roll" command to fold commit data and drop message (issue4256)
Mike Edgar <adgar@google.com>
parents: 22059
diff changeset
   623
    editor = None
24828
5045a003260b histedit: fix rollup prompting for a commit message (issue4606)
Durham Goode <durham@fb.com>
parents: 24810
diff changeset
   624
    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
   625
        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
   626
    new = context.memctx(repo,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   627
                         parents=parents,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   628
                         text=message,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   629
                         files=files,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   630
                         filectxfn=filectxfn,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   631
                         user=user,
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   632
                         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
   633
                         extra=extra,
22002
a44b7b6f3cd7 histedit: pass 'editform' argument to 'cmdutil.getcommiteditor'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21950
diff changeset
   634
                         editor=editor)
17644
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   635
    return repo.commitctx(new)
9ae073f10572 histedit: fold in memory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17643
diff changeset
   636
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   637
def _isdirtywc(repo):
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   638
    return repo[None].dirty(missing=True)
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
   639
27084
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   640
def abortdirty():
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   641
    raise error.Abort(_('working copy has pending changes'),
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   642
        hint=_('amend, commit, or revert them and run histedit '
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   643
            '--continue, or abort with histedit --abort'))
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
   644
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   645
def action(verbs, message, priority=False, internal=False):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   646
    def wrap(cls):
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   647
        assert not priority or not internal
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   648
        verb = verbs[0]
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   649
        if priority:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   650
            primaryactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   651
        elif internal:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   652
            internalactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   653
        elif len(verbs) > 1:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   654
            secondaryactions.add(verb)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   655
        else:
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   656
            tertiaryactions.add(verb)
27201
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   657
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   658
        cls.verb = verb
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   659
        cls.verbs = verbs
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   660
        cls.message = message
27201
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   661
        for verb in verbs:
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   662
            actiontable[verb] = cls
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   663
        return cls
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   664
    return wrap
dcb536d2e138 histedit: add addhisteditaction decorator
Mateusz Kwapich <mitrandir@fb.com>
parents: 27200
diff changeset
   665
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   666
@action(['pick', 'p'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   667
        _('use commit'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   668
        priority=True)
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   669
class pick(histeditaction):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   670
    def run(self):
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   671
        rulectx = self.repo[self.node]
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   672
        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
   673
            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
   674
            return rulectx, []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   675
24767
477e76936b1d histedit: convert pick action into a class
Durham Goode <durham@fb.com>
parents: 24766
diff changeset
   676
        return super(pick, self).run()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   677
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   678
@action(['edit', 'e'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   679
        _('use commit, but stop for amending'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   680
        priority=True)
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   681
class edit(histeditaction):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   682
    def run(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   683
        repo = self.repo
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   684
        rulectx = repo[self.node]
27407
bf4d5d8dc2aa histedit: omit useless message from update (edit)
timeless <timeless@mozdev.org>
parents: 27406
diff changeset
   685
        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
   686
        applychanges(repo.ui, repo, rulectx, {})
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   687
        raise error.InterventionRequired(
27629
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   688
            _('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
   689
            % node.short(self.node),
e7ff83b2bcfe histedit: list action when intervention is required
timeless <timeless@mozdev.org>
parents: 27627
diff changeset
   690
            hint=_('hg histedit --continue to resume'))
24770
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   691
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   692
    def commiteditor(self):
facdb20e60e9 histedit: convert edit action into a class
Durham Goode <durham@fb.com>
parents: 24769
diff changeset
   693
        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
   694
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   695
@action(['fold', 'f'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   696
        _('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
   697
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
   698
    def verify(self, prev, expected, seen):
27542
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   699
        """ 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
   700
        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
   701
        repo = self.repo
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   702
        if not prev:
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   703
            c = repo[self.node].parents()[0]
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   704
        elif not prev.verb in ('pick', 'base'):
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   705
            return
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   706
        else:
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   707
            c = repo[prev.node]
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   708
        if not c.mutable():
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
   709
            raise error.ParseError(
27542
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   710
                _("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
   711
bf0900d3819c histedit: check fold of public change during verify
timeless <timeless@mozdev.org>
parents: 27541
diff changeset
   712
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   713
    def continuedirty(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   714
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   715
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   716
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   717
        commit = commitfuncfor(repo, rulectx)
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   718
        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
   719
               user=rulectx.user(), date=rulectx.date(),
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   720
               extra=rulectx.extra())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   721
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   722
    def continueclean(self):
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   723
        repo = self.repo
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   724
        ctx = repo['.']
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   725
        rulectx = repo[self.node]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   726
        parentctxnode = self.state.parentctxnode
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   727
        if ctx.node() == parentctxnode:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   728
            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
   729
                              node.short(self.node))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   730
            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
   731
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   732
        parentctx = repo[parentctxnode]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   733
        newcommits = set(c.node() for c in repo.set('(%d::. - %d)', parentctx,
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   734
                                                 parentctx))
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   735
        if not newcommits:
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   736
            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
   737
                           'descendant of previous commit %s\n') %
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   738
                           (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
   739
            return ctx, [(self.node, (ctx.node(),))]
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   740
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   741
        middlecommits = newcommits.copy()
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   742
        middlecommits.discard(ctx.node())
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   743
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   744
        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
   745
                               middlecommits)
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   746
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   747
    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
   748
        """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
   749
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   750
        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
   751
        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
   752
        """
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   753
        return False
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   754
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   755
    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
   756
        """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
   757
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   758
        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
   759
        'fold'.
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   760
        """
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   761
        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
   762
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   763
    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
   764
        """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
   765
        change.
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   766
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   767
        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
   768
        'fold'.
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   769
        """
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   770
        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
   771
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   772
    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
   773
        parent = ctx.parents()[0].node()
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   774
        repo.ui.pushbuffer()
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   775
        hg.update(repo, parent)
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   776
        repo.ui.popbuffer()
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   777
        ### prepare new commit data
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   778
        commitopts = {}
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   779
        commitopts['user'] = ctx.user()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   780
        # 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
   781
        if not self.mergedescs():
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   782
            newmessage = ctx.description()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   783
        else:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   784
            newmessage = '\n***\n'.join(
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   785
                [ctx.description()] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   786
                [repo[r].description() for r in internalchanges] +
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   787
                [oldctx.description()]) + '\n'
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   788
        commitopts['message'] = newmessage
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   789
        # 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
   790
        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
   791
            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
   792
        else:
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   793
            commitopts['date'] = max(ctx.date(), oldctx.date())
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   794
        extra = ctx.extra().copy()
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   795
        # histedit_source
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   796
        # 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
   797
        #       here. This is sufficient to solve issue3681 anyway.
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   798
        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
   799
        commitopts['extra'] = extra
31459
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   800
        phasemin = max(ctx.phase(), oldctx.phase())
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   801
        overrides = {('phases', 'new-commit'): phasemin}
f84fbd27b6d3 histedit: get rid of ui.backupconfig
Jun Wu <quark@fb.com>
parents: 31329
diff changeset
   802
        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
   803
            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
   804
                         skipprompt=self.skipprompt())
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   805
        if n is None:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   806
            return ctx, []
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   807
        repo.ui.pushbuffer()
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   808
        hg.update(repo, n)
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
   809
        repo.ui.popbuffer()
24772
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   810
        replacements = [(oldctx.node(), (newnode,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   811
                        (ctx.node(), (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   812
                        (newnode, (n,)),
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   813
                       ]
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   814
        for ich in internalchanges:
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   815
            replacements.append((ich, (n,)))
8f6494eb16eb histedit: move finishfold into fold class
Durham Goode <durham@fb.com>
parents: 24771
diff changeset
   816
        return repo[n], replacements
24771
3133e246c912 histedit: convert fold/roll actions into a class
Durham Goode <durham@fb.com>
parents: 24770
diff changeset
   817
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
   818
@action(['base', 'b'],
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
   819
        _('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
   820
class base(histeditaction):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   821
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   822
    def run(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   823
        if self.repo['.'].node() != self.node:
27344
43c00ca887d1 merge: have merge.update use a matcher instead of partial fn
Augie Fackler <augie@google.com>
parents: 27262
diff changeset
   824
            mergemod.update(self.repo, self.node, False, True)
43c00ca887d1 merge: have merge.update use a matcher instead of partial fn
Augie Fackler <augie@google.com>
parents: 27262
diff changeset
   825
            #                                     branchmerge, force)
27085
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   826
        return self.continueclean()
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   827
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   828
    def continuedirty(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   829
        abortdirty()
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   830
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   831
    def continueclean(self):
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   832
        basectx = self.repo['.']
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   833
        return basectx, []
d50ff8f4891f histedit: add an experimental base action
Mateusz Kwapich <mitrandir@fb.com>
parents: 27084
diff changeset
   834
29880
a485ec066867 histedt: use inheritance to override the constraints in 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29879
diff changeset
   835
    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
   836
        # 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
   837
        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
   838
            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
   839
            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
   840
                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
   841
                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
   842
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   843
@action(['_multifold'],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   844
        _(
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   845
    """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
   846
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
   847
    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
   848
    (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
   849
    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
   850
    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
   851
    commit messages in their editor.
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   852
    """),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   853
        internal=True)
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   854
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
   855
    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
   856
        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
   857
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   858
@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
   859
        _("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
   860
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
   861
    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
   862
        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
   863
24773
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   864
    def skipprompt(self):
090da03361c5 histedit: improve roll action integration with fold
Durham Goode <durham@fb.com>
parents: 24772
diff changeset
   865
        return True
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   866
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   867
    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
   868
        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
   869
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   870
@action(["drop", "d"],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   871
        _('remove commit from history'))
24768
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   872
class drop(histeditaction):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   873
    def run(self):
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   874
        parentctx = self.repo[self.state.parentctxnode]
342671704344 histedit: convert drop action into a class
Durham Goode <durham@fb.com>
parents: 24767
diff changeset
   875
        return parentctx, [(self.node, tuple())]
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
   876
27675
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   877
@action(["mess", "m"],
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   878
        _('edit commit message without changing commit content'),
d073f4c70575 histedit: replace @addhisteditaction with @action
timeless <timeless@mozdev.org>
parents: 27674
diff changeset
   879
        priority=True)
24769
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   880
class message(histeditaction):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   881
    def commiteditor(self):
e875b94dc94c histedit: convert message action into a class
Durham Goode <durham@fb.com>
parents: 24768
diff changeset
   882
        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
   883
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   884
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
   885
    """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
   886
26171
49c1424424de histedit: fix English (en-US)
timeless@mozdev.org
parents: 26100
diff changeset
   887
    Used by initialization code"""
26335
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   888
    if opts is None:
6c93834d7d66 histedit: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26246
diff changeset
   889
        opts = {}
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   890
    dest = ui.expandpath(remote or 'default-push', remote or 'default')
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   891
    dest, revs = hg.parseurl(dest, None)[:2]
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   892
    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
   893
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   894
    revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   895
    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
   896
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   897
    if revs:
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   898
        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
   899
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   900
    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
   901
    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
   902
        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
   903
    roots = list(repo.revs("roots(%ln)", outgoing.missing))
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   904
    if 1 < len(roots):
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   905
        msg = _('there are ambiguous outgoing revisions')
29970
5ad164698626 histedit: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29887
diff changeset
   906
        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
   907
        raise error.Abort(msg, hint=hint)
19841
fab753424e78 histedit: abort if there are multiple roots in "--outgoing" revisions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19622
diff changeset
   908
    return repo.lookup(roots[0])
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
   909
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   910
@command('histedit',
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   911
    [('', 'commands', '',
24232
f9e8739018d5 histedit: use better meta-variable names than VALUE in help text
Anton Shestakov <engored@ya.ru>
parents: 24231
diff changeset
   912
      _('read history edits from the specified file'), _('FILE')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   913
     ('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
   914
     ('', 'edit-plan', False, _('edit remaining actions list')),
17147
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   915
     ('k', 'keep', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   916
      _("don't strip old nodes after edit is complete")),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   917
     ('', 'abort', False, _('abort an edit in progress')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   918
     ('o', 'outgoing', False, _('changesets not found in destination')),
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   919
     ('f', 'force', False,
80e861511e2b histedit: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 17131
diff changeset
   920
      _('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
   921
     ('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
   922
    cmdutil.formatteropts,
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   923
     _("[OPTIONS] ([ANCESTOR] | --outgoing [URL])"))
19020
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
   924
def histedit(ui, repo, *freeargs, **opts):
17131
4fb2d3d16743 histedit: add extension docstring from external README
Augie Fackler <raf@durin42.com>
parents: 17130
diff changeset
   925
    """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
   926
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   927
    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
   928
    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
   929
    You can:
27713
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   930
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   931
    - `pick` to [re]order a changeset
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   932
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   933
    - `drop` to omit changeset
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   934
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   935
    - `mess` to reword the changeset commit message
fb2c77ba577a histedit: explain basics of histedit commands
timeless <timeless@mozdev.org>
parents: 27712
diff changeset
   936
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   937
    - `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
   938
31056
37ab9e20991c histedit: modify rollup to discard date from the rollup commit (issue4820)
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 31055
diff changeset
   939
    - `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
   940
31055
f1b63ec4b987 histedit: improve documentation and behaviour of dates
Ben Schmidt <insightfuls@users.noreply.github.com>
parents: 30983
diff changeset
   941
    - `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
   942
34489
270e344a6c74 histedit: removing the experimental config 'histeditng'
Saurabh Singh <singhsrb@fb.com>
parents: 34475
diff changeset
   943
    - `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
   944
27972
92a61d7618ac histedit: fix typo in documentation
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 27958
diff changeset
   945
    There are a number of ways to select the root changeset:
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   946
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   947
    - Specify ANCESTOR directly
27262
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
   948
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   949
    - 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
   950
      included in destination. (See :hg:`help config.paths.default-push`)
27714
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   951
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   952
    - Otherwise, the value from the "histedit.defaultrev" config option
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   953
      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
   954
      specified. The first revision returned by the revset is used. By
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   955
      default, this selects the editable history that is unique to the
bbb61a8314c3 histedit: clarify modes
timeless <timeless@mozdev.org>
parents: 27713
diff changeset
   956
      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
   957
27630
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   958
    .. container:: verbose
19842
1aaefba2a3a9 histedit: add more detailed help about "--outgoing"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19841
diff changeset
   959
27630
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   960
       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
   961
       outgoing revisions. For example, if there are multiple branches
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   962
       containing outgoing revisions.
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   963
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   964
       Use "min(outgoing() and ::.)" or similar revset specification
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   965
       instead of --outgoing to specify edit target revision exactly in
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   966
       such ambiguous situation. See :hg:`help revsets` for detail about
9358124b4a65 histedit: hide --outgoing warnings
timeless <timeless@mozdev.org>
parents: 27629
diff changeset
   967
       selecting revisions.
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
   968
27145
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   969
    .. container:: verbose
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   970
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   971
       Examples:
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   972
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   973
         - A number of changes have been made.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   974
           Revision 3 is no longer needed.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   975
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   976
           Start history editing from revision 3::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   977
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   978
             hg histedit -r 3
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   979
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   980
           An editor opens, containing the list of revisions,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   981
           with specific actions specified::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   982
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   983
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   984
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   985
             pick 0a9639fcda9d 5 Morgify the cromulancy
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   986
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   987
           Additional information about the possible actions
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   988
           to take appears below the list of revisions.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   989
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   990
           To remove revision 3 from the history,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   991
           its action (at the beginning of the relevant line)
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   992
           is changed to 'drop'::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   993
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   994
             drop 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   995
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   996
             pick 0a9639fcda9d 5 Morgify the cromulancy
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   997
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   998
         - A number of changes have been made.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
   999
           Revision 2 and 4 need to be swapped.
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1000
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1001
           Start history editing from revision 2::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1002
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1003
             hg histedit -r 2
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1004
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1005
           An editor opens, containing the list of revisions,
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1006
           with specific actions specified::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1007
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1008
             pick 252a1af424ad 2 Blorb a morgwazzle
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1009
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1010
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1011
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1012
           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
  1013
           in the editor::
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1014
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1015
             pick 8ef592ce7cc4 4 Bedazzle the zerlog
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1016
             pick 5339bf82f0ca 3 Zworgle the foobar
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1017
             pick 252a1af424ad 2 Blorb a morgwazzle
3a2fd83182fb histedit: add examples
Mathias De Maré <mathias.demare@gmail.com>
parents: 27086
diff changeset
  1018
19972
1e13a5a9c66e histedit: add description about exit code
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19852
diff changeset
  1019
    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
  1020
    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
  1021
    conflicts).
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1022
    """
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1023
    state = histeditstate(repo)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
  1024
    try:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1025
        state.wlock = repo.wlock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1026
        state.lock = repo.lock()
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1027
        _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
  1028
    finally:
22984
e0b5f5e3afe8 histedit: move locks into state
David Soria Parra <davidsp@fb.com>
parents: 22983
diff changeset
  1029
        release(state.lock, state.wlock)
20071
4778f398ec83 histedit: hold wlock and lock while in progress
Siddharth Agarwal <sid0@fb.com>
parents: 19972
diff changeset
  1030
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1031
goalcontinue = 'continue'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1032
goalabort = 'abort'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1033
goaleditplan = 'edit-plan'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1034
goalnew = 'new'
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1035
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1036
def _getgoal(opts):
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1037
    if opts.get('continue'):
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1038
        return goalcontinue
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1039
    if opts.get('abort'):
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1040
        return goalabort
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1041
    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
  1042
        return goaleditplan
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1043
    return goalnew
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1044
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1045
def _readfile(ui, path):
28550
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1046
    if path == '-':
30983
d4825798818b histedit: log the time taken to read in the commands list
Simon Farnsworth <simonfar@fb.com>
parents: 30848
diff changeset
  1047
        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
  1048
            return ui.fin.read()
28550
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1049
    else:
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1050
        with open(path, 'rb') as f:
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1051
            return f.read()
e2b9145e35d8 histedit: do not close stdin
Jun Wu <quark@fb.com>
parents: 28519
diff changeset
  1052
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1053
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
  1054
    # 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
  1055
    # blanket if mq patches are applied somewhere
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1056
    mq = getattr(repo, 'mq', None)
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1057
    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
  1058
        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
  1059
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
  1060
    # 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
  1061
    outg = opts.get('outgoing')
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
  1062
    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
  1063
    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
  1064
    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
  1065
    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
  1066
        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
  1067
    if goal == 'continue':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1068
        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
  1069
            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
  1070
    elif goal == 'abort':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1071
        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
  1072
            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
  1073
    elif goal == 'edit-plan':
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24959
diff changeset
  1074
        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
  1075
            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
  1076
                               '--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
  1077
    else:
12c06686d371 histedit: move all arguments checks to the beginning of the command
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19018
diff changeset
  1078
        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1079
            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
  1080
                               '--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
  1081
        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
  1082
            if revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1083
                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
  1084
            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
  1085
                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
  1086
                    _('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
  1087
        else:
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
  1088
            revs.extend(freeargs)
24009
00d331763442 histedit: allow configuring default behavior
Durham Goode <durham@fb.com>
parents: 24002
diff changeset
  1089
            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
  1090
                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
  1091
                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
  1092
                    revs.append(defaultrev)
3d0feb2f978b histedit: pick an appropriate base changeset by default (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27217
diff changeset
  1093
19021
26b41a902195 histedit: move outgoing processing to its own function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19020
diff changeset
  1094
            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
  1095
                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
  1096
                    _('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
  1097
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1098
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
  1099
    opts = pycompat.byteskwargs(opts)
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1100
    fm = ui.formatter('histedit', opts)
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1101
    fm.startitem()
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1102
    goal = _getgoal(opts)
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1103
    revs = opts.get('rev', [])
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1104
    rules = opts.get('commands', '')
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1105
    state.keep = opts.get('keep', False)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1106
28134
df206e030c59 histedit: break _histedit function into smaller pieces
Kostia Balytskyi <ikostia@fb.com>
parents: 28133
diff changeset
  1107
    _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
  1108
29ae3b190ec5 histedit: use state object where necessary
David Soria Parra <davidsp@fb.com>
parents: 22976
diff changeset
  1109
    # rebuild state
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1110
    if goal == goalcontinue:
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1111
        state.read()
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1112
        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
  1113
    elif goal == goaleditplan:
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1114
        _edithisteditplan(ui, repo, state, rules)
24142
be7cb25186be histedit: add --edit-plan option to histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24141
diff changeset
  1115
        return
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1116
    elif goal == goalabort:
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1117
        _aborthistedit(ui, repo, state)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1118
        return
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1119
    else:
28144
ed6d650b7cb7 histedit: change string literals to constants in goal naming
Kostia Balytskyi <ikostia@fb.com>
parents: 28134
diff changeset
  1120
        # goal == goalnew
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1121
        _newhistedit(ui, repo, state, revs, freeargs, opts)
24757
7b59f16174c5 histedit: store backup file before histedit
Durham Goode <durham@fb.com>
parents: 24756
diff changeset
  1122
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1123
    _continuehistedit(ui, repo, state)
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1124
    _finishhistedit(ui, repo, state, fm)
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1125
    fm.end()
28133
8fc55388ece5 histedit: break _histedit function into smaller pieces (add _continueaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28132
diff changeset
  1126
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1127
def _continuehistedit(ui, repo, state):
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1128
    """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
  1129
    - 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
  1130
    - _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
  1131
    """
26246
bf81b696b8f4 histedit: use one editor when multiple folds happen in a row (issue3524) (BC)
Augie Fackler <augie@google.com>
parents: 26203
diff changeset
  1132
    # 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
  1133
    # and only show one editor
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1134
    actions = state.actions[:]
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1135
    for idx, (action, nextact) in enumerate(
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1136
            zip(actions, actions[1:] + [None])):
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1137
        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
  1138
            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
  1139
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1140
    # 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
  1141
    # 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
  1142
    state.write()
33445
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1143
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1144
    total = len(state.actions)
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1145
    pos = 0
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1146
    tr = None
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1147
    # 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
  1148
    # 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
  1149
    # 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
  1150
    if ui.configbool("histedit", "singletransaction"):
33445
0491004e2233 histedit: create transaction outside of try
Martin von Zweigbergk <martinvonz@google.com>
parents: 33444
diff changeset
  1151
        # 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
  1152
        # 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
  1153
        # 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
  1154
        tr = repo.transaction('histedit')
33446
fad6852cf879 histedit: extract InterventionRequired transaction handling to utils
Martin von Zweigbergk <martinvonz@google.com>
parents: 33445
diff changeset
  1155
    with util.acceptintervention(tr):
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1156
        while state.actions:
33444
c4e39512a661 histedit: remove transaction from state object
Martin von Zweigbergk <martinvonz@google.com>
parents: 33351
diff changeset
  1157
            state.write(tr=tr)
31513
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1158
            actobj = state.actions[0]
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1159
            pos += 1
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1160
            ui.progress(_("editing"), pos, actobj.torule(),
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1161
                        _('changes'), total)
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1162
            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
  1163
                                                       actobj.torule()))
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1164
            parentctx, replacement_ = actobj.run()
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1165
            state.parentctxnode = parentctx.node()
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1166
            state.replacements.extend(replacement_)
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1167
            state.actions.pop(0)
68474b72ea63 histedit: add histedit.singletransaction config option
Durham Goode <durham@fb.com>
parents: 31512
diff changeset
  1168
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1169
    state.write()
27451
f209c85183a7 histedit: add progress support
timeless <timeless@mozdev.org>
parents: 27414
diff changeset
  1170
    ui.progress(_("editing"), None)
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1171
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1172
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
  1173
    """This action runs when histedit is finishing its session"""
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
  1174
    repo.ui.pushbuffer()
27406
11be6b7f95da histedit: omit useless message from update (_histedit)
timeless <timeless@mozdev.org>
parents: 27405
diff changeset
  1175
    hg.update(repo, state.parentctxnode, quietempty=True)
28004
34165875fa5d histedit: limit updated and merging output to important updates
timeless <timeless@mozdev.org>
parents: 27972
diff changeset
  1176
    repo.ui.popbuffer()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1177
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1178
    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
  1179
    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
  1180
        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
  1181
            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
  1182
                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
  1183
            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
  1184
                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
  1185
                    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
  1186
                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
  1187
                    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
  1188
                    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
  1189
                        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
  1190
25330
8594d0b3018e histedit: fix keep during --continue
Durham Goode <durham@fb.com>
parents: 24959
diff changeset
  1191
    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
  1192
        if mapping:
33351
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1193
            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
  1194
            # TODO update mq state
33350
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1195
    else:
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1196
        mapping = {}
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1197
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1198
    for n in tmpnodes:
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1199
        mapping[n] = ()
b320ff822c7e histedit: unify strip backup files on success (BC)
Jun Wu <quark@fb.com>
parents: 33349
diff changeset
  1200
33351
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1201
    # remove entries about unknown nodes
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1202
    nodemap = repo.unfiltered().changelog.nodemap
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1203
    mapping = {k: v for k, v in mapping.items()
154298576d44 histedit: use scmutil.cleanupnodes (BC)
Jun Wu <quark@fb.com>
parents: 33350
diff changeset
  1204
               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
  1205
    scmutil.cleanupnodes(repo, mapping, 'histedit')
35126
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1206
    hf = fm.hexfunc
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1207
    fl = fm.formatlist
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1208
    fd = fm.formatdict
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1209
    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
  1210
                      for oldn, newn in mapping.iteritems()},
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1211
                     key="oldnode", value="newnodes")
a9cc233de513 histedit: add support to output nodechanges using formatter
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34999
diff changeset
  1212
    fm.data(nodechanges=nodechanges)
25894
54f9561088c7 histedit: backout ebb5bb9bc32e
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25824
diff changeset
  1213
22978
d4e764521249 histedit: add clear method to remove state
David Soria Parra <davidsp@fb.com>
parents: 22977
diff changeset
  1214
    state.clear()
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1215
    if os.path.exists(repo.sjoin('undo')):
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1216
        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
  1217
    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
  1218
        repo.vfs.unlink('histedit-last-edit.txt')
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1219
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1220
def _aborthistedit(ui, repo, state):
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1221
    try:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1222
        state.read()
28179
2e11f6756d9c histedit: unifying the way replacements are computed for abort and success
Kostia Balytskyi <ikostia@fb.com>
parents: 28154
diff changeset
  1223
        __, leafs, tmpnodes, __ = processreplacement(state)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1224
        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
  1225
                % node.short(state.topmost))
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1226
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1227
        # 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
  1228
        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
  1229
            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
  1230
            f = hg.openpath(ui, backupfile)
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1231
            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
  1232
            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
  1233
                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
  1234
                                    url='bundle:' + backupfile)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1235
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1236
            os.remove(backupfile)
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1237
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1238
        # 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
  1239
        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
  1240
                                state.parentctxnode, leafs | tmpnodes):
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1241
            hg.clean(repo, state.topmost, show_stats=True, quietempty=True)
33348
72c25a9198a1 histedit: remove "name" parameter from cleanupnode functions
Jun Wu <quark@fb.com>
parents: 33347
diff changeset
  1242
        cleanupnode(ui, repo, tmpnodes)
72c25a9198a1 histedit: remove "name" parameter from cleanupnode functions
Jun Wu <quark@fb.com>
parents: 33347
diff changeset
  1243
        cleanupnode(ui, repo, leafs)
28130
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1244
    except Exception:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1245
        if state.inprogress():
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1246
            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
  1247
                '--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
  1248
                'cleaned up\n'))
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1249
        raise
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1250
    finally:
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1251
            state.clear()
47317570ab8c histedit: break _histedit function into smaller pieces (add _abortaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28123
diff changeset
  1252
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1253
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
  1254
    state.read()
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1255
    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
  1256
        comment = geteditcomment(ui,
cdbd9c0c0775 histedit: add a hint about enabled dropmissing to histedit edit comment
Mateusz Kwapich <mitrandir@fb.com>
parents: 28550
diff changeset
  1257
                                 node.short(state.parentctxnode),
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1258
                                 node.short(state.topmost))
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1259
        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
  1260
    else:
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1261
        rules = _readfile(ui, rules)
28131
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1262
    actions = parserules(rules, state)
29874
0099e29fc95c histedit: drop the 'nodetoverify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29841
diff changeset
  1263
    ctxs = [repo[act.node] \
0099e29fc95c histedit: drop the 'nodetoverify' method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29841
diff changeset
  1264
            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
  1265
    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
  1266
    state.actions = actions
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1267
    state.write()
5a2fb2680a39 histedit: break _histedit function into smaller pieces (add _editplanaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28130
diff changeset
  1268
28154
47f56b6bfed1 histedit: renaming parts to which _histedit was split
Kostia Balytskyi <ikostia@fb.com>
parents: 28153
diff changeset
  1269
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
  1270
    outg = opts.get('outgoing')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1271
    rules = opts.get('commands', '')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1272
    force = opts.get('force')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1273
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1274
    cmdutil.checkunfinished(repo)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1275
    cmdutil.bailifchanged(repo)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1276
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1277
    topmost, empty = repo.dirstate.parents()
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1278
    if outg:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1279
        if freeargs:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1280
            remote = freeargs[0]
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1281
        else:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1282
            remote = None
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1283
        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
  1284
    else:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1285
        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
  1286
        if len(rr) != 1:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1287
            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
  1288
                'exactly one common root'))
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1289
        root = rr[0].node()
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1290
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1291
    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
  1292
    if not revs:
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1293
        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
  1294
                         node.short(root))
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1295
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1296
    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
  1297
    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
  1298
        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
  1299
        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
  1300
        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
  1301
    else:
30262
bc5d0e6fd9f3 histedit: use ui.fin to read commands from stdin
Yuya Nishihara <yuya@tcha.org>
parents: 30025
diff changeset
  1302
        rules = _readfile(ui, rules)
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1303
    actions = parserules(rules, state)
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1304
    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
  1305
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1306
    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
  1307
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1308
    state.parentctxnode = parentctxnode
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1309
    state.actions = actions
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1310
    state.topmost = topmost
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1311
    state.replacements = []
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1312
35490
784a85c87c22 histedit: add ui.log for action count
Phil Cohen <phillco@fb.com>
parents: 35414
diff changeset
  1313
    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
  1314
           histedit_num_actions=len(actions))
784a85c87c22 histedit: add ui.log for action count
Phil Cohen <phillco@fb.com>
parents: 35414
diff changeset
  1315
28132
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1316
    # 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
  1317
    backupfile = None
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1318
    if not obsolete.isenabled(repo, obsolete.createmarkersopt):
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1319
        backupfile = repair._bundle(repo, [parentctxnode], [topmost], root,
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1320
                                    'histedit')
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1321
    state.backupfile = backupfile
2d09a400b495 histedit: break _histedit function into smaller pieces (add _newaction)
Kostia Balytskyi <ikostia@fb.com>
parents: 28131
diff changeset
  1322
29467
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1323
def _getsummary(ctx):
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1324
    # 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
  1325
    # string
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1326
    summary = ctx.description() or ''
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1327
    if summary:
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1328
        summary = summary.splitlines()[0]
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1329
    return summary
4c4232e51167 histedit: extract common summary code into method
Sean Farley <sean@farley.io>
parents: 29466
diff changeset
  1330
24774
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
  1331
def bootstrapcontinue(ui, state, opts):
a9d63d87b837 histedit: delete all non-actionclass related code
Durham Goode <durham@fb.com>
parents: 24773
diff changeset
  1332
    repo = state.repo
32057
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1333
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1334
    ms = mergemod.mergestate.read(repo)
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1335
    mergeutil.checkunresolved(ms)
e5ffc91a2276 histedit: make check for unresolved conflicts explicit (issue5545)
Siddharth Agarwal <sid0@fb.com>
parents: 31638
diff changeset
  1336
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1337
    if state.actions:
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1338
        actobj = state.actions.pop(0)
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1339
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
  1340
        if _isdirtywc(repo):
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1341
            actobj.continuedirty()
26981
cda2e980281e histedit: extracts _isdirtywc function
liscju <piotr.listkiewicz@gmail.com>
parents: 26798
diff changeset
  1342
            if _isdirtywc(repo):
27084
383f10b67fd6 histedit: add abortdirty function
Mateusz Kwapich <mitrandir@fb.com>
parents: 27083
diff changeset
  1343
                abortdirty()
24766
cfb8f5e3ca49 histedit: integrate action class into flow
Durham Goode <durham@fb.com>
parents: 24765
diff changeset
  1344
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1345
        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
  1346
24959
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1347
        state.parentctxnode = parentctx.node()
3c762cceedde histedit: fix --continue when rules are finished
Durham Goode <durham@fb.com>
parents: 24958
diff changeset
  1348
        state.replacements.extend(replacements)
22980
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1349
b3483bc1ec8c histedit: pass state to boostrapcontinue
David Soria Parra <davidsp@fb.com>
parents: 22979
diff changeset
  1350
    return state
17666
5b6c8f2fbda5 histedit: move `continue` logic into a dedicated function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17665
diff changeset
  1351
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1352
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
  1353
    """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
  1354
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1355
    When keep is false, the specified set can't have children."""
17765
ef7760f0be87 histedit: rename `revs` in `ctxs` inside the `between` function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17762
diff changeset
  1356
    ctxs = list(repo.set('%n::%n', old, new))
17766
d9da327516f8 histedit: clean abort when there is nothing to edit
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17765
diff changeset
  1357
    if ctxs and not keep:
22952
8792ac090e3b obsolete: add allowunstable option
Durham Goode <durham@fb.com>
parents: 22951
diff changeset
  1358
        if (not obsolete.isenabled(repo, obsolete.allowunstableopt) and
18270
48deb483a8f8 clfilter: drop unnecessary explicit filtering on histedit
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18165
diff changeset
  1359
            repo.revs('(%ld::) - (%ld)', ctxs, ctxs)):
28294
89e04a33e958 histedit: improve error when run on nodes with children (issue5056)
liscju <piotr.listkiewicz@gmail.com>
parents: 28224
diff changeset
  1360
            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
  1361
                                'with all its descendants'))
19473
10a0ae668fe6 histedit: refuse to edit history that contains merges (issue3962)
Augie Fackler <raf@durin42.com>
parents: 19393
diff changeset
  1362
        if repo.revs('(%ld) and merge()', ctxs):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26584
diff changeset
  1363
            raise error.Abort(_('cannot edit history that contains merges'))
17767
a787e46d3b94 histedit: do not use "min" on ctx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17766
diff changeset
  1364
        root = ctxs[0] # list is already sorted by repo.set
22416
810d37485e85 histedit: check mutability of contexts correctly
Augie Fackler <raf@durin42.com>
parents: 22405
diff changeset
  1365
        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
  1366
            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
  1367
                             hint=_("see 'hg help phases' for details"))
17765
ef7760f0be87 histedit: rename `revs` in `ctxs` inside the `between` function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17762
diff changeset
  1368
    return [c.node() for c in ctxs]
17642
bea381c16809 histedit: move `between function` outside the action logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17641
diff changeset
  1369
27204
6b77e749af4a histedit: use torule instead of makedesc in ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 27203
diff changeset
  1370
def ruleeditor(repo, ui, actions, editcomment=""):
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1371
    """open an editor to edit rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1372
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1373
    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
  1374
    """
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1375
    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
  1376
        newact = util.sortdict()
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1377
        for act in actions:
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1378
            ctx = repo[act.node]
29469
ffa194c3a83c histedit: use _getsummary in ruleeditor
Sean Farley <sean@farley.io>
parents: 29468
diff changeset
  1379
            summary = _getsummary(ctx)
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1380
            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
  1381
            added = False
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1382
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1383
            # 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
  1384
            if fword.endswith('!'):
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1385
                fword = fword[:-1]
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1386
                if fword in primaryactions | secondaryactions | tertiaryactions:
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1387
                    act.verb = fword
29470
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1388
                    # get the target summary
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1389
                    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
  1390
                    # 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
  1391
                    # 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
  1392
                    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
  1393
                        actx = repo[na.node]
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1394
                        asum = _getsummary(actx)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1395
                        if asum == tsum:
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1396
                            added = True
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1397
                            l.append(act)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1398
                            break
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1399
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1400
            if not added:
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1401
                newact[act] = []
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1402
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1403
        # 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
  1404
        actions = []
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1405
        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
  1406
            actions.append(na)
2ff243c415b4 histedit: move autoverb rule to the commit it matches
Sean Farley <sean@farley.io>
parents: 29469
diff changeset
  1407
            actions += l
29465
00d2bf4137e6 histedit: move autoverb logic from torule to ruleeditor
Sean Farley <sean@farley.io>
parents: 29324
diff changeset
  1408
29466
a0efbfbba7b5 histedit: remove unneeded initial parameter
Sean Farley <sean@farley.io>
parents: 29465
diff changeset
  1409
    rules = '\n'.join([act.torule() for act in actions])
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1410
    rules += '\n\n'
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1411
    rules += editcomment
30837
f59ab1b752bd histedit: add tmpdir parameter to ui.edit call
Sean Farley <sean@farley.io>
parents: 30332
diff changeset
  1412
    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
  1413
                    repopath=repo.path, action='histedit')
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1414
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1415
    # 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
  1416
    # the user needs to ask for help after something
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1417
    # surprising happens.
31329
6ce67d3941fc histedit: directly use repo.vfs.join
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31056
diff changeset
  1418
    f = open(repo.vfs.join('histedit-last-edit.txt'), 'w')
24140
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1419
    f.write(rules)
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1420
    f.close()
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1421
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1422
    return rules
5a64b676c5d3 histedit: extract method ruleeditor
Mateusz Kwapich <mitrandir@fb.com>
parents: 24131
diff changeset
  1423
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1424
def parserules(rules, state):
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1425
    """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
  1426
    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
  1427
                if l and not l.startswith('#')]
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1428
    actions = []
17064
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1429
    for r in rules:
168cc52ad7c2 histedit: new extension for interactive history editing
Augie Fackler <raf@durin42.com>
parents:
diff changeset
  1430
        if ' ' not in r:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  1431
            raise error.ParseError(_('malformed line "%s"') % r)
27082
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  1432
        verb, rest = r.split(' ', 1)
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  1433
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1434
        if verb not in actiontable:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  1435
            raise error.ParseError(_('unknown action "%s"') % verb)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1436
27082
4898e442f392 histedit: make verification configurable
Mateusz Kwapich <mitrandir@fb.com>
parents: 27051
diff changeset
  1437
        action = actiontable[verb].fromrule(state, rest)
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1438
        actions.append(action)
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1439
    return actions
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1440
27543
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1441
def warnverifyactions(ui, repo, actions, state, ctxs):
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1442
    try:
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1443
        verifyactions(actions, state, ctxs)
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  1444
    except error.ParseError:
27543
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1445
        if repo.vfs.exists('histedit-last-edit.txt'):
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1446
            ui.warn(_('warning: histedit rules saved '
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1447
                      'to: .hg/histedit-last-edit.txt\n'))
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1448
        raise
ff0e4c8e642d histedit: limit mentioning histedit-last-edit.txt
timeless <timeless@mozdev.org>
parents: 27542
diff changeset
  1449
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1450
def verifyactions(actions, state, ctxs):
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1451
    """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
  1452
    other constraints.
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1453
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1454
    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
  1455
    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
  1456
    """
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  1457
    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
  1458
    seen = set()
27541
69df2081aeb5 histedit: pass previous action to verify
timeless <timeless@mozdev.org>
parents: 27534
diff changeset
  1459
    prev = None
33762
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  1460
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  1461
    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
  1462
        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
  1463
                               actions[0].verb)
c26a76e1af36 histedit: check first changeset for verb "roll" or "fold" (issue5498)
André Klitzing <aklitzing@gmail.com>
parents: 33486
diff changeset
  1464
27208
994d8dced775 histedit: get rid of state.rules
Mateusz Kwapich <mitrandir@fb.com>
parents: 27207
diff changeset
  1465
    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
  1466
        action.verify(prev, expected, seen)
27541
69df2081aeb5 histedit: pass previous action to verify
timeless <timeless@mozdev.org>
parents: 27534
diff changeset
  1467
        prev = action
29876
034d38b5f6fb histedit: drop the 'nodetoverify' local variable
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29875
diff changeset
  1468
        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
  1469
            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
  1470
    missing = sorted(expected - seen)  # sort to stabilize output
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1471
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1472
    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
  1473
        if len(actions) == 0:
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  1474
            raise error.ParseError(_('no rules provided'),
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  1475
                    hint=_('use strip extension to remove commits'))
518a5030acba histedit: have dropmissing abort on empty plan
Mateusz Kwapich <mitrandir@fb.com>
parents: 28396
diff changeset
  1476
29878
d7de02efa47e histedit: directly use node in 'verifyactions'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29877
diff changeset
  1477
        drops = [drop(state, n) for n in missing]
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1478
        # put the in the beginning so they execute immediately and
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1479
        # don't show in the edit-plan in the future
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1480
        actions[:0] = drops
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1481
    elif missing:
27545
a67d2e059a51 histedit: use parse-error exception for parsing
timeless <timeless@mozdev.org>
parents: 27543
diff changeset
  1482
        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
  1483
                node.short(missing[0]),
27414
6602a7b9deec histedit: delete to drop
Mateusz Kwapich <mitrandir@fb.com>
parents: 27407
diff changeset
  1484
                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
  1485
                       "'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
  1486
                       % 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
  1487
28216
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1488
def adjustreplacementsfrommarkers(repo, oldreplacements):
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 30262
diff changeset
  1489
    """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
  1490
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1491
    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
  1492
    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
  1493
    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
  1494
    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
  1495
    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
  1496
        return oldreplacements
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1497
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1498
    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
  1499
    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
  1500
    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
  1501
    newreplacements = list(oldreplacements)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1502
    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
  1503
    # 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
  1504
    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
  1505
    succstocheck = list(seensuccs)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1506
    while succstocheck:
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1507
        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
  1508
        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
  1509
        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
  1510
        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
  1511
            # 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
  1512
            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
  1513
        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
  1514
            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
  1515
            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
  1516
            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
  1517
                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
  1518
                    seensuccs.add(nsucc)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1519
                    succstocheck.append(nsucc)
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1520
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1521
    return newreplacements
eed7d8c07c20 histedit: make histedit aware of obsolescense not stored in state (issue4800)
Kostia Balytskyi <ikostia@fb.com>
parents: 28179
diff changeset
  1522
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1523
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
  1524
    """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
  1525
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  1526
    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
  1527
    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
  1528
    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
  1529
    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
  1530
    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
  1531
    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
  1532
    fullmapping = {}
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1533
    # initialize basic set
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1534
    # 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
  1535
    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
  1536
        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
  1537
        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
  1538
        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
  1539
    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
  1540
    tmpnodes = allsuccs & replaced
26039
84dcc37b1272 histedit: correct spelling etc in more comments
Augie Fackler <augie@google.com>
parents: 26038
diff changeset
  1541
    # 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
  1542
    # 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
  1543
    # 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
  1544
    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
  1545
    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
  1546
    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
  1547
        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
  1548
            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
  1549
            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
  1550
                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
  1551
                    # 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
  1552
                    # 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
  1553
                    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
  1554
                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
  1555
                    # 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
  1556
                    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
  1557
                    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
  1558
            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
  1559
                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
  1560
                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
  1561
    # 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
  1562
    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
  1563
        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
  1564
    # 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
  1565
    # 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
  1566
    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
  1567
    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
  1568
        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
  1569
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
  1570
    # 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
  1571
    if new:
22985
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1572
        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
  1573
    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
  1574
        # 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
  1575
        # 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
  1576
        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
  1577
    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
  1578
        # 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
  1579
        r = state.repo.changelog.rev
0c14b9166da6 histedit: remove now-superfluous repo argument from processreplacement
Augie Fackler <raf@durin42.com>
parents: 22984
diff changeset
  1580
        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
  1581
5863f0e4cd3a histedit: replace various nodes lists with replacement graph (and issue3582)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17757
diff changeset
  1582
    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
  1583
33346
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1584
def movetopmostbookmarks(repo, oldtopmost, newtopmost):
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1585
    """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
  1586
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1587
    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
  1588
    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
  1589
    """
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1590
    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
  1591
        return
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1592
    oldbmarks = repo.nodebookmarks(oldtopmost)
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1593
    if oldbmarks:
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1594
        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
  1595
            marks = repo._bookmarks
33486
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  1596
            changes = []
33346
7aa5160bdbf5 histedit: move topmost bookmark movement to a separate function
Jun Wu <quark@fb.com>
parents: 33345
diff changeset
  1597
            for name in oldbmarks:
33486
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  1598
                changes.append((name, newtopmost))
af402f11cb9d bookmark: use 'applychanges' when updating bookmark in histedit
Boris Feld <boris.feld@octobus.net>
parents: 33446
diff changeset
  1599
            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
  1600
33348
72c25a9198a1 histedit: remove "name" parameter from cleanupnode functions
Jun Wu <quark@fb.com>
parents: 33347
diff changeset
  1601
def cleanupnode(ui, repo, nodes):
31637
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1602
    """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
  1603
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1604
    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
  1605
    with repo.lock():
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1606
        # 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
  1607
        # 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
  1608
        # 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
  1609
        repo = repo.unfiltered()
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1610
        # 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
  1611
        # (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
  1612
        nm = repo.changelog.nodemap
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1613
        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
  1614
        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
  1615
        if roots:
28f75a1695fb histedit: pass multiple nodes to strip (BC)
Jun Wu <quark@fb.com>
parents: 33348
diff changeset
  1616
            repair.strip(ui, repo, roots)
31637
c4dd1e7c1dab histedit: backout changeset 2b599f5468a4
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31528
diff changeset
  1617
24111
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1618
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
  1619
    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
  1620
        nodelist = [nodelist]
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1621
    if os.path.exists(os.path.join(repo.path, 'histedit-state')):
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1622
        state = histeditstate(repo)
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1623
        state.read()
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32057
diff changeset
  1624
        histedit_nodes = {action.node for action
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32057
diff changeset
  1625
                          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
  1626
        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
  1627
        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
  1628
            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
  1629
                             % ', '.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
  1630
    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
  1631
11d72683f3de histedit: don't allow to strip nodes which are necessary to continue histedit
Mateusz Kwapich <mitrandir@fb.com>
parents: 24009
diff changeset
  1632
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
  1633
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1634
def summaryhook(ui, repo):
31329
6ce67d3941fc histedit: directly use repo.vfs.join
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31056
diff changeset
  1635
    if not os.path.exists(repo.vfs.join('histedit-state')):
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1636
        return
22983
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1637
    state = histeditstate(repo)
a3a981563ce8 histedit: read state from histeditstate
David Soria Parra <davidsp@fb.com>
parents: 22982
diff changeset
  1638
    state.read()
27207
2d8dbeb2462c histedit: change state.rules uses to state.actions
Mateusz Kwapich <mitrandir@fb.com>
parents: 27206
diff changeset
  1639
    if state.actions:
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1640
        # i18n: column positioning for "hg summary"
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1641
        ui.write(_('hist:   %s (histedit --continue)\n') %
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1642
                 (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
  1643
                  len(state.actions)))
19215
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1644
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1645
def extsetup(ui):
f184fe1e2ac5 summary: add a histedit hook
Bryan O'Sullivan <bryano@fb.com>
parents: 19048
diff changeset
  1646
    cmdutil.summaryhooks.add('histedit', summaryhook)
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  1647
    cmdutil.unfinishedstates.append(
19496
607191a45f8c checkunfinished: accommodate histedit quirk
Matt Mackall <mpm@selenic.com>
parents: 19479
diff changeset
  1648
        ['histedit-state', False, True, _('histedit in progress'),
19479
11664641fbad histedit: add checkunfinished support (issue3955)
Matt Mackall <mpm@selenic.com>
parents: 19473
diff changeset
  1649
         _("use 'hg histedit --continue' or 'hg histedit --abort'")])
27627
dcbba68e076f histedit: hook afterresolvedstates
timeless <timeless@mozdev.org>
parents: 27604
diff changeset
  1650
    cmdutil.afterresolvedstates.append(
dcbba68e076f histedit: hook afterresolvedstates
timeless <timeless@mozdev.org>
parents: 27604
diff changeset
  1651
        ['histedit-state', _('hg histedit --continue')])