2014-06-02 23:54:54 +04:00
|
|
|
# fbamend.py - improved amend functionality
|
|
|
|
#
|
|
|
|
# Copyright 2013 Facebook, Inc.
|
|
|
|
#
|
|
|
|
# This software may be used and distributed according to the terms of the
|
|
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
|
|
|
|
"""extends the existing commit amend functionality
|
|
|
|
|
2016-09-21 17:45:25 +03:00
|
|
|
Adds an hg amend command that amends the current parent changeset with the
|
2014-06-02 23:54:54 +04:00
|
|
|
changes in the working copy. Similiar to the existing hg commit --amend
|
|
|
|
except it doesn't prompt for the commit message unless --edit is provided.
|
|
|
|
|
2016-09-21 17:45:25 +03:00
|
|
|
Allows amending changesets that have children and can automatically rebase
|
|
|
|
the children onto the new version of the changeset.
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2014-06-12 09:34:21 +04:00
|
|
|
This extension is incompatible with changeset evolution. The command will
|
|
|
|
automatically disable itself if changeset evolution is enabled.
|
2016-10-25 21:10:47 +03:00
|
|
|
|
|
|
|
To disable the creation of preamend bookmarks and use obsolescence
|
2016-11-16 05:46:56 +03:00
|
|
|
markers instead to fix up amends, enable the userestack option::
|
2016-10-25 21:10:47 +03:00
|
|
|
|
|
|
|
[fbamend]
|
2016-11-16 05:46:56 +03:00
|
|
|
userestack = true
|
|
|
|
|
|
|
|
To make `hg previous` and `hg next` always pick the newest commit at
|
|
|
|
each step of walking up or down the stack instead of aborting when
|
2017-01-20 11:24:45 +03:00
|
|
|
encountering non-linearity (equivalent to the --newest flag), enable
|
2016-11-16 05:46:56 +03:00
|
|
|
the following config option::
|
|
|
|
|
|
|
|
[fbamend]
|
|
|
|
alwaysnewest = true
|
2016-10-25 21:10:47 +03:00
|
|
|
|
2014-06-02 23:54:54 +04:00
|
|
|
"""
|
|
|
|
|
2017-06-14 03:08:50 +03:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
from mercurial import (
|
|
|
|
bookmarks,
|
|
|
|
cmdutil,
|
|
|
|
commands,
|
2016-10-04 20:29:55 +03:00
|
|
|
error,
|
|
|
|
extensions,
|
|
|
|
merge,
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
obsolete,
|
|
|
|
phases,
|
2017-05-22 23:38:37 +03:00
|
|
|
registrar,
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
repair,
|
2017-01-20 11:24:45 +03:00
|
|
|
scmutil,
|
2017-03-12 23:11:47 +03:00
|
|
|
util,
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
)
|
2017-06-14 03:09:16 +03:00
|
|
|
from mercurial.node import hex
|
2015-08-04 19:10:50 +03:00
|
|
|
from mercurial import lock as lockmod
|
2014-06-02 23:54:54 +04:00
|
|
|
from mercurial.i18n import _
|
|
|
|
|
2017-06-14 03:08:50 +03:00
|
|
|
from . import (
|
2017-06-14 03:09:16 +03:00
|
|
|
common,
|
|
|
|
movement,
|
2017-06-14 03:09:34 +03:00
|
|
|
restack,
|
2017-06-14 03:08:50 +03:00
|
|
|
unamend,
|
|
|
|
)
|
|
|
|
|
2014-06-02 23:54:54 +04:00
|
|
|
cmdtable = {}
|
2017-05-22 23:38:37 +03:00
|
|
|
command = registrar.command(cmdtable)
|
2017-06-14 03:08:50 +03:00
|
|
|
|
|
|
|
cmdtable.update(unamend.cmdtable)
|
2017-06-14 03:09:16 +03:00
|
|
|
cmdtable.update(movement.cmdtable)
|
2017-06-14 03:08:50 +03:00
|
|
|
|
2016-11-29 16:24:07 +03:00
|
|
|
testedwith = 'ships-with-fb-hgext'
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2015-09-25 05:46:12 +03:00
|
|
|
rebasemod = None
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
inhibitmod = None
|
2015-09-25 05:46:12 +03:00
|
|
|
|
2015-02-12 22:02:34 +03:00
|
|
|
amendopts = [
|
2016-09-21 17:45:25 +03:00
|
|
|
('', 'rebase', None, _('rebases children after the amend')),
|
|
|
|
('', 'fixup', None, _('rebase children from a previous amend')),
|
2014-06-02 23:54:54 +04:00
|
|
|
]
|
|
|
|
|
|
|
|
def uisetup(ui):
|
2015-09-25 05:46:12 +03:00
|
|
|
global rebasemod
|
|
|
|
try:
|
|
|
|
rebasemod = extensions.find('rebase')
|
|
|
|
except KeyError:
|
2016-01-11 21:19:22 +03:00
|
|
|
ui.warn(_("no rebase extension detected - disabling fbamend"))
|
2015-09-25 05:46:12 +03:00
|
|
|
return
|
2017-06-14 03:09:16 +03:00
|
|
|
common.detectinhibit()
|
2015-09-25 05:46:12 +03:00
|
|
|
|
2014-06-02 23:54:54 +04:00
|
|
|
entry = extensions.wrapcommand(commands.table, 'commit', commit)
|
|
|
|
for opt in amendopts:
|
|
|
|
opt = (opt[0], opt[1], opt[2], "(with --amend) " + opt[3])
|
|
|
|
entry[1].append(opt)
|
2016-09-23 20:39:36 +03:00
|
|
|
|
2014-06-12 09:34:21 +04:00
|
|
|
# manual call of the decorator
|
|
|
|
command('^amend', [
|
2015-04-15 19:29:09 +03:00
|
|
|
('A', 'addremove', None,
|
|
|
|
_('mark new/missing files as added/removed before committing')),
|
2014-06-12 09:34:21 +04:00
|
|
|
('e', 'edit', None, _('prompt to edit the commit message')),
|
2015-10-24 03:00:56 +03:00
|
|
|
('i', 'interactive', None, _('use interactive mode')),
|
2014-06-12 09:34:21 +04:00
|
|
|
] + amendopts + commands.walkopts + commands.commitopts,
|
|
|
|
_('hg amend [OPTION]...'))(amend)
|
|
|
|
|
2016-02-04 14:03:31 +03:00
|
|
|
def has_automv(loaded):
|
|
|
|
if not loaded:
|
|
|
|
return
|
|
|
|
automv = extensions.find('automv')
|
|
|
|
entry = extensions.wrapcommand(cmdtable, 'amend', automv.mvcheck)
|
|
|
|
entry[1].append(
|
|
|
|
('', 'no-move-detection', None,
|
|
|
|
_('disable automatic file move detection')))
|
|
|
|
extensions.afterloaded('automv', has_automv)
|
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
def evolveloaded(loaded):
|
2016-09-23 20:39:36 +03:00
|
|
|
if not loaded:
|
|
|
|
return
|
Make hg next --rebase intelligently obsolete/inhibit changesets
Summary:
This change updates the behavior hg next --rebase. Specifically:
- Only one changeset can be rebased at a time. If there are multiple candidate changesets, the command aborts.
- Each time a changeset is rebased, its precursor is marked as obsolete, inhibition markers are stripped from it and its ancestors, and its preamend bookmark is deleted, if one exists.
- The result of this is that if no non-obsolete changesets depend on the existence of the pre-rebased changeset, that changeset and its ancestors will be stripped, resulting in a cleaner user experience.
- This change also adds back the --evolve flag, but makes it show in error instead of working. It turns out that removing the flag outright breaks the evolve extension.
Test Plan:
See updated unit tests for the exact commands to run to test this, as well as an overview of all of the new situations where behavior was changed.
A basic test plan would be:
1. Initialize a new repository, and create a stack of 4 commits.
2. Amend the second commit in the stack.
3. Do `hg next --rebase`. It should work as before.
4. Do `hg next --rebase` again. This time, the entire old stack should "disappear" from hg sl.
Additionally, attempting to run `hg next --rebase` when there are multiple possible child changesets should fail.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3941922
Tasks: 13570554
Signature: t1:3941922:1475205056:58a8d1726cfcccbf14a38727be0220a09532ec97
2016-09-30 20:40:58 +03:00
|
|
|
|
|
|
|
global inhibitmod
|
|
|
|
try:
|
|
|
|
inhibitmod = extensions.find('inhibit')
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
2016-09-23 20:39:36 +03:00
|
|
|
evolvemod = extensions.find('evolve')
|
2016-11-16 05:46:56 +03:00
|
|
|
|
2017-06-14 03:09:16 +03:00
|
|
|
# Remove `hg previous`, `hg next` from evolve.
|
|
|
|
table = evolvemod.cmdtable
|
2017-06-15 20:35:28 +03:00
|
|
|
for name in ['prev', 'next']:
|
|
|
|
todelete = [k for k in table if name in k]
|
|
|
|
for k in todelete:
|
|
|
|
oldentry = table[k]
|
|
|
|
table['debugevolve%s' % name] = oldentry
|
|
|
|
del table[k]
|
2017-01-20 11:24:45 +03:00
|
|
|
|
|
|
|
# Wrap `hg split`.
|
|
|
|
splitentry = extensions.wrapcommand(
|
|
|
|
evolvemod.cmdtable,
|
|
|
|
'split',
|
|
|
|
wrapsplit,
|
|
|
|
)
|
|
|
|
splitentry[1].append(
|
|
|
|
('', 'norebase', False, _("don't rebase children after split"))
|
|
|
|
)
|
|
|
|
|
|
|
|
# Wrap `hg fold`.
|
|
|
|
foldentry = extensions.wrapcommand(
|
|
|
|
evolvemod.cmdtable,
|
|
|
|
'fold',
|
|
|
|
wrapfold,
|
|
|
|
)
|
|
|
|
foldentry[1].append(
|
|
|
|
('', 'norebase', False, _("don't rebase children after fold"))
|
|
|
|
)
|
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
extensions.afterloaded('evolve', evolveloaded)
|
2016-02-04 14:03:31 +03:00
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
def rebaseloaded(loaded):
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
if not loaded:
|
|
|
|
return
|
|
|
|
entry = extensions.wrapcommand(rebasemod.cmdtable, 'rebase',
|
2016-11-03 21:11:39 +03:00
|
|
|
wraprebase)
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
entry[1].append((
|
|
|
|
'', 'restack', False, _('rebase all changesets in the current '
|
|
|
|
'stack onto the latest version of their '
|
|
|
|
'respective parents')
|
|
|
|
))
|
2016-11-03 21:11:39 +03:00
|
|
|
extensions.afterloaded('rebase', rebaseloaded)
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
|
2014-06-02 23:54:54 +04:00
|
|
|
def commit(orig, ui, repo, *pats, **opts):
|
|
|
|
if opts.get("amend"):
|
|
|
|
# commit --amend default behavior is to prompt for edit
|
2015-04-07 23:31:44 +03:00
|
|
|
opts['noeditmessage'] = True
|
2014-06-02 23:54:54 +04:00
|
|
|
return amend(ui, repo, *pats, **opts)
|
|
|
|
else:
|
2015-10-27 02:19:40 +03:00
|
|
|
badflags = [flag for flag in
|
|
|
|
['rebase', 'fixup'] if opts.get(flag, None)]
|
|
|
|
if badflags:
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort(_('--%s must be called with --amend') %
|
2015-10-27 02:19:40 +03:00
|
|
|
badflags[0])
|
|
|
|
|
2014-06-02 23:54:54 +04:00
|
|
|
return orig(ui, repo, *pats, **opts)
|
|
|
|
|
|
|
|
def amend(ui, repo, *pats, **opts):
|
2016-09-21 17:45:25 +03:00
|
|
|
'''amend the current changeset with more changes
|
2014-06-02 23:54:54 +04:00
|
|
|
'''
|
2015-04-07 23:52:59 +03:00
|
|
|
if obsolete.isenabled(repo, 'allnewcommands'):
|
|
|
|
msg = ('fbamend and evolve extension are incompatible, '
|
|
|
|
'fbamend deactivated.\n'
|
|
|
|
'You can either disable it globally:\n'
|
|
|
|
'- type `hg config --edit`\n'
|
|
|
|
'- drop the `fbamend=` line from the `[extensions]` section\n'
|
|
|
|
'or disable it for a specific repo:\n'
|
|
|
|
'- type `hg config --local --edit`\n'
|
2017-06-14 03:08:20 +03:00
|
|
|
'- add a `fbamend=!` line in the `[extensions]` section\n')
|
2015-04-07 23:52:59 +03:00
|
|
|
ui.write_err(msg)
|
2014-06-02 23:54:54 +04:00
|
|
|
rebase = opts.get('rebase')
|
|
|
|
|
2015-02-12 22:02:34 +03:00
|
|
|
if rebase and _histediting(repo):
|
|
|
|
# if a histedit is in flight, it's dangerous to remove old commits
|
|
|
|
hint = _('during histedit, use amend without --rebase')
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort('histedit in progress', hint=hint)
|
2015-02-12 22:02:34 +03:00
|
|
|
|
2015-10-24 03:00:56 +03:00
|
|
|
badflags = [flag for flag in
|
|
|
|
['rebase', 'fixup'] if opts.get(flag, None)]
|
|
|
|
if opts.get('interactive') and badflags:
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort(_('--interactive and --%s are mutually exclusive') %
|
2015-10-24 03:00:56 +03:00
|
|
|
badflags[0])
|
|
|
|
|
2015-02-12 22:02:34 +03:00
|
|
|
fixup = opts.get('fixup')
|
2014-06-02 23:54:54 +04:00
|
|
|
if fixup:
|
|
|
|
fixupamend(ui, repo)
|
|
|
|
return
|
|
|
|
|
|
|
|
old = repo['.']
|
|
|
|
if old.phase() == phases.public:
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort(_('cannot amend public changesets'))
|
2014-06-02 23:54:54 +04:00
|
|
|
if len(repo[None].parents()) > 1:
|
2016-01-08 05:30:24 +03:00
|
|
|
raise error.Abort(_('cannot amend while merging'))
|
2014-06-02 23:54:54 +04:00
|
|
|
|
|
|
|
haschildren = len(old.children()) > 0
|
|
|
|
|
2015-10-28 00:37:20 +03:00
|
|
|
opts['message'] = cmdutil.logmessage(ui, opts)
|
|
|
|
# Avoid further processing of any logfile. If such a file existed, its
|
|
|
|
# contents have been copied into opts['message'] by logmessage
|
|
|
|
opts['logfile'] = ''
|
|
|
|
|
2015-04-07 23:31:44 +03:00
|
|
|
if not opts.get('noeditmessage') and not opts.get('message'):
|
2014-06-02 23:54:54 +04:00
|
|
|
opts['message'] = old.description()
|
|
|
|
|
|
|
|
tempnode = []
|
2015-10-23 01:50:59 +03:00
|
|
|
commitdate = old.date() if not opts.get('date') else opts.get('date')
|
2014-06-02 23:54:54 +04:00
|
|
|
def commitfunc(ui, repo, message, match, opts):
|
|
|
|
e = cmdutil.commiteditor
|
|
|
|
noderesult = repo.commit(message,
|
|
|
|
old.user(),
|
2015-10-23 01:50:59 +03:00
|
|
|
commitdate,
|
2014-06-02 23:54:54 +04:00
|
|
|
match,
|
|
|
|
editor=e,
|
|
|
|
extra={})
|
|
|
|
|
|
|
|
# the temporary commit is the very first commit
|
|
|
|
if not tempnode:
|
|
|
|
tempnode.append(noderesult)
|
|
|
|
|
|
|
|
return noderesult
|
|
|
|
|
2015-05-10 06:22:31 +03:00
|
|
|
active = bmactive(repo)
|
2014-06-02 23:54:54 +04:00
|
|
|
oldbookmarks = old.bookmarks()
|
|
|
|
|
|
|
|
if haschildren:
|
|
|
|
def fakestrip(orig, ui, repo, *args, **kwargs):
|
|
|
|
if tempnode:
|
|
|
|
if tempnode[0]:
|
|
|
|
# don't strip everything, just the temp node
|
|
|
|
# this is very hacky
|
|
|
|
orig(ui, repo, tempnode[0], backup='none')
|
|
|
|
tempnode.pop()
|
|
|
|
else:
|
|
|
|
orig(ui, repo, *args, **kwargs)
|
|
|
|
extensions.wrapfunction(repair, 'strip', fakestrip)
|
|
|
|
|
2015-12-14 22:30:33 +03:00
|
|
|
tr = None
|
2015-08-04 19:10:50 +03:00
|
|
|
wlock = None
|
|
|
|
lock = None
|
|
|
|
try:
|
|
|
|
wlock = repo.wlock()
|
|
|
|
lock = repo.lock()
|
2015-10-24 03:00:56 +03:00
|
|
|
|
|
|
|
if opts.get('interactive'):
|
|
|
|
# Strip the interactive flag to avoid infinite recursive loop
|
|
|
|
opts.pop('interactive')
|
|
|
|
cmdutil.dorecord(ui, repo, amend, None, False,
|
|
|
|
cmdutil.recordfilter, *pats, **opts)
|
|
|
|
return
|
|
|
|
|
|
|
|
else:
|
|
|
|
node = cmdutil.amend(ui, repo, commitfunc, old, {}, pats, opts)
|
2015-08-04 19:10:50 +03:00
|
|
|
|
|
|
|
if node == old.node():
|
|
|
|
ui.status(_("nothing changed\n"))
|
2015-09-10 00:43:16 +03:00
|
|
|
return 0
|
2015-08-04 19:10:50 +03:00
|
|
|
|
|
|
|
if haschildren and not rebase:
|
2016-09-21 17:45:25 +03:00
|
|
|
msg = _("warning: the changeset's children were left behind\n")
|
2015-08-04 19:10:50 +03:00
|
|
|
if _histediting(repo):
|
|
|
|
ui.warn(msg)
|
|
|
|
ui.status(_('(this is okay since a histedit is in progress)\n'))
|
|
|
|
else:
|
|
|
|
_usereducation(ui)
|
|
|
|
ui.warn(msg)
|
2017-01-09 22:09:02 +03:00
|
|
|
ui.status(_("(use 'hg rebase --restack' (alias: 'hg restack') "
|
|
|
|
"to rebase them)\n"))
|
2015-08-04 19:10:50 +03:00
|
|
|
|
|
|
|
newbookmarks = repo._bookmarks
|
|
|
|
|
|
|
|
# move old bookmarks to new node
|
|
|
|
for bm in oldbookmarks:
|
|
|
|
newbookmarks[bm] = node
|
|
|
|
|
2016-10-25 21:10:47 +03:00
|
|
|
userestack = ui.configbool('fbamend', 'userestack')
|
|
|
|
if not _histediting(repo) and not userestack:
|
2015-08-04 19:10:50 +03:00
|
|
|
preamendname = _preamendname(repo, node)
|
|
|
|
if haschildren:
|
|
|
|
newbookmarks[preamendname] = old.node()
|
|
|
|
elif not active:
|
|
|
|
# update bookmark if it isn't based on the active bookmark name
|
|
|
|
oldname = _preamendname(repo, old.node())
|
|
|
|
if oldname in repo._bookmarks:
|
|
|
|
newbookmarks[preamendname] = repo._bookmarks[oldname]
|
|
|
|
del newbookmarks[oldname]
|
|
|
|
|
2015-12-14 22:30:33 +03:00
|
|
|
tr = repo.transaction('fixupamend')
|
|
|
|
newbookmarks.recordchange(tr)
|
|
|
|
tr.close()
|
2015-08-04 19:10:50 +03:00
|
|
|
|
|
|
|
if rebase and haschildren:
|
|
|
|
fixupamend(ui, repo)
|
|
|
|
finally:
|
2015-12-14 22:30:33 +03:00
|
|
|
lockmod.release(wlock, lock, tr)
|
2014-06-02 23:54:54 +04:00
|
|
|
|
|
|
|
def fixupamend(ui, repo):
|
2016-09-21 17:45:25 +03:00
|
|
|
"""rebases any children found on the preamend changset and strips the
|
|
|
|
preamend changset
|
2014-06-02 23:54:54 +04:00
|
|
|
"""
|
2015-08-04 19:10:50 +03:00
|
|
|
wlock = None
|
|
|
|
lock = None
|
2015-12-14 22:30:33 +03:00
|
|
|
tr = None
|
2015-08-04 19:10:50 +03:00
|
|
|
try:
|
|
|
|
wlock = repo.wlock()
|
|
|
|
lock = repo.lock()
|
|
|
|
current = repo['.']
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2016-10-25 21:10:47 +03:00
|
|
|
# Use obsolescence information to fix up the amend instead of relying
|
|
|
|
# on the preamend bookmark if the user enables this feature.
|
|
|
|
if ui.configbool('fbamend', 'userestack'):
|
|
|
|
with repo.transaction('fixupamend') as tr:
|
|
|
|
try:
|
2017-06-14 03:09:16 +03:00
|
|
|
common.restackonce(ui, repo, current.rev())
|
2016-10-25 21:10:47 +03:00
|
|
|
except error.InterventionRequired:
|
|
|
|
tr.close()
|
|
|
|
raise
|
2017-03-12 23:11:47 +03:00
|
|
|
# There's a subtly to rebase transaction close where the rebasestate
|
|
|
|
# file will be written to disk, even if it had already been unlinked
|
|
|
|
# by the rebase logic (because the file generator was already on the
|
|
|
|
# transaction). Until we fix it in core, let's manually unlink the
|
|
|
|
# rebasestate so the rebase isn't left pending.
|
2017-03-14 06:51:37 +03:00
|
|
|
util.unlinkpath(repo.vfs.join("rebasestate"), ignoremissing=True)
|
2017-03-12 23:11:47 +03:00
|
|
|
return
|
2016-10-25 21:10:47 +03:00
|
|
|
|
|
|
|
preamendname = _preamendname(repo, current.node())
|
2015-08-04 19:10:50 +03:00
|
|
|
if not preamendname in repo._bookmarks:
|
2016-01-11 21:19:22 +03:00
|
|
|
raise error.Abort(_('no bookmark %s') % preamendname,
|
2015-08-04 19:10:50 +03:00
|
|
|
hint=_('check if your bookmark is active'))
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
old = repo[preamendname]
|
2016-06-17 15:25:32 +03:00
|
|
|
if old == current:
|
2016-09-21 17:45:25 +03:00
|
|
|
hint = _('please examine smartlog and rebase your changsets '
|
|
|
|
'manually')
|
2016-06-17 15:25:32 +03:00
|
|
|
err = _('cannot automatically determine what to rebase '
|
2016-09-21 17:45:25 +03:00
|
|
|
'because bookmark "%s" points to the current changset') % \
|
2016-06-17 15:25:32 +03:00
|
|
|
preamendname
|
|
|
|
raise error.Abort(err, hint=hint)
|
2015-08-04 19:10:50 +03:00
|
|
|
oldbookmarks = old.bookmarks()
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2016-06-17 15:25:32 +03:00
|
|
|
ui.status(_("rebasing the children of %s\n") % (preamendname))
|
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
active = bmactive(repo)
|
|
|
|
opts = {
|
|
|
|
'rev' : [str(c.rev()) for c in old.descendants()],
|
2016-03-10 04:53:11 +03:00
|
|
|
'dest' : current.rev()
|
2015-08-04 19:10:50 +03:00
|
|
|
}
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
if opts['rev'] and opts['rev'][0]:
|
2015-09-25 05:46:12 +03:00
|
|
|
rebasemod.rebase(ui, repo, **opts)
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
for bookmark in oldbookmarks:
|
|
|
|
repo._bookmarks.pop(bookmark)
|
2015-07-08 20:33:04 +03:00
|
|
|
|
2015-12-14 22:30:33 +03:00
|
|
|
tr = repo.transaction('fixupamend')
|
|
|
|
repo._bookmarks.recordchange(tr)
|
2015-07-08 20:33:04 +03:00
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
if obsolete.isenabled(repo, obsolete.createmarkersopt):
|
2016-01-08 05:30:24 +03:00
|
|
|
# clean up the original node if inhibit kept it alive
|
|
|
|
if not old.obsolete():
|
2015-08-04 19:10:50 +03:00
|
|
|
obsolete.createmarkers(repo, [(old,())])
|
2016-01-08 05:30:24 +03:00
|
|
|
tr.close()
|
2015-08-04 19:10:50 +03:00
|
|
|
else:
|
2016-01-08 05:30:24 +03:00
|
|
|
tr.close()
|
|
|
|
repair.strip(ui, repo, old.node(), topic='preamend-backup')
|
2014-06-02 23:54:54 +04:00
|
|
|
|
2015-08-04 19:10:50 +03:00
|
|
|
merge.update(repo, current.node(), False, True, False)
|
|
|
|
if active:
|
|
|
|
bmactivate(repo, active)
|
|
|
|
finally:
|
2015-12-14 22:30:33 +03:00
|
|
|
lockmod.release(wlock, lock, tr)
|
2015-02-12 12:26:20 +03:00
|
|
|
|
2017-02-02 02:14:17 +03:00
|
|
|
def wrapsplit(orig, ui, repo, *args, **opts):
|
2017-01-20 11:24:45 +03:00
|
|
|
"""Automatically rebase unstable descendants after split."""
|
|
|
|
# Find the rev number of the changeset to split. This needs to happen
|
|
|
|
# before splitting in case the input revset is relative to the working
|
|
|
|
# copy parent, since `hg split` may update to a new changeset.
|
2017-02-02 02:14:17 +03:00
|
|
|
revs = (list(args) + opts.get('rev', [])) or ['.']
|
2017-01-20 11:24:45 +03:00
|
|
|
rev = scmutil.revsingle(repo, revs[0]).rev()
|
|
|
|
torebase = repo.revs('descendants(%d) - (%d)', rev, rev)
|
|
|
|
|
|
|
|
# Perform split.
|
2017-02-02 02:14:17 +03:00
|
|
|
ret = orig(ui, repo, *args, **opts)
|
|
|
|
|
|
|
|
# Return early if split failed.
|
|
|
|
if ret:
|
|
|
|
return ret
|
2017-01-20 11:24:45 +03:00
|
|
|
|
|
|
|
# Fix up stack.
|
|
|
|
if not opts['norebase'] and torebase:
|
2017-04-20 20:58:50 +03:00
|
|
|
with repo.wlock():
|
|
|
|
with repo.lock():
|
|
|
|
with repo.transaction('splitrebase'):
|
|
|
|
top = repo.revs('allsuccessors(%d)', rev).last()
|
2017-06-14 03:09:16 +03:00
|
|
|
common.restackonce(ui, repo, top)
|
2017-04-20 20:58:50 +03:00
|
|
|
# The rebasestate file is incorrectly left behind, so cleanup.
|
|
|
|
# See the earlier comment on util.unlinkpath for more details.
|
|
|
|
util.unlinkpath(repo.vfs.join("rebasestate"),
|
|
|
|
ignoremissing=True)
|
2017-01-20 11:24:45 +03:00
|
|
|
|
2017-02-02 02:14:17 +03:00
|
|
|
# Fix up bookmarks, if any.
|
|
|
|
_fixbookmarks(repo, [rev])
|
|
|
|
|
2017-01-20 11:24:45 +03:00
|
|
|
return ret
|
|
|
|
|
2017-02-02 02:14:17 +03:00
|
|
|
def wrapfold(orig, ui, repo, *args, **opts):
|
2017-01-20 11:24:45 +03:00
|
|
|
"""Automatically rebase unstable descendants after fold."""
|
|
|
|
# Find the rev numbers of the changesets that will be folded. This needs
|
|
|
|
# to happen before folding in case the input revset is relative to the
|
|
|
|
# working copy parent, since `hg fold` may update to a new changeset.
|
2017-02-02 02:14:17 +03:00
|
|
|
revs = list(args) + opts.get('rev', [])
|
2017-01-20 11:24:45 +03:00
|
|
|
revs = scmutil.revrange(repo, revs)
|
|
|
|
if not opts['exact']:
|
|
|
|
revs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
|
|
|
|
torebase = repo.revs('descendants(%ld) - (%ld)', revs, revs)
|
|
|
|
|
|
|
|
# Perform fold.
|
2017-02-02 02:14:17 +03:00
|
|
|
ret = orig(ui, repo, *args, **opts)
|
|
|
|
|
|
|
|
# Return early if fold failed.
|
|
|
|
if ret:
|
|
|
|
return ret
|
2017-01-20 11:24:45 +03:00
|
|
|
|
|
|
|
# Fix up stack.
|
2017-04-20 20:58:50 +03:00
|
|
|
with repo.wlock():
|
|
|
|
with repo.lock():
|
|
|
|
with repo.transaction('foldrebase'):
|
|
|
|
if not opts['norebase'] and torebase:
|
|
|
|
folded = repo.revs('allsuccessors(%ld)', revs).last()
|
2017-06-14 03:09:16 +03:00
|
|
|
common.restackonce(ui, repo, folded)
|
2017-04-20 20:58:50 +03:00
|
|
|
else:
|
|
|
|
# If there's nothing to rebase, deinhibit the folded
|
|
|
|
# changesets so that they get correctly marked as
|
|
|
|
# hidden if needed. For some reason inhibit's
|
|
|
|
# post-transaction hook misses this changeset.
|
|
|
|
visible = repo.unfiltered().revs('(%ld) - hidden()', revs)
|
2017-06-14 03:09:16 +03:00
|
|
|
common.deinhibit(repo, (repo[r] for r in visible))
|
2017-04-20 20:58:50 +03:00
|
|
|
# The rebasestate file is incorrectly left behind, so cleanup.
|
|
|
|
# See the earlier comment on util.unlinkpath for more details.
|
|
|
|
util.unlinkpath(repo.vfs.join("rebasestate"), ignoremissing=True)
|
2017-01-20 11:24:45 +03:00
|
|
|
|
2017-02-02 02:14:17 +03:00
|
|
|
# Fix up bookmarks, if any.
|
|
|
|
_fixbookmarks(repo, revs)
|
|
|
|
|
2017-01-20 11:24:45 +03:00
|
|
|
return ret
|
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
def wraprebase(orig, ui, repo, **opts):
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
"""Wrapper around `hg rebase` adding the `--restack` option, which rebases
|
2016-10-14 21:05:53 +03:00
|
|
|
all "unstable" descendants of an obsolete changeset onto the latest
|
|
|
|
version of that changeset. This is similar to (and intended as a
|
|
|
|
replacement for) the `hg evolve --all` command.
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
"""
|
2016-11-03 21:11:39 +03:00
|
|
|
if opts['restack']:
|
2017-01-11 00:53:43 +03:00
|
|
|
# We can't abort if --dest is passed because some extensions
|
|
|
|
# (namely remotenames) will automatically add this flag.
|
|
|
|
# So just silently drop it instead.
|
|
|
|
opts.pop('dest', None)
|
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
if opts['rev']:
|
|
|
|
raise error.Abort(_("cannot use both --rev and --restack"))
|
|
|
|
if opts['source']:
|
|
|
|
raise error.Abort(_("cannot use both --source and --restack"))
|
|
|
|
if opts['base']:
|
|
|
|
raise error.Abort(_("cannot use both --base and --restack"))
|
|
|
|
if opts['abort']:
|
|
|
|
raise error.Abort(_("cannot use both --abort and --restack"))
|
|
|
|
if opts['continue']:
|
|
|
|
raise error.Abort(_("cannot use both --continue and --restack"))
|
2017-01-26 02:48:12 +03:00
|
|
|
|
|
|
|
# The --hidden option is handled at a higher level, so instead of
|
|
|
|
# checking for it directly we have to check whether the repo
|
|
|
|
# is unfiltered.
|
|
|
|
if repo == repo.unfiltered():
|
|
|
|
raise error.Abort(_("cannot use both --hidden and --restack"))
|
|
|
|
|
2017-06-14 03:09:34 +03:00
|
|
|
return restack.restack(ui, repo, opts)
|
Add hg rebase --restack
Summary:
This change adds a `--restack` option to `hg rebase`. When invoked, the command will rebase all descendants of precursors of the current changeset onto the current changeset. This is similar to the behavior of `hg evolve --all`, except it only handles unstable changesets, and not other issues that can arise from shared mutable history such as divergence or bumping.
I've been playing around with some of the more advanced features (such as allowing the command to be run from anywhere in the old stack or new stack, as well as allowing the user to specify the number of changesets to rebase), but I wanted to upload the most simple iteration of this command for feedback.
Test Plan:
See unit tests for complete commands.
1. Create a stack of commits.
2. Somewhere in the middle of the stack, amend a commit, potentially several times.
3. Run `hg rebase --restack`.
4. The top half of the stack should be rebased onto the amended commit, and the preamend bookmark should be gone.
Reviewers: #sourcecontrol, durham
Reviewed By: durham
Subscribers: rmcelroy, quark, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D3972103
Tasks: 13651947
Signature: t1:3972103:1476230834:8f77eac4e8d8681dd9f8125747c1ff75c8da1ad8
2016-10-12 03:41:07 +03:00
|
|
|
|
fbamend: make inhibit hook fire after rebase
Summary:
Recently @rmcelroy discovered that attempting to rebase a single commit in the middle of a stack results in the rest of the stack being marked as unstable. See https://fb.facebook.com/groups/sourcecontrol/permalink/1207767375939547/ for full example.
It turns out that the inhibit extension's post-transaction hook that would ordinarily inhibit the rebased (and thus obsolete) commit, and thereby hide the instability, was not firing in this case. This was similar to a previous problem with `hg next --rebase` wherein `--continue`'ing a rebase with conflicts would result in visible instability for the same reason. In both cases, the problem appears to be that `rebase` doesn't actually create a transaction, so of course the post-transaction hook doesn't fire.
The solution for `hg next --rebase` was to add a (nearly) empty transaction after the rebase call to trigger the hook. This diff just makes this the default behavior for `hg rebase` so that the hook is always called.
Test Plan:
See new test file. Basically, create a situation like:
```
o e5d56d debugbuilddag
| r3
|
| o c175ba debugbuilddag
| | r2
| |
| o 220949 debugbuilddag
|/ r1
|
o 1ad88b debugbuilddag
r0
```
Perform `hg rebase -r 1 -d 3`, which rebases commit "r1" onto "r3", which would ordinarily make "r2" unstable. Instead, the result should be as below, with no visible instability because "r1" is inhibited.
```
o 738e8e debugbuilddag
| r1
|
o e5d56d debugbuilddag
| r3
|
| o c175ba debugbuilddag
| | r2
| |
| x 220949 (Rebased as 738e8e) debugbuilddag
|/ r1
|
o 1ad88b debugbuilddag
r0
```
Reviewers: rmcelroy, #mercurial, durham
Reviewed By: durham
Subscribers: mjpieters, rmcelroy
Differential Revision: https://phabricator.intern.facebook.com/D4491870
Tasks: 15697758
Signature: t1:4491870:1486033128:45b8e9a72af1e88ab78484ddef47a788d1aca7b5
2017-02-02 22:49:44 +03:00
|
|
|
# We need to create a transaction to ensure that the inhibit extension's
|
|
|
|
# post-transaction hook is called after the rebase is finished. This hook
|
|
|
|
# is responsible for inhibiting visible obsolete (suspended) changesets,
|
|
|
|
# which may be created if the rebased commits have descendants that were
|
|
|
|
# not rebased. To be less invasive, create a short transaction after the
|
|
|
|
# rebase call instead of wrapping the call itself in a transaction.
|
2017-04-20 20:58:50 +03:00
|
|
|
with repo.wlock():
|
|
|
|
with repo.lock():
|
|
|
|
ret = orig(ui, repo, **opts)
|
|
|
|
with repo.transaction('rebase'):
|
|
|
|
# The rebase command will cause the rebased commits to still be
|
|
|
|
# cached as 'visible', even if the entire stack has been
|
|
|
|
# rebased and everything is obsolete. We need to manaully clear
|
|
|
|
# the cached values to that the post-transaction callback will
|
|
|
|
# work correctly.
|
|
|
|
repo.invalidatevolatilesets()
|
|
|
|
return ret
|
2016-11-16 05:46:52 +03:00
|
|
|
|
2016-11-03 21:11:39 +03:00
|
|
|
return orig(ui, repo, **opts)
|
2016-10-25 21:10:47 +03:00
|
|
|
|
2015-02-12 13:16:28 +03:00
|
|
|
def _preamendname(repo, node):
|
|
|
|
suffix = '.preamend'
|
2015-05-10 06:22:31 +03:00
|
|
|
name = bmactive(repo)
|
2015-02-12 13:16:28 +03:00
|
|
|
if not name:
|
2015-02-13 07:43:29 +03:00
|
|
|
name = hex(node)[:12]
|
2015-02-12 13:16:28 +03:00
|
|
|
return name + suffix
|
|
|
|
|
2015-02-12 22:02:34 +03:00
|
|
|
def _histediting(repo):
|
|
|
|
return repo.vfs.exists('histedit-state')
|
|
|
|
|
2015-02-12 12:26:20 +03:00
|
|
|
def _usereducation(ui):
|
|
|
|
"""
|
|
|
|
You can print out a message to the user here
|
|
|
|
"""
|
2015-04-17 20:17:23 +03:00
|
|
|
education = ui.config('fbamend', 'education')
|
|
|
|
if education:
|
|
|
|
ui.warn(education + "\n")
|
2015-05-10 06:22:31 +03:00
|
|
|
|
2017-02-02 02:14:17 +03:00
|
|
|
def _fixbookmarks(repo, revs):
|
|
|
|
"""Make any bookmarks pointing to the given revisions point to the
|
|
|
|
latest version of each respective revision.
|
|
|
|
"""
|
|
|
|
repo = repo.unfiltered()
|
|
|
|
cl = repo.changelog
|
2017-04-20 20:58:50 +03:00
|
|
|
with repo.wlock():
|
|
|
|
with repo.lock():
|
|
|
|
with repo.transaction('movebookmarks') as tr:
|
|
|
|
for rev in revs:
|
2017-06-14 03:09:34 +03:00
|
|
|
latest = cl.node(common.latest(repo, rev))
|
2017-04-20 20:58:50 +03:00
|
|
|
for bm in repo.nodebookmarks(cl.node(rev)):
|
|
|
|
repo._bookmarks[bm] = latest
|
|
|
|
repo._bookmarks.recordchange(tr)
|
2017-02-02 02:14:17 +03:00
|
|
|
|
2015-05-10 06:22:31 +03:00
|
|
|
### bookmarks api compatibility layer ###
|
|
|
|
def bmactivate(repo, mark):
|
|
|
|
try:
|
|
|
|
return bookmarks.activate(repo, mark)
|
|
|
|
except AttributeError:
|
|
|
|
return bookmarks.setcurrent(repo, mark)
|
|
|
|
|
|
|
|
def bmactive(repo):
|
|
|
|
try:
|
|
|
|
return repo._activebookmark
|
|
|
|
except AttributeError:
|
|
|
|
return repo._bookmarkcurrent
|