Отредактированный ответ с новым (во второй половине этой записи) новым исправлением Git1.7! действие и --autosquash
опция для быстрого переупорядочения фиксации и редактирования сообщения.
Во-первых, классический процесс сжатия, как это было до Git1.7.
(Git1.7 имеет тот же процесс, только ускоренный за счет возможности автоматического переупорядочения коммитов, в отличие от ручного переупорядочения и более чистых сообщений сжатия)
Я хотел бы иметь возможность удалить все мои частые проверки и просто оставить серьезные.
Это называется фиксация коммитов .
У вас есть хороший пример «очистки comit» в этой Git ready статье:
(Примечание: интерактивная функция 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's 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
", которое отменяет изменение, но не влияет на существующее сообщение журнала.
- "
git rebase -i
" также выучил опцию --autosquash
, которая полезна вместе с новым действием "fixup".
Оба (действие исправления и опция --autosquash
) проиллюстрированы в этой записи Thechnosorcery Networks . Эти функции готовятся с прошлого июня 2009 года и обсуждаются далее в декабре прошлого года .
Действие или директива fixup
предназначены для сжатия коммита, который вы бы вручную переупорядочили в списке редактирования коммита rebase --interactive
, игнорируя при этом второе сообщение коммита, что ускорит шаг редактирования сообщения (вы можете просто сохраните его: сжатый коммит будет иметь только первое сообщение о коммите)
Полученное сообщение о коммите будет только первым.
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
Опция --autosquash
предназначена для автоматического выполнения процесса изменения порядка коммитов:
Если вы знаете, с каким коммитом вы хотите что-то раздавить, вы можете передать это с сообщением «squash! $other_commit_subject
». Затем, если вы запустите @git rebase --interactive --autosquash commitish@
, строка будет автоматически установлена как сквош и помещена под коммитом с темой $ other_commit_subject.
(На самом деле, squash!
может использовать только начало другого сообщения фиксации)
$ vim Foo.txt
$ git commit -am "Change all the 'Bar's to 'Foo's"
[topic 8374d8e] Change all the 'Bar's to 'Foo's
1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am "Change all the 'Foo's to 'Bar's"
[topic 2d12ce8] Change all the 'Foo's 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(-)
См? Здесь третий коммит использует только начало сообщения first commit.
rebase --interactive --autosquash
переместит сдавленный коммит ниже соответствующего:
pick 8374d8e Change all the 'Bar's to 'Foo's
squash 259a7e6 squash! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's
Редактирование сообщенияИон будет:
# This is a combination of 2 commits.
# The first commit's message is:
Change all the 'Bar's to 'Foo's
# This is the 2nd commit message:
squash! Change all the 'Bar's
То есть по умолчанию вы сохраняете операцию сжатия, записанную в сообщении фиксации.
Но с исправлением! Директива, вы можете оставить это сжатие «невидимым» в сообщении коммита, но при этом использовать автоматическое изменение порядка коммитов с опцией --autosquash
(и тот факт, что ваше второе сообщение коммита основано на первом коммите, с которым вы хотите быть сжато ).
pick 8374d8e Change all the 'Bar's to 'Foo's
fixup cfc6e54 fixup! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's
Сообщение по умолчанию будет:
# This is a combination of 2 commits.
# The first commit's message is:
Change all the 'Bar's to 'Foo's
# The 2nd commit message will be skipped:
# fixup! Change all the 'Bar's
Обратите внимание, что сообщение коммита fixup!
уже закомментировано.
Вы можете просто сохранить сообщение как есть, и ваше оригинальное сообщение будет сохранено .
Очень удобно для включения изменений, когда вы понимаете, что забыли добавить часть предыдущего коммита .
Теперь, если вы хотите исправить или раздавить на основе предыдущего коммита , который вы только что сделали, Джейкоб Хелвиг (автор записи в блоге Technosorcery Networks) рекомендует следующие псевдонимы:
[alias]
fixup = !sh -c 'git commit -m \"fixup! $(git log -1 --format='\\''%s'\\'' $@)\"' -
squash = !sh -c 'git commit -m \"squash! $(git log -1 --format='\\''%s'\\'' $@)\"' -
И для выполнения интерактивной перебазировки, которая всегда выигрывает от автоматического изменения порядка коммитов, предназначенных для раздавливания:
[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
) .
(Объединено Junio C Hamano - gitster
- в коммит 4a3bf32 , 23 мая 2018 г.)
rebase --skip
: очистить сообщение о коммите после неудачного исправления / сквоша
Во время серии команд исправления / сквоша интерактивная сборка ребаз
составить сообщение с комментариями. Это будет представлено пользователю в
редактор, если хотя бы одна из этих команд была squash
.
В любом случае сообщение коммита будет в конечном итоге очищено, удалив
все эти промежуточные комментарии, на последнем этапе такой цепочки исправлений / сквоша.
Однако, если последняя команда fixup / squash в такой цепочке терпит неудачу с
конфликты слияния, и если пользователь затем решает пропустить его (или разрешить
на чистое рабочее дерево, а затем продолжить перебазирование), текущий код
не удается очистить сообщение фиксации.
Этот коммит исправляет это поведение.
Исправление немного сложнее, чем кажется на первый взгляд, потому что это
не только о том, что мы git rebase --skip
исправление или сквош. Это также касается удаления пропущенных исправлений / сквоша
сообщение коммита из накопленного сообщения коммита. И это также о
вопрос, должны ли мы позволить пользователю редактировать окончательный коммит
сообщение или нет («Был ли сквош в цепи , который не был
пропущено ? ").
Например, в этом случае мы захотим исправить сообщение фиксации, но
не открывать его в редакторе:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
Это то, где недавно введенный файл current-fixups
приходит в реальном
удобно. Беглый взгляд и мы можем определить, был ли пропущен
сквош. Нам нужно только следить за тем, чтобы
пропущенные команды fixup / squash. В качестве бонуса мы можем даже избежать совершения
без необходимости, например когда было только одно исправление, и оно не удалось, и
был пропущен.
Исправить только ту ошибку, из-за которой окончательное сообщение о фиксации не было очищено
правильно, но без фиксации остальных, было бы сложнее
чем исправить все это за один раз, следовательно, это делает комки больше, чем
одна проблема.
Git 2.19 (Q3 2018) исправляет ошибку: когда «git rebase -i
» велит объединить два или более коммитов в один, он помечает сообщение журнала для каждого коммита своим номером.
Этоправильно назвал первый «1-й коммит», но следующим был «commit #1
», что было одно за другим (!).
См. коммит dd2e36e (15 августа 2018 г.) от Филиппа Вуда (phillipwood
) .
(Объединено Junio C Hamano - gitster
- в коммит 36fd1e8 , 20 августа 2018 г.)
rebase -i
: исправить нумерацию в сообщении сквоша
Commit e12a7ef ("rebase -i
: обрабатывать" комбинацию <n>
commits "с
GETTEXT_POISON
", 2018-04-27, Git 2.18) изменил способ индивидуальной фиксации
сообщения помечаются, когда сжатие фиксируется вместе.
При этом была введена регрессия, когда нумерация сообщений отключена одним. Этот коммит исправляет это и добавляет тест для нумерации.