Git squash: Как сжимать коммиты в Git с помощью git squash | by Рудольф Коршун | NOP::Nuances of Programming
Как сжимать коммиты в Git с помощью git squash | by Рудольф Коршун | NOP::Nuances of Programming
Для начала давайте разберемся: что же это вообще такое — git squash
.
Git squash
— это прием, который помогает взять серию коммитов и уплотнить ее. Например, предположим: у вас есть серия из N коммитов и вы можете путем сжатия преобразовать ее в один-единственный коммит. Сжатие через git squash
в основном применяется, чтобы превратить большое число малозначимых коммитов в небольшое число значимых. Так становится легче отслеживать историю Git.
Также этот прием используется при объединении ветвей. Чаще всего вам будут советовать всегда сжимать коммиты и выполнять перебазирование с родительской ветвью (например, master
или develop
). В таком случае история главной ветки будет содержать только значимые коммиты, без ненужной детализации.
Как именно делать git squash
Возьмем для примера следующую историю Git:
Здесь видны последние три коммита. В сообщениях к ним поясняется, что мы добавили новый файл и какое-то содержимое. Лучше заменить их одним единственным коммитом о том, что произошло добавление нового файла с некоторым содержимым. Итак, давайте посмотрим, как сжать последние три коммита в один:
git rebase -i HEAD~3
git rebase -i
— интерактивный инструмент, который помогает сжимать коммиты. У него много возможностей, но давайте сосредоточимся на git squash
.
Если вы не очень хорошо знакомы с перебазированием — не волнуйтесь. Сжатие коммитов — одна из самых простых операций, которые выполняются через интерактивный git-rebase (т.е. git rebase -i
). HEAD~3
означает, что мы берем последние три коммита.
Далее откроется редактор. Посмотрите, rebase -i
охватывает только последние три коммита, и обратите внимание на количество опций. Нас, однако, интересует только squash
. Давайте же приведем все к одному коммиту.
Как видите, для сжатия мы отметили последние два коммита с помощью команд squash
или s
.
В примере, приведенном выше, коммиты, предназначенные для сжатия, будут слиты с основным коммитом — тем, который отмечен командой pick
. Отметив коммиты, сохраните изменения в редакторе.
Далее rebase -i
снова откроет редактор для ввода сообщения о коммите, как на картинке ниже:
Отредактировав и сохранив сообщения, можете закрыть редактор. Обратите внимание: строки, которые начинаются с #
, будут проигнорированы. После этого журнал Git будет выглядеть следующим образом:
Здесь изменилось сообщение о коммите, и обратите внимание: три коммита “склеились” в один. Также изменился хэш коммита. Через git rebase
всегда создается новый коммит, содержащий соответствующие изменения.
Так что используйте этот инструмент с осторожностью.
Помните: сжатие коммитов меняет историю Git, поэтому не рекомендуется сжимать ветвь, если вы уже отправили ее в удаленный репозиторий. Всегда выполняйте сжатие до того, как отправить пуш с изменениями.
Применение fixup для сжатия коммитов
Для того, чтобы сжимать коммиты, также можно воспользоваться опцией fixup
. Это то же самое, что и squash
, только без возможности редактировать сообщение о коммите. Сообщение о коммите в таком случае будет целиком взято из “целевого” коммита — того, который был выбран с помощью pick
. Давайте посмотрим на примере:
Воспользуйтесь командой fixup
или f
, чтобы выбрать коммиты. После этого сохраните изменения в редакторе. Инструмент интерактивного перебазирования сохранит сообщение о коммите. В результате история Git будет выглядеть так:
Обратите внимание: хэш коммита также изменился, а сообщение о коммите берется из “основного” коммита, с которым были сжаты другие два.
Применение сжатия при слиянии ветвей
Git также предоставляет возможность сжатия при объединении ветвей. Во многих случаях она может оказаться полезной. Чтобы добавить новый функционал или поправить какие-то баги, нам понадобится то и дело что-то изменять в ветвях. Поэтому, когда мы будем готовы слить эти изменения в основную ветвь (master
или develop
), для начала следует применить сжатие.
Давайте рассмотрим следующую команду:
git merge --squash target_branch_name
Она берет все коммиты из целевой ветви, сжимает их и сохраняет все изменения в текущей ветви. Затем вы можете зафиксировать все изменения в одном коммите. На примере это выглядит так:
Здесь мы провели слияние нашей ветви с develop с помощью --squash
. Git воспримет и сохранит сделанные таким образом изменения.
Сжатие коммитов через Github
Возможность сжимать коммиты предоставляет и Github. Эта функция особенно полезна при пулл-реквесте.
Сначала производится сжатие, затем — слияние. Так что вместо пяти коммитов получится один.
Как видно на картинке, выполняется всего один коммит с соответствующим сообщением.
Спасибо за чтение! Надеюсь, вы почерпнули из статьи что-то новое 🙂
Читайте также:
Читайте нас в Telegram, VK и Яндекс.Дзен
Как сжимать коммиты в Git с помощью git squash
Для начала давайте разберемся: что же это вообще такое — git squash
.
Git squash
— это прием, который помогает взять серию коммитов и уплотнить ее. Например, предположим: у вас есть серия из N коммитов и вы можете путем сжатия преобразовать ее в один-единственный коммит. Сжатие через git squash
в основном применяется, чтобы превратить большое число малозначимых коммитов в небольшое число значимых. Так становится легче отслеживать историю Git.
Также этот прием используется при объединении ветвей. Чаще всего вам будут советовать всегда сжимать коммиты и выполнять перебазирование с родительской ветвью (например, master
или develop
). В таком случае история главной ветки будет содержать только значимые коммиты, без ненужной детализации.
Как именно делать git squash
Возьмем для примера следующую историю Git:
Здесь видны последние три коммита. В сообщениях к ним поясняется, что мы добавили новый файл и какое-то содержимое. Лучше заменить их одним единственным коммитом о том, что произошло добавление нового файла с некоторым содержимым. Итак, давайте посмотрим, как сжать последние три коммита в один:
git rebase -i HEAD~3
git rebase -i
— интерактивный инструмент, который помогает сжимать коммиты. У него много возможностей, но давайте сосредоточимся на git squash
.
Если вы не очень хорошо знакомы с перебазированием — не волнуйтесь. Сжатие коммитов — одна из самых простых операций, которые выполняются через интерактивный git-rebase (т.е. git rebase -i
). HEAD~3
означает, что мы берем последние три коммита.
Далее откроется редактор. Посмотрите, rebase -i
охватывает только последние три коммита, и обратите внимание на количество опций. Нас, однако, интересует только squash
. Давайте же приведем все к одному коммиту.
Как видите, для сжатия мы отметили последние два коммита с помощью команд squash
или s
.
В примере, приведенном выше, коммиты, предназначенные для сжатия, будут слиты с основным коммитом — тем, который отмечен командой pick
. Отметив коммиты, сохраните изменения в редакторе.
Далее rebase -i
снова откроет редактор для ввода сообщения о коммите, как на картинке ниже:
Отредактировав и сохранив сообщения, можете закрыть редактор. Обратите внимание: строки, которые начинаются с #
, будут проигнорированы. После этого журнал Git будет выглядеть следующим образом:
Здесь изменилось сообщение о коммите, и обратите внимание: три коммита “склеились” в один. Также изменился хэш коммита. Через git rebase
всегда создается новый коммит, содержащий соответствующие изменения.
Так что используйте этот инструмент с осторожностью.
Помните: сжатие коммитов меняет историю Git, поэтому не рекомендуется сжимать ветвь, если вы уже отправили ее в удаленный репозиторий. Всегда выполняйте сжатие до того, как отправить пуш с изменениями.
Применение fixup для сжатия коммитов
Для того, чтобы сжимать коммиты, также можно воспользоваться опцией fixup
. Это то же самое, что и squash
, только без возможности редактировать сообщение о коммите. Сообщение о коммите в таком случае будет целиком взято из “целевого” коммита — того, который был выбран с помощью pick
. Давайте посмотрим на примере:
Воспользуйтесь командой fixup
или f
, чтобы выбрать коммиты. После этого сохраните изменения в редакторе. Инструмент интерактивного перебазирования сохранит сообщение о коммите. В результате история Git будет выглядеть так:
Обратите внимание: хэш коммита также изменился, а сообщение о коммите берется из “основного” коммита, с которым были сжаты другие два.
Применение сжатия при слиянии ветвей
Git также предоставляет возможность сжатия при объединении ветвей. Во многих случаях она может оказаться полезной. Чтобы добавить новый функционал или поправить какие-то баги, нам понадобится то и дело что-то изменять в ветвях. Поэтому, когда мы будем готовы слить эти изменения в основную ветвь (master
или develop
), для начала следует применить сжатие.
Давайте рассмотрим следующую команду:
git merge --squash target_branch_name
Она берет все коммиты из целевой ветви, сжимает их и сохраняет все изменения в текущей ветви. Затем вы можете зафиксировать все изменения в одном коммите. На примере это выглядит так:
Здесь мы провели слияние нашей ветви с develop с помощью --squash
. Git воспримет и сохранит сделанные таким образом изменения.
Сжатие коммитов через Github
Возможность сжимать коммиты предоставляет и Github.
# «редактируем» последний коммит, добавляя в него содержимое индекса
# (на самом деле создаём новый коммит с тем же сообщением и переставляем на него ветку)
git commit —amend —no-edit
Поскольку вы переписали свою ветку, нужно будет запушить с -f.
git push -f origin mybranch
Как использовать git merge —squash?
У меня есть удаленный сервер Git, вот сценарий, который я хочу выполнить:
Для каждой ошибки/функции я создаю другой Git branch
Я продолжаю фиксировать свой код в этом Git branch с неофициальными Git сообщениями
В верхнем репозитории мы должны сделать один коммит для одной ошибки с официальным сообщением Git
Итак, как я могу объединить свою ветвь с удаленной ветвью, чтобы они получили только одну фиксацию(коммит) для всех моих чеков (я даже хочу предоставить сообщение о фиксации(коммита) для этого)?
git
git-merge
git-squash
Поделиться
Источник
SunnyShah
15 марта 2011 в 07:47
13 ответов
- git merge —squash (ветвь) дает ошибку
В настоящее время у меня есть ветка 1-user-model . Отсюда я затем проверил и создал ветку 1-user-model-squash . Затем , когда я пытаюсь запустить git merge —squash 1-user-model , я получаю эту ошибку. фатальная ошибка: невозможно совместить —сквош —с no-ff. Я также попытался проверить master ,…
- Git squash и merge
Может ли кто-нибудь сказать мне, в чем разница между этими двумя командами: git merge —squash и git merge —no-ff
2095
Допустим, ваша ветвь исправления ошибок называется bugfix
, и вы хотите объединить ее в master
:
git checkout master
git merge --squash bugfix
git commit
Это приведет к тому, что все коммиты из ветви bugfix
будут скомканы в 1 коммит и объединены с вашей ветвью master
.
Объяснение :
git checkout master
Переключается на вашу ветку master
.
git merge --squash bugfix
Берет все коммиты из ветви bugfix
и группирует их для коммита 1 с вашей текущей ветвью.
(фиксация(коммит) слияния не отображается; вы можете разрешить конфликты вручную перед следующей фиксацией(коммитом))
git commit
Создает единую фиксацию(коммит) из Объединенных изменений.
Опущение параметра -m
позволяет изменить черновик сообщения фиксации(коммита), содержащего все сообщения из ваших сжатых коммитов, перед завершением фиксации(коммита).
Поделиться
abyx
15 марта 2011 в 08:16
132
То, что наконец прояснило это для меня, было комментарием , показывающим, что:
git checkout main
git merge --squash feature
является ли это эквивалентом делания:
git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .
Когда я хочу объединить ветвь объекта со 105(!!) коммитами и сжать их все в один, я не хочу git rebase -i origin/master
, потому что мне нужно отдельно разрешать конфликты слияния для каждого из промежуточных коммитов (или, по крайней мере, те, которые git не может вычислить сам). Использование git merge --squash
дает мне желаемый результат-один коммит для слияния целой ветви объектов. И мне нужно сделать только самое большее одно ручное разрешение конфликта.
Поделиться
Dan Kohn
19 августа 2014 в 15:59
98
Вы хотите слиться с опцией squash. 1
git commit
Поделиться
qwertzguy
13 марта 2015 в 17:50
19
Слияние ветви newFeature
в ветвь master
с пользовательской фиксацией(коммитом):
git merge --squash newFeature && git commit -m 'Your custom commit message';
Если вместо
этого вы сделаете
git merge --squash newFeature && git commit
, то получите сообщение о фиксации(коммита), которое будет включать все фиксации(коммита) ветви newFeature
, которые вы можете настроить.
Я подробно объясняю это здесь: https://youtu.be/FQNAIacelT4
Поделиться
Vagelis Prokopiou
17 марта 2017 в 11:10
11
Я знаю, что этот вопрос не касается конкретно Github, но поскольку Github так широко используется, и это тот ответ, который я искал, я поделюсь им здесь.
Github имеет возможность выполнять сквош-слияния в зависимости от параметров слияния, включенных для репозитория.
Если слияния сквоша включены, то параметр «Squash and merge» должен появиться в раскрывающемся списке под кнопкой «Merge».
Поделиться
Aaron
22 февраля 2019 в 23:14
4
Предположим, вы работали в feature/task1 с несколькими фиксациями(коммитами).
Перейдите в свою ветвь проекта (project/my_project)
git checkout project/my_project
Создание новой ветви (feature/task1_bugfix)
git checkout -b feature/task1_bugfix
Мардж с возможностью
--squash
git merge --squash feature/task1
Создайте один коммит
git commit -am "add single comments"
Подтолкнуть вашу ветку
git push --set-upstream origin feature/task1_bugfix
Поделиться
Farid Haq
27 декабря 2018 в 00:24
1
Для Git
Создание новой функции
через Terminal/Shell:
git checkout origin/feature/<featurename>
git merge --squash origin/feature/<featurename>
Это не фиксирует его, позволяет вам сначала просмотреть его.
Затем зафиксируйте и завершите функцию из этой новой ветви, а также удалите/проигнорируйте старую (ту, на которой вы делали dev).
Поделиться
Demian Berisford-Maynard
05 октября 2017 в 14:33
1
если вы получаете ошибку: фиксация(коммит) невозможна, потому что у вас есть несмешанные файлы.
git checkout master
git merge --squash bugfix
git add .
git commit -m "Message"
исправлены все конфликтные файлы
git add .
вы также можете использовать
git add [filename]
Поделиться
ResUta
18 декабря 2019 в 07:37
0
Чтобы раздавить вашу местную ветвь, прежде чем толкать ее:
проверьте ветвь, о которой идет речь, чтобы работать над ней, если она еще не проверена.
Найдите sha самого старого коммита, который вы хотите сохранить.
Создайте/извлеките новую ветвь (tmp1) из этой фиксации(коммита).
git checkout -b tmp1 <sha1-of-commit>
Слейте исходную ветвь в новую, раздавив ее.
git merge --squash <original branch>
Зафиксируйте изменения, созданные слиянием, с помощью сводного сообщения о фиксации(коммита).
git commit -m <msg>
Проверьте исходную ветвь, которую вы хотите раздавить.
git checkout <branch>
Сбросьте исходную фиксацию(коммит) sha, которую вы хотите сохранить.
git reset --soft <sha1>
Перебазируйте эту ветвь на основе новой ветви tmp1.
git rebase tmp1
Вот и все — теперь удалите временную ветвь tmp1, как только вы убедитесь, что все в порядке.
Поделиться
Jool
30 марта 2020 в 13:07
0
Вы можете использовать инструмент, который я создал, чтобы облегчить этот процесс: git-squash . Например, чтобы раздавить все коммиты на ветке объекта, которая была разветвлена от главной ветви, напишите:
git squash master
git push --force
Поделиться
sheerun
01 июня 2020 в 19:37
0
git checkout YOUR_RELEASE_BRANCH
git pull
git checkout -b A_NEW_BRANCH
git merge --squash YOUR_BRANCH_WITH_MULTIPLE_COMMITS
git commit -am "squashing all commits into one"
git push --set-upstream origin A_NEW_BRANCH
Поделиться
izy
27 августа 2020 в 03:23
-1
Воспользуйся
git status
чтобы проверить, что происходит.
Затем
git checkout master
git merge --squash bugfix
git add (add which files you want or use wildcard command like ".")
Затем
git commit -m "message"
А теперь последнее но не менее важное
git push -u origin master
Здесь origin
может быть другим пультом дистанционного управления, который вы предпочитаете.
Поделиться
Let’s L.C.E
19 августа 2020 в 10:28
Похожие вопросы:
Различия между Git merge —squash и —no-commit
Как говорится в названии, я не совсем понимаю разницу между a git merge —squash и a git merge —no-commit . Насколько я понимаю страницу справки для git merge , обе команды оставят меня в. ..
Почему я не могу использовать git merge —squash с —no-ff?
Я пытаюсь использовать git merge —squash с параметром —no-ff, но git не позволяет. У кого-нибудь есть сахар, чтобы помочь мне? Я не могу использовать быстрое слияние вперед, и мне нужно…
Отмените git squash merge и git merge снова
У меня есть 2 удаленных ветки и мастер. Сквош merge был сделан на ветке функции от мастера. Более поздние коммиты происходили как в основной, так и в функциональной ветвях. Теперь я попытался…
git merge —squash (ветвь) дает ошибку
В настоящее время у меня есть ветка 1-user-model . Отсюда я затем проверил и создал ветку 1-user-model-squash . Затем , когда я пытаюсь запустить git merge —squash 1-user-model , я получаю эту…
Git squash и merge
Может ли кто-нибудь сказать мне, в чем разница между этими двумя командами: git merge —squash и git merge —no-ff
git `merge —squash` не добавляет заголовок «Merge» для фиксации(коммита)
Мне было интересно, как все инструменты узнают, какие ветви/коммиты объединяются, пока я не нашел заголовок Merge в коммите. Мой вопрос таков: почему a git merge —squash не добавляет этот…
Merge a PR (не близко) от git —squash
Когда я развиваюсь в ветке и превращаю ее в мастера с: git merge —no-ff $BRANCH git push origin HEAD Он сливает PR в Github (фиолетовый значок). Но если я захочу merge его раздавят: git merge…
Каковы правильные варианты использования «git merge —squash»?
Некоторые люди любят git merge —squash по следующей причине: Сжатие до одного коммита дает вам возможность очистить грязные коммиты WIP и предоставить хорошее обоснование для изменений, которые вы…
Последующее слияние после `merge —squash` вызывает конфликты
Нормальное слияние: $ git merge feature01 $ git merge feature02 Все работает нормально. сквош слияние: $ git merge —squash feature01 # OK $ git merge —squash feature02 Auto-merging src/aaa.js…
Почему ‘ git merge <branch> —squash` не делает коммит?
При выполнении обычного merge, например git merge <branch> , git создает коммит merge и обновляет HEAD текущей ветви до этого коммита. Однако при выполнении сквоша merge, например git merge…
Squash последних git коммитов в один – Diary of madman
От переводчика: Оригинал статьи
От переводчика: Перевел заметку по git squash чтобы, наконец, запомнить как это делать.
В git есть возможность сжимать (to squash) несколько последних коммитов в один. Это замечательный способ группировать несколько мелких изменений в одно перед тем как поделиться кодом с остальными (командой или сообществом, например). Ниже описан способ как это сделать. Допустим, ваша история коммитов выглядит так:
* df71a27 - (HEAD feature_x) Updated CSS for new elements (4 minutes ago)
* ba9dd9a - Added new elements to page design (15 minutes ago)
* f392171 - Added new feature X (1 day ago)
* d7322aa - (origin/feature_x) Proof of concept for feature X (3 days ago)
Здесь представлена ветка feature_x
. Вы уже запушили коммит d7322aa
с наивной реализацией новой фичи Х. После этого вы доработали некоторые моменты, добавили элементы и поправили CSS и теперь хотите сжать последние три коммита в один, чтобы история выглядела симпатичнее.
Для этого, потребуется команда:
Она откроет ваш текстовый редактор с содержимым:
pick f392171 Added new feature X
pick ba9dd9a Added new elements to page design
pick df71a27 Updated CSS for new elements
Теперь вы можете указать git, что делать с каждым коммитом. Давайте оставим коммит f392171
тот где мы изначально добавили нашу фичу и сожмем остальные два в него, избавившись от мусора. Изменим файл таким образом:
pick f392171 Added new feature X
squash ba9dd9a Added new elements to page design
squash df71a27 Updated CSS for new elements
После этого сохраним файл и выйдем из редактора. Git сожмет коммиты в один и на этом все!
Важное замечание: Не сжимайте коммиты, которыми вы уже поделились с остальными. Это изменяет историю и приведет к проблемам у ваших коллег.
#Git
#Tutorial
Стратегии слияния в Git: параметры и примеры
Когда работа завершена, протестирована и готова к передаче в основную линию разработки, ваша команда должна выбрать стратегию слияния. В этой статье рассматриваются разные стратегии и объясняется, как работает Atlassian. По прочтении у вас будет достаточно знаний, чтобы выбрать оптимальный для своей команды вариант.
Стратегии слияния в Git
Под слиянием подразумевается объединение двух веток. Git пытается найти общий базовый коммит для двух или более указателей. Есть несколько методов поиска. Они называются «стратегиями слияния». Когда Git находит общий базовый коммит, создается коммит слияния, который объединяет изменения определенных коммитов. С технической точки зрения, коммит слияния — это обычный коммит с двумя родителями.
Команда git merge
автоматически выбирает стратегию слияния, если она не указана явным образом. Команды git merge
и git pull
могут использоваться с параметром -s
(стратегия). К параметру -s
можно добавить имя стратегии слияния, которую вы хотите использовать. Если стратегия явно не указана, Git выберет подходящую на основе предоставленных веток. Далее мы рассмотрим конкретные стратегии слияния.
Рекурсивная стратегия
git merge -s recursive branch2 branch3
Эта стратегия работает с двумя указателями HEAD. Она применяется по умолчанию при выполнении команды pull или merge для одной ветки. Рекурсивная стратегия позволяет обнаруживать и обрабатывать слияния с переименованием, но на сегодняшний день не может использовать обнаруженные копии. Эта стратегия применяется по умолчанию при выполнении команд pull или merge для одной ветки.
Решение
git merge -s resolve branch2 branch3
Эта стратегия может разрешить только два указателя HEAD с помощью алгоритма трехстороннего слияния. Данная стратегия пытается выявлять неопределенности при перекрестном слиянии и считается в целом безопасной и быстрой.
Стратегия «Осьминог»
git merge -s octopus branch2 branch3 branch4 branchN
Стратегия «Осьминог» применяется по умолчанию для более чем двух голов. Когда передается больше одной ветки, «осьминог» включается автоматически. Если в слиянии есть конфликты, которые нужно разрешать вручную, эта стратегия блокирует попытку слияния. В основном она используется для объединения голов аналогичных функциональных веток.
Стратегия «Наша»
git merge -s ours branch2 branch3 branchN
Стратегия «Наша» (Ours) позволяет работать с множеством веток. Выходной результат слияния всегда соответствует указателю HEAD
текущей ветки. Эта стратегия называется «Наша», потому что она игнорирует все изменения из «чужих» веток. Ее назначение — объединение истории аналогичных функциональных веток.
Стратегия «Поддерево»
git merge -s subtree branchA branchB
Это разновидность рекурсивной стратегии. При слиянии A и B, если B — дочернее поддерево A, сначала обновляется B, чтобы отразить древовидную структуру A. Кроме того, обновляется родительское дерево, которое является общим для A и B.
Типы стратегий слияния в Git
Явное слияние
Явное слияние — стандартный вариант, который используется по умолчанию. Слияние называется явным, потому что создается новый коммит слияния. При этом меняется история коммита и явно показано, где выполнено слияние. Содержимое коммита слияния также является явным: можно увидеть, какие коммиты были родительскими для коммита слияния. Некоторые разработчики избегают явных слияний, чтобы не перегружать историю проекта.
Скрытое слияние с использованием методов rebase или fast-forward
В отличие от явного слияния, при неявном коммит слияния не создается. Из ветки с заданным указателем HEAD извлекается ряд коммитов, и они применяются к верхнему коммиту целевой ветки. Неявные слияния запускаются событиями перебазирования или ускоренными слияниями. Неявное слияние представляет собой определенный выбор коммитов из указанной ветки.
Склеивание (обычно без явного слияния)
Склеивание — это разновидность неявного слияния. Оно может выполняться во время интерактивного перебазирования. При склеивании коммиты берутся из целевой ветки и объединяются, или склеиваются, в один коммит. Затем получившийся коммит добавляется к HEAD
базовой ветки слияния. Обычно склеивание используется с целью сохранения «чистой» истории во время слияния. Целевая ветка слияния может иметь подробную историю частых коммитов. При склеивании и слиянии история коммитов становится одним склеенным коммитом ветки. Этот метод полезен для рабочих процессов Git
, в которых используются функциональные ветки.
Параметры рекурсивной стратегии слияния в Git
Рассмотренная выше рекурсивная стратегия имеет свой поднабор параметров.
Не следует путать этот параметр со стратегией слияния «Наша» (Ours). Он позволяет автоматически разрешать конфликты путем предпочтения «нашей» (ours) версии. Изменения с «их» (theirs) стороны внедряются автоматически, если в них отсутствуют конфликты.
Параметр theirs, напротив, отдает предпочтение чужому дереву слияния при разрешении конфликтов.
Этот параметр позволяет избежать ошибок слияния на неважных совпадающих линиях. Его лучше использовать, когда ветки, подлежащие слиянию, сильно расходятся.
Этот параметр позволяет явно указать алгоритм сравнения. Алгоритмы сравнения являются общими с командой git diff
.
ignore-* ignore-space-change
ignore-all-space
ignore-space-at-eol
ignore-cr-at-eol
Набор параметров, которые ориентированы на символы пробела. Любая линия, которая соответствует поднабору передаваемого параметра, будет проигнорирована.
Этот параметр запускает команды check-out и check-in во всех трех деревьях Git при разрешении конфликтов трехстороннего слияния. Он используется при слиянии веток с разными статусами checkin
/checkout
.
Отключает параметр renormalize. Это переопределяет переменную конфигурации merge.renormalize
.
Этот параметр игнорирует переименованные файлы во время слияния.
Это поведение по умолчанию. При рекурсивном слиянии поддерживается переименование файлов. Параметр n
можно использовать для передачи порогового значения сходства при переименовании. По умолчанию значение n
равно 100%
.
Этот параметр является вариантом стратегии «Поддерево» (Subtree). В то время как стратегия работает с двумя деревьями и задает способ их совмещения в общем родителе, этот параметр работает с метаданными пути дерева для обеспечения совмещения.
Наша политика слияния в Git
Atlassian настоятельно рекомендует использовать скрытые слияния. Причина простая: явные слияния оставляют следы и контекст в объединяемых функциях. Перед тем как отправлять функциональную ветку на проверку, следует выполнить очистку локальной истории с помощью команды rebase, однако это не меняет нашу политику, а дополняет ее.
Отмена изменений в GIT
Случай, который происходит довольно редко, но метко — это «Ааааа, я накосячил в git!!!». У меня случилось такое сегодня, когда я сделал rebase со squash’ем локальной ветки, не имея этих коммитов в другой ветке. Git не задумываясь слил мои коммиты в один и перенёс его, а мне нужно было сохранить исходную ветку, создав новый squash-коммит.
В общем, здесь я вспомнил про логи и отмену изменений. Git умеет отменять практически любые изменения. Все связанное с передвижением HEAD’а можно отменить reset’ом. В моём случае отмена rebase делается следующим способом…
Смотрим последние изменения (безопасно):
git reflog # для выхода жмем q # или смотреть последние 10 действий git reflog -n 10 # или тоже самое, но короче git reflog -10
Например, мой вывод
$ git reflog -n 6 703952e HEAD@{0}: rebase -i (finish): returning to refs/heads/BPN-3546 703952e HEAD@{1}: rebase -i (squash): BPN-3546 Add content type for Gauge in Drupal 9a23f7e HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits. c1b984f HEAD@{3}: rebase -i (pick): BPN-3546 Add content type for Gauge in Drupal c6be61c HEAD@{4}: rebase -i (start): checkout refs/heads/Gauge cf81cc3 HEAD@{5}: commit (amend): BPN-3546 Add content type for Gauge in Drupal
Дальше находим необходимую точку и откатываем код до её состояния. Здесь я вижу, что последние 5 чекпоинтов связаны с ребейзом. Я их пропускаю и двигаю HEAD назад на 6 изменений.
Здесь нужно понимать, что нельзя отменить какое-то одно, определённое действие совершённое ранее (если оно не последнее в истории). Можно лишь вернуться в фиксированную точку во времени, отменив все действия от текущего момента.
Флаг --hard
будет означать, что добавленные изменения будут удалены.
Например, если вы откатываете коммит, в котором добавили файл, то после отката этот файл будет удалён из репозитория.Здесь можно использовать флаг --soft
, который означает, что после отката коммита файл останется как не зафиксированные изменения.
git reset --hard HEAD@{5} # для Windows могут понадобиться кавычки git reset --hard "HEAD@{5}"
Полезные ссылки
Как сжать коммиты в Git
«Сквош» в Git означает объединение нескольких коммитов в один. Вы можете сделать это в любой момент (используя функцию Git «Интерактивное изменение базы»), хотя чаще всего это делается при слиянии ветвей.
Обратите внимание, что автономной команды git squash
не существует. Вместо этого сжатие — это, скорее, опция при выполнении других команд Git, таких как интерактивная перестановка или слияние.
Шпаргалка по Git
Не нужно запоминать все эти команды и параметры: получите нашу популярную «Шпаргалку по Git» — бесплатно!
Когда ограничивать ваши коммиты
Как уже было сказано, «раздавливание» ваших коммитов означает, что вы объединяете несколько существующих коммитов в один. Следует ли вам это делать или избегать, это — в некоторой степени — вопрос предпочтений: в некоторых командах, например, сжатие коммитов является предпочтительным способом слияния ветки функции обратно в давно работающую ветку, такую как «master» или основной».
Но зачем вам это делать? Давайте рассмотрим классический случай разработки функции в качестве примера: вы, вероятно, работали над отдельной веткой функции и произвели несколько коммитов в этом контексте. В зависимости от сложности и продолжительности вашей работы это может быть даже большое количество коммитов. В какой-то момент вы захотите снова объединить свою работу в основную ветку. Обычно это когда вы решаете раздавить или нет:
- (a) , если вы решите раздавить перед слиянием, то все эти отдельные коммиты из вашей функциональной ветки будут объединены в одну фиксацию.Таким образом, в основной истории фиксации будет отображаться только одна фиксация для этой интеграции.
- (b) , если вы решите ПРОТИВ раздавливания , все ваши индивидуальные коммиты будут сохранены как таковые.
Некоторые команды видят возможное преимущество в использовании (а) и использовании сквоша: вместо множества отдельных коммитов, которые могут быть ненужными и потенциально ошеломляющими, в основной истории коммитов появляется только один коммит. Это может быть полезно для поддержания порядка!
Однако нельзя сказать, что (а) или (б) — это «правильный» способ действий.У обоих подходов есть свои плюсы и минусы, так что это в основном вопрос предпочтений и условностей.
Как подавить ваши коммиты
Есть разные способы и инструменты, когда дело доходит до раздавливания коммитов. В этом посте мы поговорим о Interactive Rebase и Merge как о двух основных способах сквоша коммитов.
Интерактивная база
Вы можете вручную, раздавить свои коммиты в любое время, используя функцию Git «Интерактивное изменение базы».Углубление в Interactive Rebase выходит за рамки этой статьи (взгляните на First Aid Kit for Git , где есть серия бесплатных коротких видеороликов по этой теме), но мы вместе рассмотрим простой пример.
Допустим, вы завершили работу над новой веткой функций (в приведенном ниже примере «функция / логин») и теперь хотите объединить ее обратно в «главную» ветку. Но перед этим вам нужно очистить и сжать новые коммиты в один :
Мы можем сделать это, запустив сеанс интерактивной перебазировки:
$ git rebase -i HEAD ~ 3
Откроется окно редактора, в котором вы можете выбрать, как вы хотите манипулировать выбранной частью истории коммитов.Имейте в виду, что Interactive Rebase позволяет выполнять множество различных действий с вашей историей коммитов; в нашем примере, однако, нас интересует ключевое слово «сквош». Если вы отметите одну или несколько линий как «сквош», они будут объединены с приведенной выше:
После ввода сообщения о коммите для нового комбинированного коммита, интерактивное ребазирование завершено — и три старых коммита были объединены в один.
Наконечник
Использование интерактивного перебазирования в башне
В случае, если вы используете клиент Tower Git, использовать Interactive Rebase для сжатия некоторых коммитов очень просто: просто выберите коммиты, которые вы хотите объединить, щелкните правой кнопкой мыши любой из них и выберите «Squash Revisions. .. «из контекстного меню.
Слияние
Сжатие также возможно при слиянии ветвей:
$ git merge - функция сквоша / вход
Автоматическое объединение imprint.html
Удаление img / iconBlog.png
Автоматическое слияние about.html
Фиксация сквоша - HEAD не обновляется
Автоматическое слияние прошло хорошо; остановлен перед фиксацией по запросу
Эффект очень похож на то, что мы обсуждали ранее: все изменения будут объединены так же, как и при обычном слиянии, но с использованием параметра --squash
, вместо коммита слияния будет автоматически создается , у вас остается локальных изменений в вашей рабочей копии , которые вы затем можете зафиксировать самостоятельно.
В конце концов, это позволяет избежать автоматической фиксации, которая обычно происходит в результате слияния. Будет казаться, что работа над вашей функцией была произведена всего за одну фиксацию.
Запросы на извлечение
Эта стратегия — использование сквоша при слиянии — часто используется, когда Pull Request закрыт. Платформы для размещения кода, такие как GitHub, GitLab или Bitbucket, поддерживают это в качестве опции при объединении Pull Request:
Узнать больше
github — что значит сквошировать коммиты в git?
У команды rebase есть несколько замечательных опций, доступных в режиме --interactive
(или -i
), и одна из наиболее широко используемых — это возможность сквошировать коммиты.Это делает небольшие коммиты и объединяет их в более крупные, что может быть полезно, если вы завершаете рабочий день или просто хотите по-другому упаковать свои изменения. Мы собираемся обсудить, как это легко сделать.
Предупреждение: Делайте это только для коммитов, которые не были отправлены во внешний репозиторий. Если другие основывают работу на коммитах, которые вы собираетесь удалить, может возникнуть множество конфликтов. Только не переписывайте свою историю, если ею поделились с другими.
Допустим, вы только что сделали несколько небольших коммитов и хотите сделать из них одну большую. История нашего репозитория на данный момент выглядит так:
Последние 4 коммита были бы намного счастливее, если бы они были объединены вместе, поэтому давайте сделаем это с помощью интерактивного переназначения:
$ git rebase -i HEAD ~ 4
pick 01d1124 Добавление лицензии
pick 6340aaa Перенос лицензии в отдельный файл
pick ebfd367 Джекил осознал себя.
pick 30e0ccb Также изменил слоган в двоичном файле.# Rebase 60709da..30e0ccb на 60709da
#
# Команды:
# p, pick = использовать фиксацию
# e, edit = использовать фиксацию, но не вносить поправки
# s, squash = использовать фиксацию, но сливается с предыдущей фиксацией
#
# Если вы удалите здесь строчку, ЧТО COMMIT БУДЕТ УТЕРЯНЫ.
# Однако, если вы удалите все, перебазирование будет прервано.
#
Итак, здесь произошло несколько вещей. Прежде всего, я сказал Git, что хочу выполнить перебазирование с использованием последних четырех коммитов, из которых HEAD находится с HEAD ~ 4. Теперь Git поместил меня в редактор с приведенным выше текстом и небольшим объяснением того, что можно сделать.На этом экране вам доступно множество опций, но сейчас мы просто собираемся объединить все в одну фиксацию. Итак, изменение первых четырех строк файла на это поможет:
pick 01d1124 Добавление лицензии
squash 6340aaa Перенос лицензии в отдельный файл
squash ebfd367 Джекил осознал себя.
squash 30e0ccb Также изменил слоган в двоичном файле.
В основном это указывает Git объединить все четыре коммита в первый коммит в списке.Как только это будет сделано и сохранено, появится другой редактор со следующим текстом:
# Это комбинация 4 коммитов.
# Сообщение первого коммита:
Добавление лицензии
# Это второе сообщение коммита:
Перенос лицензии в отдельный файл
# Это третье сообщение коммита:
Джекил осознал себя.
# Это 4-е сообщение коммита:
Также изменился слоган в двоичном файле.
# Пожалуйста, введите сообщение фиксации для ваших изменений. Линии начинаются
# с '#' будет проигнорировано, а пустое сообщение прервет фиксацию.# Явные пути указаны без -i или -o; предполагая - только пути ...
# В настоящее время нет ни в одной ветке.
# Изменения, которые необходимо зафиксировать:
# (используйте "git reset HEAD <файл> ...", чтобы отключить сцену)
#
# новый файл: LICENSE
# изменено: README.textile
# изменено: Rakefile
# изменено: bin / jekyll
#
Поскольку мы объединяем так много коммитов, Git позволяет вам изменять сообщение нового коммита на основе остальных коммитов, задействованных в процессе.Отредактируйте сообщение по своему усмотрению, затем сохраните и закройте. Как только это будет сделано, ваши коммиты будут успешно отменены!
Создан коммит 0fc4eea: Создание файла лицензии и создание самосознания jekyll.
Изменено 4 файла, 27 вставок (+), 30 удалений (-)
режим создания 100644 ЛИЦЕНЗИЯ
Успешно перебазирован и обновлен refs / Heads / master.
А если еще раз взглянуть на историю…
Итак, до сих пор это было относительно безболезненно. Если вы столкнетесь с конфликтами во время перебазирования, их обычно довольно легко разрешить, и Git проведет вас через все, что возможно.Основы этого — исправить конфликт, о котором идет речь, git добавить
файл, а затем git rebase --continue
возобновит процесс. Конечно, выполнение git rebase --abort
вернет вас в предыдущее состояние, если вы захотите. Если по какой-то причине вы потеряли фиксацию при перебазировании, вы можете использовать журнал ссылок, чтобы вернуть его.
Подробности можно найти по этой ссылке.
Руководство для начинающих по сжатию коммитов с помощью Git Rebase | Сэм Линдстром
Git — это система контроля версий, обычно используемая разработчиками программного обеспечения для управления постоянно меняющейся кодовой базой. Пользователи «фиксируют» свои изменения в локальном или удаленном репозитории вместе с короткой пояснительной запиской. Частично полезность Git заключается в его быстрой и легкой способности отделять новую работу от существующего проекта, сохраняя критические изменения или новую функцию изолированными и отдельными до тех пор, пока они не будут готовы к интеграции в существующий проект.
Обычно команда разработчиков разграничивает работу по ветвям для отдельного разработчика или конкретной функции. Когда пришло время интегрировать эти изменения в основную ветвь проекта, команды могут стать довольно скрупулезными с историей фиксации своего проекта, стремясь сделать обновления краткими и удобочитаемыми.
В этом ключе я обнаружил, что для команд обычной практикой является сжатие или сжатие этих длинных цепочек сообщений коммитов в один или несколько коммитов перед объединением в основную ветку. Это полезно и на личном уровне. Если вы похожи на меня, вы ошибаетесь и часто совершаете коммиты. Побочным эффектом этого является обилие лишних сообщений о фиксации, которые не делают ничего, кроме путаницы в журнале git. Сжатие этих коммитов может сделать журнал более читаемым и понятным как для нас, так и для других.
Чтобы отобразить это, предположим, что у нас есть следующие 10 коммитов в ветке под названием «домашняя страница».
* 44d2565 (HEAD -> home_page, master) Создать границу навигации
* 1bd999c Стилизация пользовательских данных WIP. Добавить поле
* a135e04 Реализовать ввод поиска для отображения пользователя
* 76e5811 Добавить заполнение для элементов списка навигации
* 97178bd Отображение данных пользователя WIP
* c289adc Создать div для данных пользователя
* 14a64ff Добавить цвет фона для навигации и тела
* 83c9bbb Добавить список items to nav
* 60042c8 Добавить nav к приложению
* c0fa78d Начальная фиксация
Вы увидите, что у нас есть некоторые коммиты WIP (Work in Progress) вместе с дополнительными коммитами, относящимися к части домашней страницы нашего проекта. Это коммиты, которые мы, вероятно, захотим сжать, чтобы сделать наш журнал git более кратким.
Для интерактивной перебазировки коммитов мы можем следовать приведенному ниже формату и ввести нашу команду через командную строку:
git rebase -i HEAD ~
или
git rebase -i
Флаг «-i» в приведенном выше примере указывает, что это будет интерактивная перебазировка с «
В нашем примере мы хотели бы перебазировать все коммиты, продолжающие начальную фиксацию.Таким образом, мы должны ввести:
git rebase -i HEAD ~ 9
или
git rebase -i 60042c8
Эти команды откроют интерфейс ниже с параметрами для выполнения следующих действий:
p, выберите = использовать commit
r, перефразировать = использовать фиксацию, но отредактировать сообщение фиксации
e, отредактировать = использовать фиксацию, но остановить изменение
s, сквош = использовать фиксацию, но объединить с предыдущей фиксацией
f, исправление = как «сквош», но отбросить сообщение журнала этой фиксации
x, exec = запустить команду (остальная часть строки) с использованием оболочки
d, drop = удалить фиксацию
0 выбрать 60042c8 Добавить навигацию в приложение
1 выбор 83c9bbb Добавить элементы списка в навигацию
2 выбрать 14a64ff Добавить цвет фона для навигации и тела
3 выбрать c289adc Создать элемент div для данных пользователя
4 выбрать 97178bd Отображение данных пользователя WIP
5 выбрать 76e5811 Добавить заполнение в элементы списка навигации
6 выбрать a135e04 Реализовать поиск i nввод для пользовательского дисплея
7 pick 1bd999c Стилизация пользовательских данных WIP.Добавить поле
8 pick 44d2565 Создать границу навигации
9
10 # Перебазировать c0fa78d..44d2565 на c0fa78d (9 команд)
11 #
12 # Команды:
13 # p, pick = use commit
14 # r, reword = использовать фиксацию, но отредактировать сообщение фиксации
15 # e, edit = использовать фиксацию, но остановиться для изменения
16 # s, squash = использовать фиксацию, но объединиться с предыдущей фиксацией
17 # f, fixup = like "squash" , но отбросить сообщение журнала этой фиксации
18 # x, exec = run command (остальная часть строки) с использованием оболочки
19 # d, drop = remove commit
20 #
21 # Эти строки можно переупорядочить; они выполняются сверху вниз.
22 #
23 # Если вы удалите здесь строчку, КОМИТЕТ БУДЕТ УТЕРЯН.
24 #
25 # Однако, если вы удалите все, перебазирование будет прервано.
26 #
27 # Обратите внимание, что пустые коммиты закомментированы.
Мы хотели бы сжать сообщения коммитов в один коммит, который указывает, что мы добавили домашнюю страницу в наш проект. Для этого примера я буду использовать squash
вместо fixup
. Это сохранит все наши второстепенные сообщения о фиксации в одной окончательной сжатой фиксации.
Вкратце: Что, если бы мы хотели удалить один или несколько коммитов в приведенном выше примере? Вместо pick
мы могли бы использовать ключевое слово drop
, чтобы удалить эту фиксацию из нашего кода. В качестве альтернативы мы могли бы просто удалить строку фиксации, чтобы выполнить то же самое, но я предпочитаю явность drop
.
После перезагрузки ветки наш обновленный журнал git выглядит следующим образом.
* ca22552 (HEAD -> home_page) Добавить домашнюю страницу на веб-сайт
* c0fa78d Начальная фиксация
Сквош фиксируется в одну с Git
— Написано Triangles 17 ноября 2017 г.
• обновлено 21 декабря 2020 г.
• ID 60 —
Хороший способ сгруппировать некоторые изменения, особенно перед тем, как поделиться ими с другими.
В Git вы можете объединить несколько коммитов в один с помощью мощного интерактивного перебазирования . Это удобный инструмент, которым я пользуюсь довольно часто; Обычно я убираю свое рабочее пространство, объединяя несколько небольших промежуточных коммитов в один коммит, чтобы продвигать его вверх по течению.
Шаг 1: выберите начальную фиксацию
Первое, что нужно сделать, это вызвать git для запуска интерактивного сеанса перебазирования:
git rebase - интерактивная ГОЛОВКА ~ N
Или, короче:
git rebase -i HEAD ~ N
, где N — количество коммитов, к которым вы хотите присоединиться, , начиная с самого последнего .Например, это гипотетический список коммитов, взятых из команды git log
, а я работаю над общей функцией Z:
.
871adf Хорошо, функция Z полностью реализована --- более новая фиксация
0c3317 Ой, еще нет ...
87871a Я готов!
643d0e Очистка кода
afb581 Исправить то и то
4e9baa Классная реализация
d94e78 Подготовьте верстак для функции Z
6394dc Feature Y --- более старая фиксация
А вот что я хотел бы сделать:
871adf Хорошо, функция Z полностью реализована --- более новая фиксация --┐
0c3317 Ой, еще нет... |
87871a Я готов! |
643d0e Очистка кода | - Объедините их в один
afb581 Исправьте то и это |
4e9baa Классная реализация |
d94e78 Подготовьте верстак для функции Z ------------------- ┘
6394dc Feature Y --- более старая фиксация
Получение:
84d1f8 Feature Z --- более новая фиксация (результат rebase)
6394dc Feature Y --- более старая фиксация
Обратите внимание, как ребазирование генерирует новую фиксацию с новым хешем ( 84d1f8
в приведенном выше примере).Итак, в этом случае команда будет:
git rebase --interactive HEAD ~ [7]
, потому что я хочу объединить последние семь коммитов в один, а d94e78 Подготовьте верстак для функции Z
— седьмой.
У меня куча коммитов, которые нужно сквошить, мне нужно пересчитывать их один за другим?
Обратной стороной команды git rebase --interactive HEAD ~ [N]
является то, что вы должны угадывать точное количество коммитов, считая их один за другим.К счастью, есть другой способ:
git rebase --interactive [хеш фиксации]
Где [commit-hash]
— это хэш коммита непосредственно перед первым, который вы хотите перезаписать из . Итак, в моем примере команда будет:
git rebase - интерактивный 6394dc
Где 6394dc
— Feature Y
. Вы можете прочитать все это как:
Слить все мои коммиты поверх коммита
[commit-hash]
.
Намного проще, не правда ли?
Шаг 2: сбор и раздавливание
В этот момент появится выбранный вами редактор со списком коммитов, которые вы хотите объединить. Обратите внимание, что сначала это может сбить с толку, поскольку они отображаются в порядке , обратном , где более старый коммит находится наверху. Я добавил --- более старые коммиты
и --- новые коммиты
, чтобы было понятно, вы не найдете этих заметок в редакторе.
pick d94e78 Подготовьте рабочую среду для функции Z --- более ранняя фиксация
выбрать 4e9baa Классная реализация
выберите afb581 Исправьте это и это
выберите 643d0e Очистка кода
забрать 87871a Я готов!
pick 0c3317 Ой, пока нет...
выберите 871adf ОК, функция Z полностью реализована --- более новая фиксация
[...]
Под списком коммитов есть короткий комментарий (опущен в моем примере), в котором описаны все доступные операции. Во время интерактивной перестановки вы можете проделать множество хитростей, но пока давайте остановимся на основах. Наша задача здесь — пометить все коммиты как сжимаемые , , кроме первого / более старого : он будет использоваться в качестве отправной точки.
Вы помечаете фиксацию как подлежащую сжатию, изменив рядом с ней слово pick
на squash
(или s
для краткости, как указано в комментариях).Результат будет:
pick d94e78 Подготовьте рабочую среду для функции Z --- более ранняя фиксация
s 4e9baa Классная реализация
s afb581 Исправить то и то
s 643d0e Очистка кода
s 87871a Я готов!
s 0c3317 Ой, еще нет ...
s 871adf ОК, функция Z полностью реализована --- более новая фиксация
[...]
Сохраните файл и закройте редактор.
Шаг 3. Создайте новую фиксацию
Вы только что сказали Git объединить все семь коммитов в первый коммит в списке.Пришло время дать ему имя: ваш редактор снова всплывает с сообщением по умолчанию, состоящим из имен всех коммитов, которые вы раздавили.
Вы можете оставить все как есть, и сообщение о фиксации приведет к списку всех промежуточных фиксаций, как показано ниже:
Подготовьте рабочую среду для функции Z
Классная реализация
Исправить то и то
Очистка кода
Я готов!
Упс, еще нет ...
Хорошо, функция Z полностью реализована
Обычно я не хочу хранить такую информацию, поэтому я стираю сообщение по умолчанию и использую что-то более понятное, например . Реализованная функция Z
.
Источники
Stackoverflow — Git rebase интерактивно последние n коммитов (ссылка)
Stackoverflow — Как я могу объединить две коммиты в одну? (ссылка)
Gitready — Сжатие коммитов с перебазированием (ссылка)
Всегда сжимайте и переустанавливайте свои коммиты Git
Использование git для управления версиями обеспечивает эффективное сотрудничество в технических командах. Как и любой другой инструмент, при неправильном использовании он также может вызвать серьезные головные боли. Поработав с самыми разными размерами и динамикой команд, я обнаружил, что рабочий процесс squash and rebase
помогает сделать процесс совместной работы более эффективным и намного менее болезненным.
Что такое рабочий процесс перебазирования сквоша?
Это просто — перед тем, как вы объедините функциональную ветку обратно в свою основную ветвь (часто master
или разрабатывают
), ваша функциональная ветка должна быть сжата до одного сборочного коммита, а затем перебазирована из обновленной основной ветка. Вот разбивка.
Потяните ведущую ветвь
git pull origin master
Создать ветку ошибки / функции
git checkout -b имя ветки
Вносите необходимые изменения, используя необходимое количество коммитов.Убедитесь, что финальный коммит готов к сборке и все тесты пройдены.
Получите количество коммитов с начала вашей ветки. Есть несколько способов получить это. Вы можете просто git log
и подсчитать свои коммиты или
git log --graph --decorate --pretty = oneline --abbrev-commit
, который покажет график вашей истории журнала коммитов и может упростить визуализацию ваших коммитов. Иногда у вас будет достаточно большое количество коммитов, и подсчет может стать затруднительным.В этом случае возьмите SHA из последнего коммита, от которого ответвляется ваша ветка.
Сквош до 1 фиксации.
git rebase -i HEAD ~ [КОЛИЧЕСТВО КОМИТЕТОВ]
ИЛИ
git rebase -i [SHA]
Если вы ранее отправляли свой код в удаленную ветку, вам нужно будет принудительно отправить его.
git push origin имя ветки --force
Отделение кассы
мастер проверки git
Потяните ведущую ветвь
git pull origin master
Ошибка оформления заказа / функциональная ветка
git checkout branchName
Ребаза от мастера
git rebase master
Обращайтесь с любыми конфликтами и убедитесь, что ваш код компилируется и все тесты проходят.Принудительно нажать ветку на удаленный.
git push origin имя ветки --force
Оформить заказ, объединить и отправить в мастер
мастер проверки git
git merge branchName
git push origin master
Почему вы должны принять этот рабочий процесс?
Если вы последуете этому процессу, он гарантирует, что ВСЕ будут зафиксированы в основной сборке и пройдут тесты. Этот простой факт значительно упрощает отладку проблемы.Вы можете использовать git bisect при попытке найти источник ошибки. Git bisect становится почти полностью неэффективным, если в основной ветке есть неработающие коммиты; если вы перейдете к нечеткой фиксации, будет сложно или невозможно определить, внесла ли она ошибку.
Этот процесс также очищает ваш журнал git. Вы когда-нибудь видели график журнала git, который выглядит так?
Невероятно сложно понять, что происходит, особенно если сравнить это с тем, как мой процесс делает историю похожей:
Поскольку каждая фиксация содержит весь код для функции или исправления ошибки, вы можете легко увидеть всю единицу работы в фиксации, и вам не нужно беспокоиться о проверке правильности фиксации из ветки.
Моим любимым результатом этого рабочего процесса является то, что он упрощает обработку конфликтов из-за перезагрузки. Поскольку вы сжались до одной фиксации, вам нужно иметь дело с этими конфликтами только один раз, вместо того, чтобы работать с недоработанным кодом. Это снижает риск потери кода при разрешении конфликтов.
Так в чем же недостатки?
Поскольку мы сжимаем коммиты и перебазируем, мы буквально меняем историю репозитория. Некоторые люди считают, что история должна отражать вашу истинную историю, хорошее, плохое и уродливое.Я полагаю, что чистая история более ценна, чем та, которую трудно понять. Не вся история потеряна; стойкие приверженцы все еще могут видеть исходную историю в журнале ссылок. Еще один небольшой недостаток заключается в том, что мы теряем некоторую детализацию, когда сдавливаем наши коммиты. Если вы действительно хотите иметь несколько коммитов для функции, по крайней мере, подавите их, чтобы каждый коммит строил и проходил тесты. Хотя этот рабочий процесс может быть опасен, если вы не понимаете, что делаете, после минимального образования в этом вопросе этот процесс чрезвычайно безопасен.
TLDR
Когда дело доходит до сжатия и изменения коммитов, плюсы значительно перевешивают минусы. Это ускоряет процесс отладки, очищает вашу историю, уменьшает боль от конфликтов слияния и делает сотрудничество в вашей команде намного лучше.
____________________________________________________________________________________________________________________
Нанимаем! Ищем инженеров-программистов, менеджеров по продуктам и дизайнеров, чтобы присоединиться к нашим командам в Сан-Франциско, Лос-Анджелесе, Нью-Йорке, ЦДХ.
Узнайте больше и подайте заявку на сайте www.carbonfive.com/careers
Сквош и слияние | GitLab
История версий
- Перешел на GitLab Free в версии 11.0.
С помощью сквоша и слияния вы можете объединить все коммиты вашего мерж-реквеста в один
и сохранить чистую историю.
Обзор
Squashing позволяет вам привести в порядок историю фиксации ветки при принятии слияния.
запрос. Он применяет все изменения в мерж-реквесте как одну фиксацию,
а затем объединяет этот коммит, используя метод слияния, установленный для проекта.
Другими словами, сжатие мерж-реквеста превращает длинный список коммитов:
В одну фиксацию при слиянии:
note За сжатой фиксацией в этом примере следует фиксация слиянием, потому что метод слияния для этого репозитория использует фиксацию слияния. Вы можете отключить коммиты слиянием в
Настройки проекта> Общие> Запросы на слияние> Метод слияния> Слияние с перемоткой вперед .
Сообщение о фиксации сжатой фиксации:
- Взято из первого многострочного сообщения фиксации при слиянии.
- Заголовок мерж-реквеста, если не найдено многострочное сообщение о фиксации.
note Это вступает в силу только при наличии как минимум 2 коммитов. Поскольку нет ничего, что можно было бы раздавить, сообщение фиксации не меняется, если есть только 1 фиксация.
Его можно настроить перед объединением запроса на слияние.
Сжатие также работает со стратегией слияния с ускоренной перемоткой вперед, подробнее см. Сжатие и слияние с перемоткой вперед.
Сценарии использования
При работе над функциональной веткой иногда требуется зафиксировать текущую
прогресс, но не особо заботимся о сообщениях коммита.Те, кто работает в
коммиты прогресса не обязательно содержат важную информацию и как таковые
вы бы предпочли не включать их в свою целевую ветку.
При использовании сквоша и слияния, когда запрос на слияние готов к слиянию,
все, что вам нужно сделать, это включить сжатие, прежде чем нажимать слияние, чтобы присоединиться
коммиты в мерж-реквесте в один коммит.
Таким образом, история вашей базовой ветки останется чистой с
значимые сообщения фиксации и:
- При необходимости восстановить данные проще.
- Объединенная ветка сохраняет полную историю фиксации.
Включение сквоша для мерж-реквеста
Любой, кто может создать или отредактировать запрос на слияние, может выбрать его сжатие
в форме запроса слияния. Пользователи могут установить или снять флажок, когда они
создать мерж-реквест:
После отправки запроса на слияние Squash и Merge все еще могут быть включены или отключены
отредактировав описание мерж-реквеста:
- Прокрутите страницу слияния вверх и нажмите Изменить .
- Прокрутите форму запроса на слияние до конца и установите флажок
Squash фиксируется, когда принят запрос на слияние .
Этот параметр можно изменить во время принятия запроса на слияние.
В конце виджета мерж-реквеста рядом с кнопкой Merge стоит флажок Squash commitits
может быть выбран или не выбран:
Обратите внимание, что функции Squash и Merge могут быть недоступны в зависимости от конфигурации проекта.
для параметров фиксации Squash.
Сжатый коммит имеет следующие метаданные:
- Сообщение: сообщение о фиксации сквоша или настраиваемое сообщение.
- Автор: автор слияния.
- Коммиттер: пользователь, инициировавший сквош.
Сквош и быстрая перемотка вперед
Когда в проекте включена настройка слияния с перемоткой вперед, слияние
запрос должен иметь возможность быстрой пересылки без сжатия, чтобы подавить
Это. Это связано с тем, что сжатие доступно только при принятии запроса на слияние,
поэтому мерж-реквест, возможно, потребуется перебазировать перед сжатием, даже если
Сжатие само по себе можно считать эквивалентом перебазирования.
Параметры фиксации сквоша
История версий
- Представлено в GitLab 13.2.
- Развернуто за флагом функции, по умолчанию отключено.
- Включено по умолчанию в GitLab 13.3.
- Включено на GitLab.com.
- Можно включить для каждого проекта.
- Рекомендовано для производственного использования.
С помощью параметров Squash Commits вы можете настроить поведение Squash и Merge для вашего проекта.
Чтобы настроить его, перейдите в настройки проекта > Общие и разверните Merge requests .Вы можете выбрать один из этих вариантов, которые влияют на существующие и новые запросы на слияние.
отправлено в ваш проект:
- Не разрешать : пользователи не могут использовать Squash и Merge для сжатия всех коммитов непосредственно перед
слияние. Флажок для включения или отключения снят и скрыт от пользователей. - Разрешить : пользователи могут включить сжатие и слияние на основе запроса слияния.
По умолчанию флажок снят (отключен), но пользователь может включить его. - Encourage : пользователи могут включить Squash и Merge на основе запроса слияния.
По умолчанию флажок установлен (включен), чтобы поощрять его использование, но пользователю разрешено
отключи это. - Требовать : Сквош и слияние включены для всех запросов на слияние, поэтому они выполняются всегда.
Флажок для включения или отключения установлен и скрыт от пользователей.
Флажок Squash and Merge отображается при создании запроса на слияние и при редактировании описания существующего, за исключением случая, когда для параметра Squash Commit Options установлено значение Не разрешать или Требовать .
Примечание: если для вашего проекта установлено значение . Не разрешать Squash and Merge, у пользователей все еще есть возможность
squash фиксируется локально через командную строку и принудительно нажимает на свою удаленную ветку перед слиянием.
Git Interactive Rebase, Squash, Amend и другие способы перезаписи истории
«Пожалуйста, сделайте переустановку поверх мастера, и мы объединим ваш запрос на перенос».
«Не могли бы вы собрать ваши коммиты вместе, чтобы мы получили чистый, обратимый git.
история? ».«Можете ли вы переписать сообщение вашего коммита, чтобы лучше описать проблему,
решает, и как это решает? ».
Подобные вопросы обычно задают в запросах на вытягивание. Посмотрим, почему они
существуют, как их выполнять, и их возможные проблемы.
Одно из самых простых переписываний истории, которое мы можем сделать с помощью git, — это изменение последнего
зафиксировать сообщение. Допустим, сразу после фиксации вы обнаружите опечатку в
description, или вы найдете лучший способ описания набора изменений.Чтобы сделать
исправление, которое вы выполняете:
Откроется редактор
с последним сообщением о фиксации, поэтому вы можете его изменить. После сохранения новая фиксация
будет создан с теми же изменениями и новым сообщением, заменяющим фиксацию
с предыдущим сообщением.
Это может быть полезно для включения файлов, которые вы забыли отслеживать, или для включения
модификации файлов, которые вы только что зафиксировали. Для этого вы можете добавить изменения
а затем внесите поправку:
git добавить README.md config / routes.rb
git rm notes.txt
git commit --amend
Помимо редактирования сообщения фиксации, новая фиксация будет содержать изменения
указывается с помощью git add
и git rm
. Вы также можете редактировать автора. Для
пример:
git commit --amend --author = "Тут Коста и Дэн Кроук "
Достижение разблокировано! Теперь вы можете изменить последнюю фиксацию
ваш репозиторий, чтобы включить новые изменения в файлы и / или улучшить
зафиксировать сообщение.Но не начинайте все исправлять, пока не поймете
последний раздел этого сообщения в блоге озаглавлен «ОПАСНОСТЬ».
Хотел бы поговорить об этом сейчас, но нам нужно понять более общие
инструмент раньше. Ждите продолжения! Все остальное станет проще, когда мы прочитаем о…
git rebase
повторно применяет коммиты, один за другим
один, по порядку, из текущей ветки в другую. Принимает несколько вариантов
и параметры, так что это лишь верхушка айсберга, достаточная для преодоления
разрыв между комментариями StackOverflow или GitHub и страницами руководства git.
Интересный вариант, который он принимает — - интерактивный
( -i
для краткости), который
откройте редактор со списком коммитов, которые собираются изменить. Этот
list принимает команды, позволяя пользователю редактировать список перед запуском
перебазировать действие.
Давайте посмотрим на пример.
Допустим, я хочу перефразировать любую из последних 4 коммитов этого блога. Я тогда бегу
git rebase -i HEAD ~ 4
, и вот что я вижу:
pick 07c5abd Знакомство с OpenPGP и обучение основам использования
выберите de9b1eb Исправить PostChecker :: Post # urls
выберите 3e7ee36 Эй, ребята, перестаньте выделять
выберите fa20af3 git интерактивное перебазирование, сквош, поправка
# Rebase 8db7e8b..fa20af3 на 8db7e8b
#
# Команды:
# p, pick = использовать фиксацию
# r, reword = использовать фиксацию, но отредактировать сообщение фиксации
# e, edit = использовать фиксацию, но не вносить поправки
# s, squash = использовать фиксацию, но сливается с предыдущей фиксацией
# f, fixup = как "squash", но удалить сообщение журнала этой фиксации
# x, exec = run команда (остальная часть строки) с использованием оболочки
#
# Эти строки можно переупорядочить; они выполняются сверху вниз.
#
# Если вы удалите здесь строчку, ЧТО COMMIT БУДЕТ УТЕРЯНЫ.
#
# Однако, если вы удалите все, перебазирование будет прервано.#
# Обратите внимание, что пустые коммиты закомментированы
Мы видим четыре последних коммита, от старых к более новым. См. Комментарий под
список коммитов? Хорошая работа по объяснению, мерзавец! pick
( p
для краткости) по умолчанию
действие. В этом случае он повторно применит фиксацию как есть, никаких изменений в его
содержание или сообщение. Сохранение (и выполнение) этого файла не повлияет на
репозиторий.
Если я скажу reword
( r
для краткости) в коммите, я хочу отредактировать:
pick 07c5abd Знакомство с OpenPGP и обучение основам использования
выберите de9b1eb Исправить PostChecker :: Post # urls
r 3e7ee36 Эй, ребята, перестаньте выделять свет
выберите fa20af3 git интерактивное перебазирование, сквош, поправка
Когда я сохраняю и выхожу из редактора, git будет следовать описанным командам, приземляясь
я снова в редактор, как будто я исправил commit 3e7ee36
.Я редактирую это
зафиксировать сообщение, сохранить и выйти из редактора, и вот результат:
robots.oughttbot.com tc-git-rebase% git rebase -i HEAD ~ 4
[detached HEAD dd62a66] Прекратить выделение
Автор: Калеб Харт
Дата: 31 окт, пт, 10:52:26 2014 -0500
2 файла изменено, 39 вставок (+), 42 удаления (-)
Refs / Heads / tc-git-rebase успешно перебазированы и обновлены.
Теперь Калеб в своем сообщении фиксации говорит: «Прекратите выделение», независимо от того,
ребенок или нет.
Достижение разблокировано! Теперь вы можете изменить сообщение любого
совершить вы хотите.Вы можете это сделать, просто убедитесь, что вы понимаете «ОПАСНОСТЬ»
раздел.
Две другие команды интерактивного перебазирования нам предлагают:
-
squash
(s
для краткости), который объединяет фиксацию с предыдущей (
один в строке перед) -
fixup
(f
для краткости), который действует как «сквош», но отбрасывает эту фиксацию
сообщение
Продолжим работу над примером перебазирования, над которым мы работали.
до. У нас было четыре коммита, мои собственные для этого сообщения в блоге, и
три других от Калеба, которые были связаны с его предыдущим постом на PGP:
pick 07c5abd Знакомство с OpenPGP и обучение основам использования
выберите de9b1eb Исправить PostChecker :: Post # urls
выберите 3e7ee36 Эй, ребята, перестаньте выделять
выберите fa20af3 git интерактивное перебазирование, сквош, поправка
Допустим, я хочу объединить коммиты Калеба, потому что они принадлежат
тот же логический набор изменений, поэтому мы можем легко вернуть git, если обнаружим, что
предпочитаю не хранить эти изменения в этом репозитории.Мы хотим сохранить
первое сообщение фиксации и сдвинуть две последующие фиксации в предыдущее
один. Я меняю pick
на squash
где необходимо:
pick 07c5abd Знакомство с OpenPGP и обучение основам использования
s de9b1eb Исправить PostChecker :: Post # urls
s 3e7ee36 Эй, ребята, перестаньте выделять
выберите fa20af3 git интерактивное перебазирование, сквош, поправка
Сохраните, и я попадаю в редактор, чтобы определить сообщение фиксации объединенного
три коммита (посмотрите, как они объединяются один за другим):
# Это комбинация 3 коммитов.# Сообщение первого коммита:
Знакомство с OpenPGP и обучение основам использования
Помимо демистификации относительно сложного инструмента, протокола и этикета,
этот пост предназначен для помощи в решении таких проблем, как описанная в
этот твит:
> Отправил по электронной почте конфиденциальную информацию кому-то с PGP. Они ответили моим
> исходное электронное письмо, все в виде открытого текста. Они этого не осознавали.
# Это второе сообщение коммита:
Исправить PostChecker :: Post # urls
# Это третье сообщение коммита:
Эй, детки, перестаньте выделять
# Пожалуйста, введите сообщение фиксации для ваших изменений.Линии начинаются
# с '#' будет проигнорировано, а пустое сообщение прервет фиксацию.
#
# Автор: Калеб Харт
# Дата: Вт, 2 сентября, 09:39:07 2014 -0500
#
# выполняется перебазирование; на 71d4789
# В настоящее время вы редактируете фиксацию при перемещении ветки 'tc-git-rebase' на '71d4789'.
Я решаю удалить третье сообщение о фиксации и добавить более релевантное примечание в
второе сообщение фиксации. Сохраните редактор, и четыре коммита были преобразованы
на два: одно от Халева и мое после.Хорошо!
Мы могли бы использовать команду fixup
, если бы мы видели ранее, что мы хотим
изменяется, но не сообщение фиксации третьей фиксации. В этом случае
команды выглядели бы так:
pick 07c5abd Знакомство с OpenPGP и обучение основам использования
s de9b1eb Исправить PostChecker :: Post # urls
f 3e7ee36 Эй, ребята, перестаньте выделять свет
выберите fa20af3 git интерактивное перебазирование, сквош, поправка
При сохранении редактор уже включил бы третье сообщение фиксации
прокомментировали для нас:
# Это комбинация 3 коммитов.# Сообщение первого коммита:
Знакомство с OpenPGP и обучение основам использования
Помимо демистификации относительно сложного инструмента, протокола и этикета,
этот пост предназначен для помощи в решении таких проблем, как описанная в
этот твит:
> Отправил по электронной почте конфиденциальную информацию кому-то с PGP. Они ответили моим
> исходное электронное письмо, все в виде открытого текста. Они этого не осознавали.
- https://twitter.com/csoghoian/status/505366816685060096
* Используйте примеры, которые приблизительно соответствуют выходным данным `gpg2`.
* Отклонить обратную косую черту в URL s
перед проверкой их
Markdown позволяет использовать обратную косую черту в URL для escape-символов, которые передаются непосредственно в
URL , поэтому `http: // some \ _url.com`
становится http: // some_url.com.
Это смягчает проблемы с подсветкой синтаксиса уценки, полагая, что
выделенный текст начался, например `_this text_`.
# Это второе сообщение коммита:
Исправить PostChecker :: Post # urls
# Третье сообщение фиксации будет пропущено:
# Эй, детки, перестаньте выделять свет
# Пожалуйста, введите сообщение фиксации для ваших изменений. Линии начинаются
# с '#' будет проигнорировано, а пустое сообщение прервет фиксацию.
#
# Автор: Калеб Харт
# Дата: Вт, 2 сентября, 09:39:07 2014 -0500
#
# выполняется перебазирование; на 71d4789
# Вы сейчас редактируете фиксацию при перебазировании ветки 'tc-git-rebase' на
«71d4789».
Сохранить и вывести:
[отдельная ГОЛОВА 809241b] Представьте OpenPGP и научите основам использования
Автор: Калеб Харт
Дата: 2 сен, вторник, 09:39:07 2014 г. -0500
2 файла изменено, 1429 вставок (+), 1 удаление (-)
режим создания 100644 source / posts / 2014 / 10-31-pgp-and-you.md
Refs / Heads / tc-git-rebase успешно перебазированы и обновлены.
Результат тот же: 2 коммита вместо 4, каждый с одним отдельным блогом.
Почта.
Достижение разблокировано! Теперь вы можете объединять коммиты вместе.Как
всегда помните о разделе ОПАСНОСТЬ.
Мы разветвляем библиотеку с открытым исходным кодом, начинаем работать над функциональной веткой и осваиваем
проект по разведке и добыче продвигается вперед. Наша история выглядит так:
A --- B --- C функция
/
D --- E --- F --- G восходящий / главный
Сопровождающий библиотеки спрашивает «перебазировать поверх мастера», поэтому мы исправляем любое слияние
конфликты, которые могут возникнуть между обеими ветвями, и сохранить наш набор изменений вместе.
Сопровождающий хотел бы видеть историю вроде:
Элемент A '- B' - C '
/
D --- E --- F --- G восходящий / главный
Мы хотим повторно применить наши коммиты, один за другим, по порядку, к ведущему устройству восходящего потока.Похоже на описание команды rebase! Посмотрим, какие команды будут
посадить нас в желаемый сценарий:
# Направляем наш удаленный `upstream` на исходную вилку
git удаленный добавить вверх по течению https://github.com/gotitbot/factory_girl.git
# Получить последние коммиты из `upstream` (исходный форк)
git fetch вверх по течению
# Оформить заказ на нашу ветку функций
функция проверки git
# Повторно примените его к мастеру апстрима
git rebase upstream / master
# Исправьте конфликты, затем `git rebase --continue`, повторяйте, пока не сделаете
# Нажимаем на нашу вилку
git push - форсировать функцию происхождения
Достижение разблокировано! Ваша функциональная ветка будет применяться к
вершина последнего мастера оригинальной вилки.
Итак, получаем…
Видите --force
в последней команде git push
? Это означает, что мы перезаписываем
история репозитория. Это всегда безопасно делать в коммитах, с которыми мы не делимся
других членов команды или в наших филиалах (см. мои инициалы в
пример этого сообщения в блоге).
Но если вы принудительно отправите выпуски, которые уже были переданы команде (совершает
которые существуют за пределами моего репозитория, например, изменения, которые я внес в коммиты PGP
которые уже были опубликованы), тогда все ветки рассинхронизируются.