Я проверяю свой код на ветвь Git каждые несколько минут или около того, и комментарии заканчиваются такими вещами, как "Все сломанное начало снова" и другие абсурды.
Затем каждые несколько минут/часов/дней я делаю серьезный коммит с настоящим комментарием вроде "Исправлена ошибка 22.55, в 3 раза". Как я могу отделить эти две концепции? Я хотел бы удалить все мои частые коммиты и просто оставить серьезные.
Ответ 2
Отредактированный ответ теперь (во второй половине этой записи) с новым исправлением Git1.7! действие и опция --autosquash
для быстрого изменения порядка коммитов и редактирования сообщений.
Во-первых, классический процесс сжатия, как это было сделано до Git1.7.
(Git1.7 имеет тот же процесс, только ускоренный за счет возможности автоматического переупорядочения фиксации в отличие от ручного переупорядочения и более чистых сообщений о сжатии)
Я хотел бы иметь возможность удалить все мои частые проверки и просто оставить серьезные.
Это называется фиксация коммитов.
У вас есть хороший пример "очистки comit" в этой статье о Git:
(Примечание: интерактивная функция rebase появилась с сентября 2007 года и позволяет раздавливать, разбивать, удалять или переупорядочивать коммиты: см. Также страницу GitPro)
Предупреждение: делайте это только с коммитами, которые не были переданы во внешний репозиторий. Если другие основывают работу на коммитах, которые вы собираетесь удалить, может возникнуть множество конфликтов. Просто не переписывайте свою историю, если она была передана другим.
Последние 4 коммита были бы намного счастливее, если бы они были свернуты вместе
$ git rebase -i HEAD~4
pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.
# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
сделайте ребаз, используя последние четыре коммита, где HEAD
с HEAD~4
.
Просто собирались раздавить все в один коммит.
Таким образом, изменение первых четырех строк файла на это поможет:
pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.
В основном это говорит Git объединить все четыре коммита в первый коммит в списке. Как только это будет сделано и сохранено, появится другой редактор со следующим:
# This is a combination of 4 commits.
# The first commit message is:
Adding license
# This is the 2nd commit message:
Moving license into its own file
# This is the 3rd commit message:
Jekyll has become self-aware.
# This is the 4th commit message:
Changed the tagline in the binary, too.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i nor -o; assuming --only paths...
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: LICENSE
# modified: README.textile
# modified: Rakefile
# modified: bin/jekyll
#
Поскольку Git объединяет так много коммитов, вы можете изменять новое сообщение коммитов, основываясь на остальных коммитах, вовлеченных в процесс. Отредактируйте сообщение, как считаете нужным, затем сохраните и выйдите.
Как только это будет сделано, ваши коммиты будут успешно раздавлены!
Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
4 files changed, 27 insertions(+), 30 deletions(-)
create mode 100644 LICENSE
Successfully rebased and updated refs/heads/master.
И если мы посмотрим на историю снова...
Примечание: для целей "фиксации коммита" Git1.7 (февраль 2010 г.) представил 2 новых элемента (как упомянуто Дастином в комментарии):
- "
git rebase -i
" изучил новое действие " fixup
", которое fixup
изменение, но не влияет на существующее сообщение журнала. - "
git rebase -i
" также изучил --autosquash
которая полезна вместе с новым действием "fixup".
Оба (действие --autosquash
опция --autosquash
) проиллюстрированы в этой записи блога Thechnosorcery Networks. Эти функции готовятся с июня прошлого года и обсуждаются в декабре прошлого года.
Действие или директива fixup
предназначены для уничтожения коммита, который вы бы вручную переупорядочили в списке редактирования коммита rebase --interactive
, в то же время игнорируя второе сообщение коммита, что rebase --interactive
редактирования сообщения (вы можете просто сохранить его).: сжатый коммит будет иметь только первое сообщение коммита)
Полученное сообщение о коммите будет только первым.
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit log message
Опция --autosquash
предназначена для автоматического выполнения процесса изменения порядка коммитов:
Если вы знаете, с каким коммитом вы хотите что-то раздавить, вы можете сделать это с сообщением " squash! $other_commit_subject
". Затем, если вы запустите @git rebase --interactive --autosquash [email protected]
, строка будет автоматически установлена как сквош и помещена под коммит с темой $ other_commit_subject.
(На самом деле, squash!
Может использовать только начало другого сообщения коммита)
$ vim Foo.txt
$ git commit -am "Change all the 'Bar to 'Foo's"
[topic 8374d8e] Change all the 'Bar to 'Foo's
1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am "Change all the 'Foo to 'Bar's"
[topic 2d12ce8] Change all the 'Foo to 'Bar's
1 files changed, 1 insertions(+), 1 deletions(-)
$ vim Foo.txt
$ git commit -am "squash! Change all the 'Bar's"
[topic 259a7e6] squash! Change all the 'Bar's
1 files changed, 2 insertions(+), 1 deletions(-)
Увидеть? Здесь третий коммит использует только начало первого сообщения коммита.
rebase --interactive --autosquash
переместит сдавленный коммит ниже соответствующего:
pick 8374d8e Change all the 'Bar to 'Foo's
squash 259a7e6 squash! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo to 'Bar's
Редакция сообщения будет:
# This is a combination of 2 commits.
# The first commit message is:
Change all the 'Bar to 'Foo's
# This is the 2nd commit message:
squash! Change all the 'Bar's
Это означает, что по умолчанию вы сохраняете операцию сжатия в сообщении коммита.
Но с исправлением! Директива, вы можете оставить это сжатие "невидимым" в сообщении коммита, но при этом воспользоваться автоматическим переупорядочением фиксации с --autosquash
(и тот факт, что ваше второе сообщение коммита основано на первом коммите, с которым вы хотите быть сжато).
pick 8374d8e Change all the 'Bar to 'Foo's
fixup cfc6e54 fixup! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo to 'Bar's
Сообщение по умолчанию будет:
# This is a combination of 2 commits.
# The first commit message is:
Change all the 'Bar to 'Foo's
# The 2nd commit message will be skipped:
# fixup! Change all the 'Bar's
Обратите внимание, что fixup!
сообщение коммитов уже закомментировано.
Вы можете просто сохранить сообщение как -i, и ваше исходное сообщение будет сохранено.
Очень удобно для включения изменений, когда вы понимаете, что забыли добавить часть более раннего коммита.
Теперь, если вы хотите исправить или раздавить, основываясь на предыдущем коммите, который вы только что сделали, Джейкоб Хелвиг (автор записи в блоге Technosorcery Networks) рекомендует следующие псевдонимы:
[alias]
fixup = !sh -c 'git commit -m \"fixup! $(git log -1 --format='\\''%s'\\'' [email protected])\"' -
squash = !sh -c 'git commit -m \"squash! $(git log -1 --format='\\''%s'\\'' [email protected])\"' -
И для выполнения интерактивной перебазировки, которая всегда выигрывает от автоматического изменения порядка коммитов, предназначенных для раздавливания:
[alias]
ri = rebase --interactive --autosquash
Обновление для Git 2.18 (Q2 2018): " git rebase -i
" иногда оставляется промежуточным " # This is a combination of N commits
", предназначенного для использования человеком в редакторе в конечном результате в определенных угловых случаях, который был фиксированный.
См. Коммит 15ef693, коммит dc4b5bc, коммит e12a7ef, коммит d5bc6f2 (27 апреля 2018 г.) от Йоханнеса dscho
(dscho
).
(Объединено Джунио К Хамано - gitster
- в коммите 4a3bf32, 23 мая 2018 г.)
rebase --skip
: очистить сообщение о коммите после неудачного исправления/сквоша
Во время серии команд fixup/squash интерактивное перебазирование создает коммит-сообщение с комментариями. Это будет представлено пользователю в редакторе, если хотя бы одна из этих команд была squash
.
В любом случае сообщение о фиксации будет в конечном итоге очищено, удалив все эти промежуточные комментарии, на последнем этапе такой цепочки исправлений/сквоша.
Однако, если последняя команда fixup/squash в такой цепочке завершается неудачно с конфликтами слияния, и если пользователь затем решает пропустить ее (или разрешить ее для чистого рабочего дерева, а затем продолжить перебазирование), текущему коду не удается очистить отправить сообщение
Этот коммит исправляет это поведение.
Исправление несколько сложнее, чем кажется на git rebase --skip
взгляд, потому что речь идет не только о том, что мы делаем git rebase --skip
исправление или сквош. Также речь идет об удалении пропущенного сообщения коммита/сквоша из накопленного сообщения о коммите. И это также вопрос о том, должны ли мы позволить пользователю редактировать окончательное сообщение коммита или нет ("Был ли сквош в цепочке, который не был пропущен?").
Например, в этом случае мы хотим исправить сообщение коммита, но не открывать его в редакторе:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
Вот где недавно current-fixups
файл -i current-fixups
очень удобен. Беглый взгляд, и мы можем определить, был ли не пропущенный сквош. Нам нужно только следить за тем, чтобы они были актуальными в отношении пропущенных команд fixup/squash. В качестве бонуса мы можем даже избежать ненужных фиксаций, например, когда была только одна фиксация, и она не удалась и была пропущена.
Исправить только ту ошибку, из-за которой окончательное сообщение о фиксации не было очищено должным образом, но без исправления остальных, было бы сложнее, чем исправить все за один раз, следовательно, эта фиксация объединяет больше, чем одну проблему.
Git 2.19 (Q3 2018) исправляет ошибку: когда " git rebase -i
" git rebase -i
два или более коммитов в один, он помечает сообщение журнала для каждого коммита своим номером.
Первый корректно назывался "1-й коммит", но следующим был " commit #1
", который был однозначным (!).
См. Коммит dd2e36e (15 августа 2018 г.) Филиппа Вуда (phillipwood
).
(Объединено Юнио К Хамано - gitster
- в коммите 36fd1e8, 20 августа 2018 г.)
rebase -i
: исправить нумерацию в сообщении сквоша
Коммит e12a7ef (" rebase -i
: обрабатывать" комбинацию <n>
GETTEXT_POISON
"с GETTEXT_POISON
", 2018-04-27, Git 2.18) изменил способ, которым отдельные сообщения коммитов помечаются при объединении коммитов при сжатии.
При этом была введена регрессия, когда нумерация сообщений отключена одним. Этот коммит исправляет это и добавляет тест для нумерации.