Можете ли вы закрыть филиал Mercurial, не обновляясь сначала?
Я знаю, что вы можете закрыть ветвь Mercurial с помощью:
hg update rev-number
hg commit --close-branch -m "Closing branch."
Однако некоторые из репозиториев я работаю с довольно большим, и после того, как многие годы назад я обнаружил свободную ветку, которую я хочу закрыть, обновление для нее сначала может занять много минут (если не часов), только для того, чтобы сделать одно коммит а затем обновить исходную версию, над которой я работал (больше минут, если не часов).
Итак, мой вопрос, есть ли способ закрыть ветвь Mercurial, не обновляя сначала рабочий каталог до ревизии ветки?
Ответы
Ответ 1
Да, вы можете, но это нигде не документировано. Я использовал эту технику в течение длительного времени, не волнуйтесь, это безопасно.
Вместо обновления вы можете выпустить следующие команды
hg debugsetparent <revision>
hg branch <branchOfRevision>
Обратите внимание, что порядок важен. Это заставит ваше репо подумать, что оно находится в новой редакции, а все ваши файлы от исходного. После этого вы можете использовать фиксацию --close-branch
, но используйте параметр -X *
, чтобы сделать пустую фиксацию.
hg commit --close-branch -X * -m "Closing branch."
Теперь просто вернитесь к предыдущей голове, как будто ничего не произошло.
hg debugsetparent <InitialRevision>
hg branch <branchOfInitialRevision>
Наконец, если у вас есть субрепозиции, вы можете временно переименовать файл .hgsub
, прежде чем совершать --close-branch
, а затем переименовать обратно.
Ответ 2
Спасибо Винсу за подход. Я реализовал это как Python script - это была немного больше работы, чем я ожидал, поэтому, надеюсь, это сэкономит время на некоторое время. Протестировано на Windows 8.1 с помощью TortoiseHg 3.3 и Python 2.7.9.
Обратная связь приветствуется, возможно, это связано с некоторой утонченностью, особенно в отношении обработки ошибок.
#!/usr/bin/python
from subprocess import check_output
def close_branch( branch, message ):
if not message:
message = 'Closing branch "{}"'.format( branch )
print( 'Closing branch "{}"'.format( branch ) )
try:
check_output( 'hg debugsetparent ' + branch )
check_output( 'hg branch ' + branch )
check_output( 'hg commit --close-branch -X * -m "' + message + '"' )
except:
print( 'Failed to close branch.' )
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('branch', help='branch name(s)', nargs = '+' )
parser.add_argument('-m', '--message', help='message (defaults to "Closing branch <branch name>")' )
args = parser.parse_args()
status = check_output( 'hg status' )
if len(status) > 0:
print( 'Do not use this script with local changes. Commit/revert changes and try again' )
exit(1)
# Cache initial revision and branch.
initial_revision = check_output( 'hg id -i -b' ).split()
# print( 'Using: ' + initial_revision[0].decode("utf-8") )
for branch in args.branch:
close_branch( branch, args.message )
# Return to original changeset
check_output( 'hg debugsetparent ' + initial_revision[0].decode("utf-8") )
check_output( 'hg branch ' + initial_revision[1].decode("utf-8") )
if __name__ == '__main__':
main()
Ответ 3
Mercurial 4.8 и выше поставляется с расширенным ядром расширения ядра, который обеспечивает эту функциональность:
hg close-head <revision>
Из справки:
Это эквивалентно проверке каждой ревизии в чистом дереве и запуску "hg commit --close-branch", за исключением того, что она не меняет рабочий каталог.
На данный момент вам нужно явно включить это расширение в вашем [HGRC][]
:
[extensions]
closehead =