Как я могу использовать git rebase -i после git merge, чтобы не запутаться? - PullRequest
8 голосов
/ 11 ноября 2010

У меня следующая ситуация: Я сделал несколько коммитов в свой локальный репозиторий, а затем огромное слияние другой ветви (~ 150 коммитов) с мастером - в нем было много конфликтов.

Теперь я хочу переместить коммит, который я сделал до слияния, после него перед нажатием.

Обычно я бы использовал для этого "rebase -i".

К сожалению, поведение по умолчанию состоит в том, чтобы разбить один сделанный мной слиянием коммит, который фактически добавил еще 150 коммитов к мастеру на отдельные коммиты (я понимаю, что я бы использовал для начала rebase вместо merge) плохое поведение для меня по нескольким причинам.

Я обнаружил флаг '-p' для rebase, который сохраняет слияния, и был очень рад этому. К сожалению, это фактически применило то же самое слияние снова, и забыло все о моей тяжелой работе по разрешению конфликтов. Опять же - плохое поведение!

Есть ли решение для чего я хочу? Использование rebase -i после слияния для изменения порядка или редактирования определенных коммитов без необходимости повторения моих операций после слияния?

Спасибо!

Ответы [ 3 ]

12 голосов
/ 11 ноября 2010

Вот что делает сценарий rerere-train.sh , о котором я упоминал в своем комментарии - по сути, он повторяет слияние, использует ваше разрешение и просто позволяет повторно просмотреть его.Вы можете сделать это вручную только для одного коммита, если хотите:

git checkout <parent of merge commit>
git merge <merged commit>         # if this goes cleanly, we're done
git rerere                        # done automatically if rerere.enabled is true
git checkout <merge commit> -- .  # check out the files from the result of the merge
git rerere                        # done automatically if rerere.enabled is true
git reset --hard                  # wipe away the merge

# and you'd want to follow with git checkout <branch> to return to where you were

Но вы также можете просто установить для rerere.enabled значение true и выполнить эти шаги за вычетом прямых вызовов на git rerere - и выбудет установлен в будущем, при этом rerere будет автоматически запускаться при разрешении конфликтов. Это то, что я делаю - это круто.

Если вы хотите запустить скрипт напрямую, вы, вероятно, захотите запустить его с аргументами вроде rerere-train.sh ^<commit before the merge> <current branch>.(Обозначение ^commit означает «не проходите мимо этого в историю», поэтому оно не будет беспокоиться о том, что all слияние совершается в вашем репо.)

Однаковы получаете rerere, чтобы сделать свое дело, вы должны в конечном итоге с желаемым записанным разрешением.Это означает, что вы можете пойти дальше и выполнить перебазирование -i, а когда вы столкнетесь с конфликтом, rerere повторно использует REcorded REsolution.Просто напоследок: он по-прежнему оставляет файлы, помеченные в индексе как конфликтующие, чтобы вы могли их проверить и убедиться, что то, что он сделал, имеет смысл.Как только вы это сделаете, используйте git add, чтобы проверить их, как если бы вы сами разрешили конфликты, и продолжайте как обычно!

git-rerere manpage содержит очень хороший,длинное описание нормального использования rerere, которое никогда не включает в себя фактический вызов rerere - все это делается автоматически.И примечание, в котором это не подчеркивается: все это основано на фрагментах конфликта, поэтому оно может повторно использовать разрешение, даже если конфликт заканчивается в совершенно другом месте, если это все тот же текстовый конфликт.

1 голос
/ 15 апреля 2013

Я сделал скрипт для этого здесь .См. открытые выпуски для известных ограничений.

Сначала вам нужно будет установить rerere-train.sh в свой PATH.На Fedora это можно сделать с помощью:

    install "$(rpm -ql git|grep '/rerere-train.sh$')" ~/bin
0 голосов
/ 23 февраля 2017

Я использовал rerere-train.sh от ответа пользователя @ Jefromi.Однако у меня была эта ошибка:

$ ../rerere-train.sh HEAD
C:\Program Files\Git\mingw64/libexec/git-core/git-sh-setup: line 6: .: git-sh-i18n: file not found

Из этого http://kernel.opensuse.org/cgit/kernel-source/commit/?h=linux-next&id=d52b9f00588bb18d7f7a0e043eea15e6c27ec40c Я видел это:

Михал Марек

Git-sh-setupпомощник, очевидно, никогда не предназначался для использования скриптами вне git.Это стало очевидным с git 2.10:

После загрузки старой версии - 2.3.4 portable - мне удалось заставить rerere-train.sh работать.

...