В чем разница между "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".
Оба и позволят вносить изменения в код с помощью соответствующих различий. (обычно не упоминается)
Различие между и заключается в том, как обрабатываются сообщения фиксации .
В случае, если исходное сообщение фиксации остается неизменным, а любой текст в сообщении фиксации игнорируется (бесцеремонно сбрасывается).
В этом случае оба сообщения фиксации объединяются («объединяются») одно за другим и предлагаются редактору пользователя, чтобы их можно было объединить / объединить вместе по желанию пользователя.
Первоначальное комбинированное сообщение (сквош) будет содержать отметки комментариев, показывающие, где сообщения начинаются и заканчиваются. Множественные и
Терминология может сбивать с толку при обсуждении небольших исправлений кода (без необходимости изменять сообщение), так как часто можно предположить, что код «втиснут», когда
В дополнение к предыдущим ответам я хотел выделить новые параметры, которые также можно использовать, что еще больше отличает их от использования .
Я использую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", но удалить сообщение журнала этой фиксации