ветка git rebase со всеми ответвлениями - PullRequest
17 голосов
/ 28 апреля 2010

возможно ли перебазировать ветку со всеми ее ветками в git?

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

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

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

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

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

но я получаю:

* master
*
* (same changeset as featureA-finished)
* (changed/reworded)
| * featureA-finished
|.* (original commit i wanted to edit)
* origin/master

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

Ответы [ 4 ]

5 голосов
/ 16 июня 2010

Согласно объектной модели git , если вы изменяете только метаданные коммита (т.е. сообщение коммита), но не базовые данные ("дерево (и)"), содержащиеся в нем, тогда это хеш дерева останется без изменений.

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

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

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

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

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

Редактировать : Вы можете получить адрес электронной почты автора и метку времени, используя:

$ git log --graph --all --pretty=format:"%h %ae:%ci"
* 53ca31a robert.meerman@gmail.com:2010-06-16 13:50:12 +0100
* 03dda75 robert.meerman@gmail.com:2010-06-16 13:50:11 +0100
| * a8bb03a robert.meerman@gmail.com:2010-06-16 13:49:46 +0100
| * b93e59d robert.meerman@gmail.com:2010-06-16 13:49:44 +0100
|/
* d4214a2 robert.meerman@gmail.com:2010-06-16 13:49:41 +0100

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

$ git branch --contains 03dda75
* testbranch

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

2 голосов
/ 27 июня 2011

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

2 голосов
/ 28 апреля 2010

Я не уверен, как именно вы туда попали, но:

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

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

1 голос
/ 15 июня 2010

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

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

...