git reword показывает конфликт слияния при перебазировании, однако выборка работает правильно - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь перебазировать ветку с другой веткой с несколькими коммитами.Хотя коммиты включают в себя коммиты слияния, я могу успешно перебазировать их с помощью следующей команды git rebase -i -r -m <base_branch>

Однако, когда я пытаюсь изменить некоторые из сообщений коммита, используя 'reword', я вижу конфликты слияния.

Я попробовал команду git rebase -i -r -m <base_branch> и изменил несколько коммитов для перефразирования вместо выбора, после чего возникали конфликты слияния.

Используемая команда:
git rebase -i -r -m <base_branch>

Я ожидаю успешной перезагрузки, но есть конфликты.

1 Ответ

1 голос
/ 23 мая 2019

Вероятно, это связано с конфликтом исходного слияния.(Я не могу доказать , что это так, если у вас нет доступа к хранилищу и его коммитам.)

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

Эту проблему можно обойти с помощью git rerere (и сценарий rerere-train, возможно: см. Разумная перебазировка, позволяющая избежать избыточной работы? ).

Long

Помните, что git rebase работает путем копирования фиксирует.Простая интерактивная перебазировка начинается с перечисления всех коммитов для копирования с использованием pick команд для каждого такого коммита.Этот простой вид rebase отбрасывает слияния.Добавление --rebase-merges (или -r) говорит о том, что сохраняет слияния вместе с исходным расположением коммитов. Но во всей этой концепции есть недостаток: хотя можно копировать коммит без слияния, не можно скопировать коммит слияния.

Что git rebase -r (и его более старый, более бедный git rebase -p кузен) делают вместо этого, потому что они не могут копировать слияния, повторно выполнить слияния при необходимости.То есть, после копирования некоторого количества старых коммитов в новые, с новыми и разными хеш-идентификаторами, они достигают момента, когда пора «копировать» слияние, и вместо этого они просто запускают git merge напрямую.

Например, учитывая:

                    C--D
                   /    \
               A--B      G--H   <-- source (HEAD)
              /    \    /
             /      E--F
            /
...--o--o--*--o--o   <-- target

и запрос командной строки git rebase -r target сгенерирует серию команд pick, label, reset и merge длякопия A, B, C, D, E и F;затем объедините the copies of D and F ; then copy G and H`, чтобы получить:

                    C--D
                   /    \
               A--B      G--H   <-- [abandoned]
              /    \    /
             /      E--F
            /
...--o--o--*--o--o   <-- target
                  \
                   \      C'-D'
                    \    /    \
                     A'-B'     G'-H'   <-- source (HEAD)
                         \    /
                          E'-F'

, где commit A' является копией A, B'является копией B и т. д.

Но, с опцией -r или без нее, рассмотрим операцию перебазирования, которая начинается с:

...--I--J   <-- target
         \
          K--L   <-- source (HEAD)

Теперь вы спрашиваете Gitчерез git rebase скопировать коммит K в новый улучшенный K, который точно такой же, как K, за исключением того, что он идет после J, а не после J.Затем вы говорите Git скопировать L, чтобы вместо «1083» он шел после новой копии K.

Git понимает, что существующая копия K, который идет после J, уже идет сразу после J.Таким образом, «копия», которую нужно сделать, уже существует: git rebase просто повторно использует K напрямую.Теперь он должен скопировать L после K, но посмотрите: L уже идет сразу после K, поэтому Git просто повторно использует L напрямую.В результате ничего не меняется.(Если по какой-то причине - и по некоторым причинам - вы действительно хотите Git для копирования K, в любом случае, вы можете использовать --force-rebase или --no-ff или -f, все из которых делаютто же самое.)

Если вы запустите эту же перезагрузку, обязательно используя интерактивный режим, и используйте reword на K, теперь Git действительно делает необходимо скопировать K в новый K', который похож на K, но имеет другое сообщение о коммите.В результате Git теперь действительно должен скопировать L, чтобы он шел после нового K' с новым сообщением.Результат:

          K'-L'  <-- source (HEAD)
         /
...--I--J   <-- target
         \
          K--L   [abandoned]

Для простого линейного случая, подобного этому, ребазирование всегда проходит гладко, но когда вы добавляете -r к миксу, вынуждаете Git «копировать» (т.е.-производить) слияние, если исходное слияние имело конфликты, то будет и новое слияние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...