Вот демонстрация того, что я придумал после 15 минут взлома. Это не полное решение поставленной проблемы, но оно должно сократить объем работы.
Цель состоит в том, чтобы использовать git bisect
, чтобы найти самую раннюю бесконфликтную точку слияния для будущего коммита. В этом решении используются возможности двоичного поиска, присущие git bisect
, для сокращения шагов.
К сожалению, это не не исключает конфликты последующих коммитов, поэтому для проверки результатов требуется интерактивная перебазировка (но в любом случае это главное).
Единственный недостаток / предостережение заключается в том, что вы должны обратить вспять смысл good
и bad
в своей голове, когда вы инструктируете git о том, был ли этот шаг неудачным или успешным при тестировании патча.
Если какой-либо из приведенных ниже шагов неясен, дайте мне знать, и я постараюсь уточнить.
Сначала создайте следующий файл в серии коммитов. Каждый коммит должен добавлять серию из четырех одинаковых строк (a, затем b, затем c, затем d).
a
a
a
a
b
b
b
b
c
c
c
c
d
d
d
d
В этот момент git log
должно вывести что-то вроде:
commit 6f2b809863632a86cc0523df3a4bcca22cf5ab17
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:45:44 2011 -0500
Added d.
commit 91ba7e6f19db74adb6ce79e7b85ea965788f6b88
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:44:26 2011 -0500
Added c.
commit f83beee55d6e060536584852ebb55c5ac3b850b2
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:44:00 2011 -0500
Added b.
commit d6d924b0a30a9720f6e01dcc79dc49097832a587
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:43:38 2011 -0500
Added a.
commit 74d41121470108642b1a5df087bc837fdf77d31c
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:43:11 2011 -0500
Initial commit.
Теперь отредактируйте файл, чтобы он содержал следующее, и передайте следующее:
a
a
a
a
b
x
x
b
c
x
x
c
d
d
d
d
Теперь журнал должен включать еще один коммит:
commit 09f247902a9939cb228b580d39ed2622c3211ca6
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:46:36 2011 -0500
Replaced a few lines with x.
Теперь сгенерируйте патч для X
commit.
git diff -p master~ > x.patch
Crank up bisect
- не забудьте использовать git bisect good
, когда патч не работает, и git bisect bad
, когда патч успешен:
$ git bisect start
$ git bisect good 74d41121470108642b1a5df087bc837fdf77d31c
$ git bisect bad master
Bisecting: 2 revisions left to test after this (roughly 1 step)
[f83beee55d6e060536584852ebb55c5ac3b850b2] Added b.
$ patch --dry-run -p1 < x.patch
patching file file.txt
Hunk #1 FAILED at 3.
1 out of 1 hunk FAILED -- saving rejects to file file.txt.rej
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[6f2b809863632a86cc0523df3a4bcca22cf5ab17] Added d.
$ patch --dry-run -p1 < x.patch
patching file file.txt
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[91ba7e6f19db74adb6ce79e7b85ea965788f6b88] Added c.
$ patch --dry-run -p1 < x.patch
patching file file.txt
Hunk #1 succeeded at 3 with fuzz 2.
$ git bisect bad
91ba7e6f19db74adb6ce79e7b85ea965788f6b88 is the first bad commit
commit 91ba7e6f19db74adb6ce79e7b85ea965788f6b88
Author: Todd Sundsted <...>
Date: Tue Dec 20 22:44:26 2011 -0500
Added c.
$ git bisect reset
Как и ожидалось, изменения в коммите X
могут быть перемещены сразу после коммита C
. Интерактивная перебазировка подтверждает это:
91e92489 * Added d.
6c082b1f * Replaced a few lines with x.
a60ae2a9 * Added c.
4d5e78f2 * Added b.
7d2ff759 * Added a.
74d41121 * Initial commit.