Git ветвь переадресации со всеми дочерними частями

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

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

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

теперь я хочу rebase -i master на origin/master, чтобы изменить/переделать commit 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

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

Ответы

Ответ 1

В соответствии с git Object Model, если вы изменяете только метаданные коммита (т.е. сообщение фиксации), но не лежащие в основе данные ( "дерево (деревья)" ), содержащиеся в нем, тогда он хеш дерева останется неизменным.

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

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

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

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

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

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

$ 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 branch -f (same changeset as featureA-finished)

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

Ответ 3

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

Ответ 4

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

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