Выводить diff в командную строку при сбое rebase вместо изменения файлов - PullRequest
0 голосов
/ 27 мая 2018

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

Когда git rebase терпит неудачу, пользователь, очевидно, хочет получить некоторые diff (target x patch) конфликтующих строк, выводимых в командную строку.Как этого добиться?

Примечание: Из-за этих двух проблем я избегаю git rebase, так как я впервые научился использовать git.Я получаю новую ветку от цели и использую git cherry pick -X theirs (принудительный выбор вишни).После этого я решаю проблемы, используя git diff и git commit --amend, что не так просто, но работает для меня лучше, чем git rebase.

1 Ответ

0 голосов
/ 27 мая 2018

TL; DR

Необходимые файлы находятся в индексе, в промежуточных слотах, зарезервированных для конфликтов слияния.

Long

При сбое git rebase, он изменяет конфликтующие файлы, что не очень удобно.Есть ли способ, как остановить git rebase, чтобы сделать это?

Нет.

Но это гораздо больше, чем это.Rebase - это, по сути, серия операций git cherry-pick, и каждый вишневый пик на самом деле является слиянием - трехсторонним слиянием с необычной базой слияния с учетом двух левых / локальных / HEAD / --ours и правых/ remote / other / --theirs коммиты.

Рассмотрим последовательность «перед перебазированием» и «после перебазировки»:

[before rebase]

...--o--*--A--B--C   <-- yourbranch
         \
          D--E   <-- target

[after rebase]

...--o--*--A--B--C   [mostly abandoned]
         \
          D--E   <-- target
              \
               A'-B'-C'  <-- yourbranch

Чтобы перейти от «до» к после »,Git начинает с проверки коммита E (как отдельного HEAD), затем запускает git cherry-pick <hash-of-A>.

Эта операция выбора вишни запускает слияние, при этом основой слияния является коммит *, --ours или HEAD commit - коммит E, а --theirs commit - коммит A.

Как и все слияния, фактическое слияние для каждого файла происходит в индексе , используя три промежуточных слота слияния . Они пронумерованы: слот 1 - для базы слияния, слот 2 - для версии --ours, а слот 3 - для версии --theirs.

Если слияние прошло хорошо, окончательный результат слияния копируется в нулевой слот, уничтожаяСлот 1-3 записи, и Git продолжается.Если нет, версия файла work-tree размечена так, как вам не нужно.Однако все три другие версии файла остаются в индексе, в слоте 1 (который просто пронумерован), слоте 2 (доступно через git checkout --ours) и слоте 3 (доступно через git checkout --theirs). You can therefore obtain any or all three versions of the file into the work-tree using gitcheckout or git show`:

git show :1:file > file.base
git show :2:file > file.head
git checkout --theirs file   # overwrite work-tree version

, например.

Как только вы разрешили конфликт слияния в рабочем дереве, вы запускаете git add file, чтобы скопировать file внулевой слот, стирая записи слотов 1, 2 и 3. Как только все такие файлы разрешены, вы запускаете git rebase --continue (если перебазирование, или git cherry-pick --continue, если выбор вишни), чтобы сделать коммит Gitрезультат из индекса как обычно.

Для rebase следующим шагом будет копирование коммита B:

...--o--*--A--B--C   <-- yourbranch
         \
          D--E   <-- target
              \
               A'  <-- HEAD

Это копирование выполняется как бы git cherry-pick, чтоозначает, что база слияния - это коммит A, --ours - это коммит A', а --theirs - это коммит B. Если существует конфликт слияния, это три версии файла, которыевы найдете в индексе.

После разрешения этого конфликта и запуска git rebase --continue, вы получите это, еслиВишня выбора коммита C останавливается с конфликтом:

...--o--*--A--B--C   <-- yourbranch
         \
          D--E   <-- target
              \
               A'-B'  <-- HEAD

, и теперь три индексные версии будут те из базы слияния B, --ours коммит B' и--theirs commit C.

Следовательно, вам нужны файлы .Они просто в index , а не в рабочем дереве.

...