Как объединить два git коммита в один коммит без использования интерактивного git перебазирования? - PullRequest
1 голос
/ 27 апреля 2020

Я работаю над веткой функций, которая также используется другими командами, и у них много разработчиков, поэтому с их конца происходит много коммитов. В последний раз я совершал около 10 дней go, и снова я планирую сделать это сегодня, но я хочу обеспечить один коммит с моей стороны.

Я знаю, что могу добиться этого с помощью "git rebase -i HEAD ~ n ", но я не знаю, какое число поставить вместо n, так как за эти 10 дней было более 20+ коммитов с конца другой команды. Эта команда хороша, если у вас есть последовательные коммиты, но она не идеальна для мой сценарий.

Хотя у меня есть хеш-коды git коммитов, сделанные с моего конца, так есть ли какой-нибудь способ кроме git интерактивного перебазирования, где я мог бы просто использовать один из своих git хеш-кодов в качестве "выбрать", а другой как "Squa sh". Это избавит меня от необходимости проходить 20+ git коммитов.

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

Это - это можно достичь желаемого результата без использования git rebase -i. Этот метод стоит того, чтобы вы действительно поняли , что делает git rebase, независимо от того, используете ли вы опцию -i.

Это , вероятно, неразумно для достижения желаемого результата на всех , хотя только вы и ваши коллеги действительно могут определить это.

Один из способов сделать это вручную - git checkout указать c передайте по ha sh ID и создайте новое имя ветви, указывающее на этот коммит. Коммит, который вы выбираете здесь, должен быть одним как раз перед двумя коммитами, о которых идет речь.

Тогда вы git cherry-pick -n сделаете два коммита, которые вы хотели сква sh в один новый коммит и используйте git commit для фиксации результата.

Теперь вы столкнулись с проблемой дополнительного использования git cherry-pick для копирования каждого последующего коммита в новую ветвь. Это не так уж и сложно - на самом деле, все должно go автоматически, при наличии правильных идентификаторов sh. Вам просто нужно найти правильные идентификаторы ha sh.

Как только вы закончите, вам нужно убедить своих коллег отказаться от существующей ветви функций и использовать новую, перестроенную ветвь функций. Эта новая ветвь имеет копии оригинальных коммитов, но они являются новыми и улучшенными в том смысле, что они построены на вашей раздавленной замене ваших оригинальных двух коммитов.

Если это звучит немного запутанно, то это то же самое, что сделал бы ваш git rebase -i, за исключением того, что когда вы делаете это с git rebase -i, вы должны убедить своих коллег отказаться от ветви с именем feature/foo в пользу новой ветви с именем still feature/foo, что немного сбивает с толку!


Чтобы сделать это с git rebase -i без необходимости считать коммитов (как в HEAD~20), используйте :

git log --decorate --oneline --graph

, чтобы получить представление о коммитах, которые вы собираетесь перебазировать. Вы получите однострочный список коммитов с сокращенными идентификаторами ha sh и их темами, а также чертеж ASCII графика коммитов. Убедитесь, что в коммитах, которые вы скопируете, нет шаблонов ветвления и слияния (или если это так, то все в порядке, если вы выбросите все слияния) - в этом случае это означает, что это всего лишь серия * маркировки перед коммитами, которые вы собираетесь копировать и заменять. Тогда вместо , считая , используйте:

git rebase -i <hash>

, где hash - это то, что с первого коммита, который вы не будете copy-or-modify.

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

1 голос
/ 28 апреля 2020

В этой ситуации (функция ветвь с большим количеством изменений других людей) я всегда держу свои невыдвинутые коммиты на вершине других коммитов, всегда делая git pull --rebase. Это извлечет ветку, как на сервере, и поместит мои локальные коммиты сверху. Обратите внимание, что это изменит мою локальную историю ветвей, но не историю удаленных веток, поэтому на pu sh будет нет необходимости использовать --force:).

Тогда когда вы готовы отправить свою работу на сервер, используя всего один коммит, вы можете просто набрать sh, найдя га sh топового серверного коммита и:

git reset --soft HASH_BEFORE_MY_FIRST_LOCAL_COMMIT

Это оставит все изменения от ваших локальных коммитов уже подготовленными. Вам просто нужно зафиксировать их, указав новое сообщение, используя git commit -m "...", git gui или предпочитаемый вами инструмент. Обратите внимание, что в данный момент у вас не будет каждого отдельного сообщения, поэтому, если оно вам нужно, лучше получить его, прежде чем выполнить сброс git.

Обратная сторона этого подхода: при использовании git pull --rebase git будет применять каждый ваш локальный коммит один за другим. Если возникает конфликт, вам придется разрешить его и использовать git rebase --continue. Недостатком является то, что в зависимости от количества локальных коммитов вы можете принимать конфликты несколько раз.

...