Документы и поиск просто сбивают меня с толку относительно того, что делать, чтобы очистить историю коммитов.
Скажем, у меня есть ветка под названием tests, которую я использую для отправки сборок в travis-ci, и у меня возникает сбой сборки. Затем мне пришлось бы сделать несколько небольших коммитов, чтобы попытаться исправить сообщение об ошибке и повторно нажать ветку tests
.
Это может привести к цепочке небольших и почти бессмысленных коммитов, которые я действительно не хочу делать, но, тем не менее, вынужден это делать. Как мне сжать их в одну фиксацию? Я думаю, что rebase
- это то, что я ищу, но меня несколько смущают некоторые вещи.
Если я использую squash
, я обнаруживаю, что сталкиваюсь с множеством конфликтов слияния, которые мне затем приходится решать вручную.
Я думаю, что решением может быть просто удалить коммиты, но тогда я не уверен, буду ли я удалять какую-то историю, которая нужна моему последнему «рабочему» коммиту.
Скажем, моя история коммитов выглядит так:
commit1: some new feature
commit2: crap, builds failing, trying fix
commit3: more build attempts
commit4: Ahh I think I got it this time
commit5: ok finally fixed, build passing
Сейчас я бы хотел, чтобы только один коммит снова слился с master
. Что бы вы здесь сделали, что не приведет к конфликтам слияния?
3 ответа
Как насчет
git reset --soft HEAD~[n]
git commit
Это должно уничтожить ваши n последних коммитов.
Git Squash
работает с объединением коммитов в один.
Как уже упоминалось, git rebase -i HEAD~n
замените n количеством коммитов, которые вы хотите сжать, и force push
внесите изменения, если это необходимо.
В идеале фиксация совершается тогда, когда ее необходимо отметить и оставить следы. История коммитов играет важную роль в перебазировании, проверке версий кода, при создании веток. При записи изменений в git убедитесь, что изменения актуальны и должны быть сохранены.
Выбирайте сквош только тогда, когда это действительно не нужно, чтобы говорить об изменениях, которые вы делаете. Это изменяет отчет о проделанной работе.
Что бы вы здесь сделали, что не приведет к конфликтам слияния?
К сожалению, конфликты слияния могут быть неизбежны, если вы раздавите коммиты.
Вы можете попробовать выполнить интерактивную перебазировку, в которой вы объединяете фиксации исправления в одну фиксацию. Имейте в виду, что это решение рекомендуется, только если вы еще не отправили эту ветку на удаленный компьютер. Итак, если вы сделали коммиты 1–5 локально, а не нажали их, и вы хотите их объединить, то интерактивная перебазировка - хороший выбор.
Начнем со следующего:
git checkout tests
git rebase -i HEAD~5
Должно появиться окно со следующим списком из 5 коммитов, начиная с самого старого коммита 1 и заканчивая самым новым коммитом 5 вашей ветки tests
:
pick 07c5abd message for commit 1
pick dl398cn message for commit 2
pick 93nmcdu message for commit 3
pick lst28e4 message for commit 4
pick 398nmol message for commit 5
Вы можете видеть, что по умолчанию опция для каждой фиксации - pick
. Если вы закончите перебазирование сейчас, вы просто сохраните каждую фиксацию как есть, что фактически не работает. Но так как вы хотите раздавить определенные средние коммиты, отредактируйте и измените список на этот:
pick 07c5abd message for commit 1
squash dl398cn message for commit 2
squash 93nmcdu message for commit 3
squash lst28e4 message for commit 4
squash 398nmol message for commit 5
Сохраните и закройте файл, затем завершите перебазирование.
Внимательно обратите внимание на то, что происходит выше. Набирая squash, вы указываете Git объединить этот коммит с коммитом, который выше , то есть с коммитом, который был сделан непосредственно перед ним. Таким образом, это говорит о том, что нужно сжать фиксацию 5 назад в фиксацию 4, а затем сжать 4 в 3 и так далее, оставляя вам только одну фиксацию для коммитов с 1 по 5. Остальные коммиты, которые произошли до фиксации 1, остаются как есть.
Если коммиты, которые вы только что раздавили, не были отправлены, а фиксация 1 опережает origin/tests
, тогда вы просто сможете отправить эту ветку через:
git push origin tests
Если это не сработает, возможно, вам придется принудительно нажать ветку:
git push --force origin tests
Но имейте в виду, что это переписывает удаленную историю, и в идеале вам не нужно этого делать.
Похожие вопросы
Новые вопросы
git
Git — это распределенная система контроля версий с открытым исходным кодом (DVCS). Используйте этот тег для вопросов об использовании Git и рабочих процессах. Не используйте этот тег для общих вопросов по программированию, связанных с репозиторием Git. Не используйте этот тег для вопросов GitHub/GitHub Actions, не связанных с использованием git; вместо этого используйте [github] или [github-actions]. Не используйте тег [github] для проблем, связанных с Git, только потому, что репозиторий размещен на GitHub.