В чем разница между "squash" и "fixup" в Git/Git Extension?

Я уже давно пользуюсь Git Extensions (это здорово!), Но я не нашел простого ответа на следующее:

Иногда, при вводе сообщения о коммите, создается опечатка. Мой друг показал мне, как это исправить следующим образом (в Git Extentions):

Щелкните правой кнопкой мыши на коммите> Дополнительно> Фикс фиксации

Затем я просто ставлю галочку "Изменить" и переписываю свое сообщение и вуаля! Мое сообщение фиксации исправлено.

Однако этот другой вариант "Сквош коммит"... Я всегда задавался вопросом, что он делает?!

Мой вопрос:

Кто-нибудь просто объяснит мне, какова точная разница между коммитом Squash и Fixup в Git / Git Extentions? Они выглядят как... "похожи" на меня

8 ответов

Решение

Я не знаю, что конкретно делает с ним Git Extensions, но git rebase имеет возможность автоматически совершать сквош или фиксировать коммит с помощью сквоша! или исправление! префиксы соответственно:

   --autosquash, --no-autosquash
       When the commit log message begins with "squash! ..." (or "fixup!
       ..."), and there is a commit whose title begins with the same ...,
       automatically modify the todo list of rebase -i so that the commit
       marked for squashing comes right after the commit to be modified,
       and change the action of the moved commit from pick to squash (or
       fixup).

Разница между сквошем и фиксацией заключается в том, что во время перебазирования squash операция предложит вам объединить сообщения оригинала и коммита, в то время как fixup Операция сохранит исходное сообщение и отбросит сообщение из фиксации фиксации.

Проще говоря, при перебазировании серии коммитов каждый коммит помечается как squash, дает вам возможность использовать свое сообщение как часть pick или же reword отправить сообщение.

Когда вы используете fixup сообщение от этого коммита отбрасывается.

Если вопрос в том, в чем разница междуsquash а также fixupв git при выполнении git rebase --interactive ответом будет сообщение фиксации.

s, squash <commit> = использовать фиксацию, но слиться с предыдущей фиксацией

f, fixup <commit>= как "squash", но удалить сообщение журнала этой фиксации


Например:

pick 22a4667 father commit message
squash 46d7c0d child commit message # case 1
# fixup 46d7c0d child commit message # case 2

Сообщение фиксации после перебазирования в случае 1 будет:

father commit message

child commit message

а сообщение фиксации в случае 2:

father commit message
# no sub messages

Из git-rebase doc:

Если вы хотите сложить два или более коммитов в один, замените команду "pick" для второго и последующих коммитов на "squash" или "fixup". Если у коммитов были разные авторы, свернутый коммит будет приписан автору первого коммита. Предлагаемое сообщение коммита для свернутого коммита - это конкатенация сообщений коммита первого коммита и сообщений с командой "squash", но пропускает коммит сообщения коммитов с помощью команды "fixup".

Оба и позволят вносить изменения в код с помощью соответствующих различий. (обычно не упоминается)

Различие между и заключается в том, как обрабатываются сообщения фиксации .

В случае, если исходное сообщение фиксации остается неизменным, а любой текст в сообщении фиксации игнорируется (бесцеремонно сбрасывается).

В этом случае оба сообщения фиксации объединяются («объединяются») одно за другим и предлагаются редактору пользователя, чтобы их можно было объединить / объединить вместе по желанию пользователя.

Первоначальное комбинированное сообщение (сквош) будет содержать отметки комментариев, показывающие, где сообщения начинаются и заканчиваются. Множественные и s могут быть применены.

Терминология может сбивать с толку при обсуждении небольших исправлений кода (без необходимости изменять сообщение), так как часто можно предположить, что код «втиснут», когда на самом деле не требуется.

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

Я используюgit version 2.32.1


Давайте представим, что вы перемещаете ветку, вызываемуюmain. Для этого вы выполняете интерактивную перебазировку с помощью команды, пока у вас естьmy-new-featureФилиал проверен.

(Если вы используете графический интерфейс для git, например, OP использует расширения Git, если они обновлены, они также должны содержать эти новые параметры)

Бегgit rebase -i mainоткрывает следующее в вашем редакторе:

      pick 996b0 work in progress
pick 59f3a feature finished

# Rebase b6914..59f3a onto b6914 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message

Обратите внимание на новый-C | -cфлаг.

s, squash = использовать фиксацию, но объединяться с предыдущей фиксацией

f, исправление [-C | -c] = как "сквош", но сохранить только сообщение журнала предыдущей фиксации, если не используется -C, и в этом случае сохранить только сообщение этой фиксации; -c тоже самое, что и -C, но открывает редактор


Глядя на наши 2 коммита:

      pick 996b0 work in progress
pick 59f3a feature finished

Давайте представим, что вы хотите объединить их вместе (это можно сделать с помощью или ), но вы хотите сохранить только полезное сообщение коммита второго коммита.


Используя, как мы это делали в прошлом, вот так:

      pick 996b0 work in progress
f 59f3a feature finished

не будет делать то, что мы хотим. Он объединит коммиты вместе, но оставит нас с сообщением коммита, что не очень полезно.


Мы могли бы использовать так:

      pick 996b0 work in progress
s 59f3a feature finished

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


Вот где новая опция, к которой мы можем перейти, очень удобна.

      pick 996b0 work in progress
f -C 59f3a feature finished

Это объединит коммиты вместе, но отброситwork in progressзафиксировать сообщение и сохранить толькоfeature finishedзафиксировать сообщение.


Эти новые опции делаютfixupеще более мощный и позволяет вам еще меньше полагаться на использованиеsquashкогда вам это не нужно.

Я возился с расширениями git и не мог заставить его сжать много коммитов в один. Для этого мне пришлось прибегнуть к командной строке и найти этот пост полезным

git rebase -i Head~2

Это интерактивная перебазировка, и обратите внимание на следующее:

  • ~ 2 здесь относится к тому, сколько коммитов вы хотите задействовать в этой операции, включая текущий заголовок
  • Вы должны отредактировать последующее интерактивное окно редактирования, оставить первый элемент как "выбрать" и заменить последующие строки на "сквош". Инструкции в приведенной выше ссылке намного понятнее, если они непрозрачны.

Почему бы не спросить самого git? Когда вы переустанавливаетеgit-bash, он говорит:

pick 512b1d7 (some comment)
# Rebase 621b2e4..512b1d7 onto 621b2e4 (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
D:/code/fenixito-legacy-api/.git/rebase-merge/git-rebase-todo [unix] (11:57 23/10/2019)                                         1,1 start
"D:/code/xxx/.git/rebase-merge/git-rebase-todo" [UNIX] 27L, 1170C

Итак, вы видите:

s, squash = использовать фиксацию, но объединить с предыдущей фиксацией

f, fixup = как "squash", но удалить сообщение журнала этой фиксации

Другие вопросы по тегам