Squash commits git что это
Как сжимать коммиты в Git с помощью git squash
Git squash — это прием, который помогает взять серию коммитов и уплотнить ее. Например, предположим: у вас есть серия из N коммитов и вы можете путем сжатия преобразовать ее в один-единственный коммит. Сжатие через git squash в основном применяется, чтобы превратить большое число малозначимых коммитов в небольшое число значимых. Так становится легче отслеживать историю Git.
Также этот прием используется при объединении ветвей. Чаще всего вам будут советовать всегда сжимать коммиты и выполнять перебазирование с родительской ветвью (например, master или develop ). В таком случае история главной ветки будет содержать только значимые коммиты, без ненужной детализации.
Как именно делать git squash
Возьмем для примера следующую историю Git:
Здесь видны последние три коммита. В сообщениях к ним поясняется, что мы добавили новый файл и какое-то содержимое. Лучше заменить их одним единственным коммитом о том, что произошло добавление нового файла с некоторым содержимым. Итак, давайте посмотрим, как сжать последние три коммита в один:
3 означает, что мы берем последние три коммита.
Как видите, для сжатия мы отметили последние два коммита с помощью команд squash или s .
Здесь изменилось сообщение о коммите, и обратите внимание: три коммита “склеились” в один. Также изменился хэш коммита. Через git rebase всегда создается новый коммит, содержащий соответствующие изменения.
Так что используйте этот инструмент с осторожностью.
Помните: сжатие коммитов меняет историю Git, поэтому не рекомендуется сжимать ветвь, если вы уже отправили ее в удаленный репозиторий. Всегда выполняйте сжатие до того, как отправить пуш с изменениями.
Применение fixup для сжатия коммитов
Обратите внимание: хэш коммита также изменился, а сообщение о коммите берется из “основного” коммита, с которым были сжаты другие два.
Применение сжатия при слиянии ветвей
Git также предоставляет возможность сжатия при объединении ветвей. Во многих случаях она может оказаться полезной. Чтобы добавить новый функционал или поправить какие-то баги, нам понадобится то и дело что-то изменять в ветвях. Поэтому, когда мы будем готовы слить эти изменения в основную ветвь ( master или develop ), для начала следует применить сжатие.
Давайте рассмотрим следующую команду:
Она берет все коммиты из целевой ветви, сжимает их и сохраняет все изменения в текущей ветви. Затем вы можете зафиксировать все изменения в одном коммите. На примере это выглядит так:
Сжатие коммитов через Github
Возможность сжимать коммиты предоставляет и Github. Эта функция особенно полезна при пулл-реквесте.
Сначала производится сжатие, затем — слияние. Так что вместо пяти коммитов получится один.
Как видно на картинке, выполняется всего один коммит с соответствующим сообщением.
Спасибо за чтение! Надеюсь, вы почерпнули из статьи что-то новое 🙂
Тонкости благополучного git-merge
Вступительное слово
Основными командами пользовательского уровня для ветвления в Git являются git-branch, git-checkout, git-rebase, git-log и, конечно же, git-merge. Для себя я считаю git-merge зоной наибольшей ответственности, точкой огромной магической энергии и больших возможностей. Но это достаточно сложная команда, и даже достаточно длительный опыт работы с Git порой бывает недостаточным для освоение всех ее тонкостей и умения применить ее наиболее эффективно в какой-либо нестандартной ситуации.
Попробуем же разобраться в тонкостях git-merge и приручить эту великую магию.
Здесь я хочу рассмотреть только случай благополучного слияния, под которым я понимаю слияние без конфликтов. Обработка и разрешение конфликтов — отдельная интересная тема, достойная отдельной статьи. Я очень рекомендую так же ознакомиться со статьей Внутреннее устройство Git: хранение данных и merge, содержащей много важной информации, на которую я опираюсь.
Анатомия команды
Если верить мануалу, команда имеет следующий синтаксис:
По большому счету, в Git есть два вида слияния: перемотка (fast-forward merge) и «истинное» слияние (true merge). Рассмотрим несколько примеров обоих случаев.
«Истинное» слияние (true merge)
Мы отклоняемся от ветки master, чтобы внести несколько багов улучшений. История коммитов у нас получилась следующая:
Выполним на ветке master git merge feature :
Посмотрим историю коммитов в тестовом репозитории, который я создал специально для этого случая:
А теперь посмотрим информацию о коммите (M):
Мы видим двух родителей, объект-дерево, соответствующее данному состоянию файлов репозитория, а так же информацию о том, кто виновен в коммите.
Посмотрим, куда ссылается указатель master:
Действительно, он теперь передвинут на коммит (M).
Squash и no-commit
В случае применения такого слияния коммиты ветки feature не будут включены в нашу историю, но коммит Sq будет содержать все их изменения:
Позже, в случае выполнения «классического» git merge feature можно исправить это. Тогда история примет следующий вид:
Перемотка (fast-forward merge)
Рассмотрим другой случай истории коммитов:
Все как и в прошлый раз, но теперь в ветке master нет коммитов после ответвления. В этом случае происходит слияние fast-forward (перемотка). В этом случае отсутствует коммит слияния, указатель (ветка) master просто устанавливается на коммит Y, туда же указывает и ветка feature:
Стратегии слияния
Стратегия resolve
Здесь C — общий коммит двух веток, дерево файлов, соответствующее этому коммиту, принимается за общего предка. Анализируются изменения, произведенные в ветках master и feature со времен этого коммита, после чего для коммита (M) создается новая версия дерева файлов в соответствии с пунктами 4 и 5 нашего условного алгоритма.
Стратегия recursive
Для иллюстрации этой стратегии позаимствуем пример из статьи Merge recursive strategy из блога «The plasticscm blog»:
Итак, у нас есть две ветки: main и task001. И так вышло, что наши разработчики знают толк в извращениях: они слили коммит 15 из ветки main с коммитом 12 из ветки task001, а так же коммит 16 с коммитом 11. Когда нам понадобилось слить ветки, оказалось, что поиск реального предка — дело неблагодарное, но стратегия recursive с ее конструированием «виртуального» предка нам поможет. В результате мы получим следующую картину:
]
Выполнение рекурсивного слияния с этой опцией будет более продвинутым вариантом стратегии subtree, где алгоритм основывается на предположении, как деревья должны совместиться при слиянии. Вместо этого в этом случае указывается конкретный вариант.
Стратегия octopus
Эта стратегия используется для слияние более чем двух веток. Получившийся в итоге коммит будет иметь, соответственно, больше двух родителей.
Данная стратегия предполагает большую осторожность относительно потенциальных конфликтов. В связи с этим порой можно получить отказ в слиянии при применении стратегии octopus.
Стратегия ours
Не следует путать стратегию ours и опцию ours стратегии recursive.
Стратегия ours — более радикальное средство.
Стратегия subtree
Для иллюстрации данной стратегии возьмем пример из главы Слияние поддеревьев книги «Pro Git».
Добавим в наш проект новые удаленный репозиторий, rack:
Ясно, что ветки master и rack_branch имеют абсолютно разные рабочие каталоги. Добавим файлы из rack_branch в master с использованием squash, чтобы избежать засорения истории ненужными нам фактами:
Теперь файлы проекта rack у нас в рабочем каталоге.
Как сжимать коммиты в Git с помощью git squash
Aug 31, 2020 · 5 min read
Git squash — это прием, который помогает взять серию коммитов и уплотнить ее. Например, предположим: у вас есть серия из N коммитов и вы можете путем сжатия преобразовать ее в один-единственный коммит. Сжатие через git squash в основном применяется, чтобы превратить большое число малозначимых коммитов в небольшое число значимых. Так становится легче отслеживать историю Git.
Также этот прием используется при объединении ветвей. Чаще всего вам будут советовать всегда сжимать коммиты и выполнять перебазирование с родительской ветвью (например, master или develop ). В таком случае история главной ветки будет содержать только значимые коммиты, без ненужной детализации.
Как именно делать git squash
Возьмем для примера следующую историю Git:
Здесь видны последние три коммита. В сообщениях к ним поясняется, что мы добавили новый файл и какое-то содержимое. Лучше заменить их одним единственным коммитом о том, что произошло добавление нового файла с некоторым содержимым. Итак, давайте посмотрим, как сжать последние три коммита в один:
3 означает, что мы берем последние три коммита.
Здесь изменилось сообщение о коммите, и обратите внимание: три коммита “склеились” в один. Также изменился хэш коммита. Через git rebase всегда создается новый коммит, содержащий соответствующие изменения.
Так что используйте этот инструмент с осторожностью.
Помните: сжатие коммитов меняет историю Git, поэтому не рекомендуется сжимать ветвь, если вы уже отправили ее в удаленный репозиторий. Всегда выполняйте сжатие до того, как отправить пуш с изменениями.
Применение fixup для сжатия коммитов
Обратите внимание: хэш коммита также изменился, а сообщение о коммите берется из “основного” коммита, с которым были сжаты другие два.
Применение сжатия при слиянии ветвей
Git также предоставляет возможность сжатия при объединении ветвей. Во многих случаях она может оказаться полезной. Чтобы добавить новый функционал или поправить какие-то баги, нам понадобится то и дело что-то изменять в ветвях. Поэтому, когда мы будем готовы слить эти изменения в основную ветвь ( master или develop ), для начала следует применить сжатие.
Давайте рассмотрим следующую команду:
Она берет все коммиты из целевой ветви, сжимает их и сохраняет все изменения в текущей ветви. Затем вы можете зафиксировать все изменения в одном коммите. На примере это выглядит так:
Сжатие коммитов через Github
Возможность сжимать коммиты предоставляет и Github. Эта функция особенно полезна при пулл-реквесте.
Сначала производится сжатие, затем — слияние. Так что вместо пяти коммитов получится один.
Как видно на картинке, выполняется всего один коммит с соответствующим сообщением.
Спасибо за чтение! Надеюсь, вы почерпнули из статьи что-то новое 🙂
Squash commits git что это
Как склеивать коммиты
Отлично, у меня 5 коммитов. Теперь я хочу переписать историю с момента HEAD
Тут список моих коммитов и большой комментарий о том, что я могу сделать. Из списка комманд видно, что мы можем использовать squash или fixup для того, чтобы склеить коммиты. Первый пригодится тогда, когда вы хотите изменить коммит-месседж, а второй — когда хотите использовать коммит-месседж первого. Итак, чтобы склеить все коммиты, я делаю вот так:
То есть я говорю гиту «используй первый коммит, а остальные приклей к нему». Потом я сохраняю файл и закрываю его. Гит склеивает коммиты и предлагает мне ввести коммит-месседж (показывает коммит-месседжи всех склеенных коммитов):
Я хочу оставить только последний:
Ура, остался один коммит с нужным сообщением.
Как автоматизировать ребейз
Обычно всё-таки нужно оставить коммит-месседж первого изменения, типа «Сверстал то-то», остальные коммиты — просто правки к нему. Число правок иногда доходит до 15, не очень удобно сидеть и писать везде squash. Можно сделать так, чтобы коммиты автоматически присквошивались к нужному, только для этого нужно их правильно коммитить. Предположим, вы поменяли файл и хотите закоммитить изменения как правку по ревью:
Сначала надо узнать хеш коммита, к которому этот коммит является правкой. Воспользуемся уже знакомым cherry :
Необязательно в точности копировать весь хеш, достаточно первых 7 символов. Я обычно выделяю от начала и сколько выделится и копирую:
4 И гит сам подставит слово fixup там, где нужно:
Просто сохраняем, и гит склеивает коммиты и использует коммит-месседж первого:
Еще одна инструкция по пользованию git
И еще. Я по какой-то непонятной причине почти не пользуюсь IDE для работы с git. Если использовать IDE, то думаю все равно с какой системой контроля версий работать.
10 шагов для работы с проектом
Хочу написать что нужно делать если вы работаете в компании в которой используется git. Как правило для каждой задачи, которую вы делаете вам надо будет заводить отдельную ветку (branch), называть ее по имени задачи в вашей системе управления задач (например по имени задачи в JIRA), а после завершения выполнения задачи и прохождения процедуры проверки кода другими работниками объединять вашу ветку с общим кодом.
git тупо не разрешит сделать pull если у вас есть локально измененные файлы и update их модифицирует. Можно тут использовать git stash / git pull / git shash pop.
Допустим вы внесли изменения и сделали commit. Есть 2 варианта — если ваши изменения и удаленные не конфликтуют, то git создаст еще один дополнительный сommit и предложит вам отредактировать сообщение этого вновь созданного комита.
Если есть конфликты, то я делаю так.
Смотрим какие файлы конфликтуют (both modified)
, правим их, добавляем
Переключаемся в ветку master:
Создаем новую ветку:
Сообщаем git какие файлы мы хотим закомитить:
Примечание — git ругается, что не знает куда отправлять — смотри примечание к пункту 2.
github ui magic
squash commit
Переходим в основную ветку (master)
, делаем squash commit
. Все изменения, из нашей ветки появятся как локальные, но уже в основной ветке. Смотрим что мы наваяли. Посмотреть изменения — пункт 3. Комитим — пункт 8, отправляем на сервер — пункт 9. Можно делать squash commit не в основную ветку, а завести новую, сделать в нее squash commit и из нее сделать merge в основную (смотри следующий пункт).
merge
Ваши комиты в этом случае не склеятся в один. Переходим в основную ветку (master)
, делаем обычный commit
, отправляем на сервер — пункт 9.
rebase
Можно сделать rebase ветки и, например, склеить все ваши комиты в один.