2010-04-28 2 views
15

Можно ли переделать ветку со всеми ее дочерними частями в git?git rebase branch со всеми дочерними элементами

Я часто использую ветви в качестве быстрых/изменяемых тегов для обозначения определенных коммитов.

* master 
* 
* featureA-finished 
* 
* origin/master 

теперь я хочу rebase -imaster на origin/master, чтобы изменить/перефразировать фиксации featureA-finished^

после git rebase -i --onto origin/master origin/master master, я в основном хочу история быть:

* master 
* 
* featureA-finished 
* (changed/reworded) 
* origin/master 

но то, что я получаю :

есть способ обойти это, или я застрял с воссозданием ветвей на новых переборках?

+0

Вы можете вместо ветвей использовать 'git notes' для отметки ваших коммитов - они автоматически копируются во время переустановок, я полагаю. (Это новая функция, поэтому вам понадобится последняя версия). Http://www.kernel.org/pub/software/scm/git/docs/git-notes.html – Cascabel

+0

См. Также [как я могу переустановить целая часть истории - несколько ветвей с некоторыми связями между ними, возникающими в результате слияния] (http://stackoverflow.com/a/9706495/94687). Неприятной частью этого решения является необходимость сброса ссылок на ветку темы на новые переустановленные фиксации впоследствии. –

ответ

2

Я не уверен, как именно там у вас, но:

git branch -f (same changeset as featureA-finished) 

должно быть достаточно, чтобы сбросить featureA-finished ветвь с правой историей.

+0

да, это то, что я имел в виду с »воссозданием ветвей на новых перезаряженных коммитах». Я знаю, что это возможно, но это становится очень громоздким для трех ветвей уже – knittl

+0

@knittl: interesting. Более подробная диаграмма журнала этих ветвей до и после может помочь здесь. – VonC

+0

просто представьте себе тот же график с 15 коммитами, каждая вторая фиксация является функциейА-закончена, featureB-finished, featureC-finished и т. Д. – knittl

1

Что я бы посоветовал сначала переупаковать featureA-finished на origin/master. Затем сделайте шаг перезаписи. После этого rebase master на featureA-finished. Это даст вам конечный результат, который вы хотите.

Обратите внимание, что вам нужно будет использовать -i на обеих скидках и, возможно, придется удалить все коммиты с оригинала featureA-finshed вниз во второй перестановке. Если бы вы захотели, вы могли бы написать сценарий, который бы устранил это, сохранив промежуточную ветку и используя это как базу для переустановки --onto новой версии. Он мог бы даже обрабатывать последовательность таких «подбриков», если бы вы написали это правильно. Если вам нужна помощь, я могу попытаться ударить ее.

5

В соответствии с git's Object Model, если вы только изменяете метаданные фиксации (т. Е. Сообщение фиксации), но не лежащие в нем базовые данные («дерево (деревья)»), то это хеш дерева останется неизменным.

Помимо редактирования сообщения о фиксации, вы также выполняете rebase, который будет изменять хеши дерева каждой фиксации в вашей истории, поскольку любые изменения, сделанные с origin/master, будут влиять на файлы в вашей переписанной истории: это означает некоторые из файлов (капли), которые ваша фиксация указывает на изменение.

Таким образом, нет пуленепробиваемого способа делать то, что вы хотите.

Таким образом, редактирование фиксации с помощью rebase -i обычно не изменяет метку времени и автора фиксации, поэтому вы можете использовать это, чтобы однозначно идентифицировать свои фиксации до и после операции переадресации.

Вам необходимо написать сценарий, который записывает все начальные точки ветвления в отношении этого идентификатора «timestamp: author» перед выполнением переустановки, а затем найдите переписанные фиксации с тем же идентификатором «timestamp: author» и переустановите ветвь на нем.

К сожалению, у меня нет времени, чтобы попробовать написать этот скрипт самостоятельно, поэтому я могу только пожелать вам удачи!

Edit: Вы можете получить адрес электронной почты автора и метку времени с помощью:

$ git log --graph --all --pretty=format:"%h %ae:%ci" 
* 53ca31a [email protected]:2010-06-16 13:50:12 +0100 
* 03dda75 [email protected]:2010-06-16 13:50:11 +0100 
| * a8bb03a [email protected]:2010-06-16 13:49:46 +0100 
| * b93e59d [email protected]:2010-06-16 13:49:44 +0100 
|/ 
* d4214a2 [email protected]:2010-06-16 13:49:41 +0100 

И вы можете получить список филиалов для каждого из них на основе их фиксации хэша:

$ git branch --contains 03dda75 
* testbranch 

Следите за несколькими ветвями за фиксацию, общий предок d4214a2 принадлежит к обоим ветвям!

2

похоже, что эта функция медленно проникает в git. rebase получит опцию --rebase-refs, которая будет выполнять именно то, что мой первоначальный ответ был задан. для предлагаемой серии патчей см. резьбу rebase: command "ref" and options --rewrite-{refs,heads,tags} на gmane.

+0

Жаль, что это, похоже, не попало в Git: я не видел такой функции в текущая документация (manpage) для git-rebase! (ГИТ-1.7.9.3) –

Смежные вопросы