Когда git перебазирует две ветви с некоторой общей историей, есть ли простой способ сохранить общую историю общей? - PullRequest
19 голосов
/ 12 апреля 2011

Предположим, у нас есть следующий граф ревизий:

A-X-Z--B
     \
      \-C

с A, предшествующим как B, так и C. Далее предположим, что я перебазирую A из восходящего потока, создавая новый коммит A *, а затем перебазирую оба B и C в A *. Полученный график изменений выглядит следующим образом:

A*-X'-Z'-B
 \
  \-X"-Z"-C

Обратите внимание, что общая история больше не доступна. Есть ли простой способ исправить это, кроме, скажем, перебазирования B, а затем явного переброса C на Z '. Другими словами, есть ли лучший способ автоматически перебазировать несколько веток одновременно, чтобы сохранить общую историю? Просто немного неловко, когда приходится либо искусственно размещать тег в точке разделения, либо вручную проверять график, чтобы выяснить sha1 коммита, на который нужно перебазировать C, чтобы сохранить общую историю, не говоря уже об открытии возможности ошибок, тем более что мне приходится делать это каждый раз, когда я перезагружаюсь, пока не проверю изменения в ветке upstream.

Ответы [ 2 ]

16 голосов
/ 12 апреля 2011
git rebase --committer-date-is-author-date --preserve-merges --onto A* A C
git rebase --committer-date-is-author-date --preserve-merges --onto A* A B

При этом общие коммиты должны иметь одинаковый sha1 и любые слияния. Сохранение слияний в этом случае не требуется, но станет проблемой с менее тривиальной историей.

Чтобы сделать это для всех ветвей, которые содержат A в своей истории, выполните:

git branch --contains A | xargs -n 1 git rebase --committer-date-is-author-date --preserve-merges --onto A* A 

Надеюсь, это поможет.

UPDATE:

Это может быть более чистый синтаксис:

for branch in $(git branch --contains A); do git rebase --committer-date-is-author-date --preserve-merges --onto A* A $branch; done
2 голосов
/ 14 марта 2012

Проблема в общем случае

Меня беспокоила похожая проблема: перебазирование целой подистории - нескольких ветвей, с некоторыми связями между ними в результате слияния:

A--B-B2-B3 <--topicB
\   /
 \-C-C2-C3 <--topicC

Если я запускаю несколько git rebase последовательно (для topicB и topicC), то я сомневаюсь, что слияния между ветвями могут быть сохранены правильно.Поэтому мне нужно перебазировать все ветви сразу , надеясь, что это правильно восстановит слияния между ними.

"Решение", которое работало в конкретном подслучае

В моем случае мне повезло, что topicC был фактически объединен с topicB:

A-B-----------B2-B3 <--topicB
   \         /
    \-C-C2-C3 <--topicC

, поэтому, чтобы перебазировать всю подисторию, я мог просто запустить

git rebase -p A topicB --onto A*

(гдеA* - это новая база, а не A, как в вашем вопросе; topicB - это имя ветви, которое первоначально указывало бы на старый коммит B3 и на переписанный коммит B3' впоследствии; -p - этокороткое имя для опции --preserve-merges), получая историю, например:

A-B-----------B2-B3
   \         /
    \-C-C2-C3 <--topicC

A*-B'-------------B2'-B3' <--topicB
    \            /
     \-C'-C2'-C3'

, а затем сбрасывает все оставшиеся ссылки веток (и теги) на новые соответствующие коммиты (в новой подистории), например,

git branch -f topicC C3'

Это сработало:

A*-B'-------------B2'-B3' <--topicB
    \            /
     \-C'-C2'-C3' <--topicC

(Перемещение ссылок и тегов ветки можно было бы сделать с помощью скрипта .)

"Решение"для общего случая, вдохновленного этим конкретным

Если topicC не было объединено вo topicB, я мог бы создать фальшивый топ-коммит, чтобы объединить все ветви, которые я хочу перебазировать, например:

git checkout -b fake topicB
git merge -s ours topicC

, а затем перебазировать его таким образом:

git rebase -p A fake --onto A*

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

Другие ответы

Я считаю, что другой ответ с --committer-date-is-author-date также хорош и разумен,но в моем опыте работы с Git у меня не было этой идеи, и я решил проблему сохранения общего доступа к общей истории после перебазирования, как я описал в своем дополнительном ответе здесь.

...