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
новой версии. Он мог бы даже обрабатывать последовательность таких "подбриков", если бы вы написали это правильно. Если вам нужна помощь, я могу попытаться ударить ее.