Как сделать две ветки git (с общей историей) связанными друг с другом после ребазирования одной из них? - PullRequest
0 голосов
/ 08 июля 2020

Я думаю, что мой заголовок недостаточно ясен, поэтому опишу проблему:

В моем проекте git у меня есть 3 ветки: master, b1 и b2 . Вот дерево истории:

 A---B---C  master
          \
           D---E---F  b1
                    \
                     G---H---I  b2

Предположим, я хочу перебазировать ветку b1 и отредактировать фиксацию E. После перебазирования коммиты E и F будут заменены новыми коммитами E' и F' с разными SHA фиксации. Следовательно, история в b1 будет отличаться от истории в b2:

 A---B---C  master
           \
             D---E'---F'  b1
                     
 A---B---C---D---E---F---G---H---I  b2

Итак, мой вопрос: как убедиться, что b2 следует за b1 (автоматически получает тот же новый фиксируется как b1) после перенастройки b1, чтобы их соответствующие истории оставались согласованными.

Ответы [ 3 ]

1 голос
/ 09 июля 2020

Если у вас есть только две ветки с линейной историей, как на диаграмме:

Я бы перебазировал b2 вместо b1:

 A---B---C  master
          \
           D---E'---F'
                     \
                      G'---H'---I'  b2

, а затем обновил b1:

git branch -f b1 F'

Ответ @ Han-KwangNienhuys совершенно верен, и вы можете применить его, если вам нужно обновить b2, когда b1 уже был переписан.

1 голос
/ 08 июля 2020

После вашего первого перебазирования это не это:

 A---B---C  master
           \
             D---E'---F'  b1
                     
 A---B---C---D---E---F---G---H---I  b2

, а скорее это:

A---B---C  master
         \
          D---Ea---F'  b1
           \      
            E---F---G---H---I  b2

Здесь Ea означает исправленный E коммит. И вы хотите этого, если я правильно понимаю:

A---B---C  master
         \
          D---Ea---F'  b1
                    \      
                     G'---H'---I'  b2

Вы можете добиться этого с помощью интерактивной перебазировки:

git checkout b2
git rebase -i b1

В редактировании перебазирования вы закомментируете строки для фиксации E:

# pick df8efe6 E
pick a7fcbed G
pick 936b51a H
pick c77ca69 I

# ...
# Commands:
# p, pick = use commit
# ...
# If you remove a line here THAT COMMIT WILL BE LOST.

Отвечая на ваш комментарий, если вы хотите go полностью от начальной позиции (ABCDEFGHI) до желаемой конечной позиции:

git checkout b2
git rebase -i master

В редакторе:

pick 1234567 D
edit a7fcbed E
pick 936b51a F
pick c77ca69 G
pick 1e8d614 H
pick 8daafa7 I

# ...
# p, pick = use commit
# e, edit = use commit, but stop for amending
# ...

Когда закончите, исправьте ветку b1:

git checkout b1
git reset --hard 936b51a

Вы также можете посмотреть другие ответы для вдохновения. Я не уверен, почему вы хотите добиться всего этого с помощью одной команды; вам все равно придется изменить коммит E где-нибудь в процессе. Таким образом вы сэкономите одну интерактивную переустановку.

0 голосов
/ 09 июля 2020

Итак, мой вопрос: как убедиться, что b2 следует за b1 (автоматически получает те же новые коммиты, что и b1).

Вам тоже нужно переписать историю b2, вы перебазирование всех коммитов master..b2 и перестановка меток b1 и b2.

Интерактивное перебазирование позволяет выполнять произвольные команды, в частности, git branch, после каждого шага. Так что сделайте

git rebase -i master b2

и в списке выбора после текущего коммита b1 скажите exec git branch -f b1.

Вы можете автоматизировать это, перенаправив буфер списка выбора через

while read command commit rest; do case $command in 
*) printf %s\\n "$command${commit:+ $commit${rest:+ $rest}}" ;;&
pick) git for-each-ref refs/heads --points-at $commit \
        --format='exec git branch -f %(refname:short)' ;;
esac; done

и будет добавлять exec git branch -f после каждого выбора для наконечника ветки. Я только что построил и попробовал это. Приправить, конечно, по вкусу.

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

...