Документы и поиск просто сбивают меня с толку относительно того, что делать, чтобы очистить историю коммитов.

Скажем, у меня есть ветка под названием 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. Что бы вы здесь сделали, что не приведет к конфликтам слияния?

git
2
Joff 7 Сен 2016 в 08:36

3 ответа

Лучший ответ

Как насчет

git reset --soft HEAD~[n]
git commit

Это должно уничтожить ваши n последних коммитов.

5
qantik 7 Сен 2016 в 05:49

Git Squash работает с объединением коммитов в один.

Как уже упоминалось, git rebase -i HEAD~n замените n количеством коммитов, которые вы хотите сжать, и force push внесите изменения, если это необходимо.

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

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

1
VinayVeluri 7 Сен 2016 в 05:59

Что бы вы здесь сделали, что не приведет к конфликтам слияния?

К сожалению, конфликты слияния могут быть неизбежны, если вы раздавите коммиты.

Вы можете попробовать выполнить интерактивную перебазировку, в которой вы объединяете фиксации исправления в одну фиксацию. Имейте в виду, что это решение рекомендуется, только если вы еще не отправили эту ветку на удаленный компьютер. Итак, если вы сделали коммиты 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

Но имейте в виду, что это переписывает удаленную историю, и в идеале вам не нужно этого делать.

1
Tim Biegeleisen 7 Сен 2016 в 05:46