Перейти к содержимому

Git squash что это

  • автор:

Как склеить коммиты и зачем это нужно

Когда вы открываете пулреквест и ваш код смотрят и комментируют другие, бывает нужно что-то исправить. Обычно такие изменения мы комментируем сообщением вроде «Увеличил шрифт на 2px » или «Поменял оттенок фона в шапке». Такие маленькие изменения интересны, только пока они в пулреквесте. Ревьювер (человек, который смотрит ваш код), может легко узнать, что и когда вы изменили, а не читать весь diff заново, а вы можете легко откатить коммит, если он не нужен. Но когда приходит время вливать пулреквест, эти маленькие коммиты теряют свою ценность. Поэтому лучше их склеить в один.

Как подготовиться

Для некоторых операций из этой статьи Git будет открывать текстовый редактор. Во многих системах по умолчанию это Vim. Не самый дружелюбный для новичков. Чтобы вам было комфортно, установите в качестве Git-редактора ваш любимый редактор. Это делается с помощью команды:

git config --global core.editor 

Если у вас Windows и вы хотите установить VS Code в качестве Git-редактора, ваша команда будет такой:

git config --global core.editor "code --wait" 

А если у вас Mac OS и вы хотите установить Atom в качестве редактора по умолчанию, введите:

git config --global core.editor "atom --wait" 

С другими редакторами нужно просто посмотреть команду и подставить её.

Как склеивать коммиты

Сначала узнаем, сколько коммитов нужно склеить. Эта команда покажет, какие коммиты у вас прибавились по сравнению с веткой master :

git cherry -v master 

А эта — сколько их:

git cherry -v master | wc -l 

git cherry -v master

Отлично, у нас пять коммитов. Теперь перепишем историю с момента HEAD~5 , то есть с того, что было пять коммитов назад. Для этого делаем:

git rebase -i HEAD~5 

Флаг -i — значит в интерактивном режиме. Открывается файл:

Тут список коммитов и большой комментарий о том, что можно сделать. Из списка команд видно, что мы можем использовать squash или fixup для склейки коммитов. Первый пригодится, когда нужно изменить коммит-месседж, а второй — когда хотите использовать коммит-месседж первого.

Итак, чтобы склеить все коммиты, делаем так:

То есть говорим «используй первый коммит, а остальные приклей к нему». Потом сохраняем файл и закрываем его. Git склеивает коммиты и предлагает ввести коммит-месседж (показывает коммит-месседжи всех склеенных коммитов):

Оставляем только последний:

Сохраняем файл и смотрим лог:

Ура, остался один коммит с нужным сообщением.

Теперь нужно работу отправить на ваш Git-сервер. Обычно это делается с помощью git push , но сейчас это не удастся:

Это потому, что ваша локальная ветка и ветка на сервере отличаются. Причём не просто в локальной ветке есть некоторые коммиты, которых нет на сервере, но и старых коммитов нет. Ведь теперь один новый коммит вместо всех прежних. Чтобы запушить на сервер все изменения, несмотря на конфликт, запустим пуш с флагом —force :

git push --force 

Теперь всё получилось.

⭐ Используйте —force только тогда, когда вы уверены в своих действиях.

Как автоматизировать ребейз

Обычно всё-таки нужно оставить коммит-месседж первого изменения, типа «Сверстал то-то», остальные коммиты — просто правки к нему. Число правок иногда доходит до 15 — это не очень удобно, ведь нужно писать везде squash . Можно сделать так, чтобы коммиты автоматически присквошивались к нужному, для этого нужно их правильно коммитить. Предположим, мы поменяли файл и захотели закоммитить изменения как правку по ревью:

Сначала нужно узнать хеш коммита, к которому этот коммит является правкой. Воспользуемся уже знакомым cherry :

git cherry -v master

Вот наш хеш. А теперь следующий коммит обозначим правкой к этому:

git commit --fixup

Необязательно в точности копировать весь хеш, достаточно первых 7 символов. Я обычно выделяю от начала и сколько выделится и копирую:

git commit --fixup

Изменения закоммитились с сообщением fixup! Сообщение того коммита . История теперь выглядит nак:

git log

Добавим ещё несколько правок таким образом. Посмотрим изменения:

git cherry -v master

Отлично. А теперь склеим все эти коммиты. Только не вручную. Git сделает это за нас:

git rebase -i --autosquash HEAD~4 

И Git сам подставит слово fixup там, где нужно:

git rebase -i --autosquash

Просто сохраняем, и Git склеивает коммиты и использует коммит-месседж первого:

Результат автосквоша

Материалы по теме

  • Шпаргалка по Git
  • Работа с Git через консоль
  • Учебник по Git

«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

Читать дальше

5 частых ошибок при работе с Git

5 частых ошибок при работе с Git

Git — это важный и довольной понятный инструмент для контроля версий в разработке программного обеспечения, но иногда он может выдавать ошибки, которые сбивают с толку. Если вы столкнулись с одной из этих ошибок, попробуйте наше решение.

  • 27 августа 2023

Работа с Git через консоль

Работа с Git через консоль

Задача: форкнуть репозиторий в GitHub, создать ветку и работать с кодом.

Сразу появляется много вопросов — что такое GitHub, какие для этого нужны команды, зачем, а главное, как всем этим пользоваться? Давайте разберёмся.

Когда мы пишем код, мы постоянно туда что-то добавляем, удаляем, и иногда всё может ломаться. Поэтому перед любыми изменениями стоит сделать копию проекта. Если собирать проекты в папки с именами проект1 , проект1_финал и проект2_доделка , вы быстро запутаетесь и точно что-нибудь потеряете. Поэтому для работы с кодом используют системы контроля версий.

Система контроля версий — программа, которая хранит разные версии одного документа, позволяет переключаться между ними, вносить и отслеживать изменения. Таких систем много и все они работают по принципу компьютерной игры, где вы можете вернуться к месту сохранения, если что-то пошло не так.

Git — самая популярная система контроля версий. С Git можно работать через командную строку (или терминал). В каждой системе своя встроенная программа для работы с командной строкой. В Windows это PowerShell или cmd, а в Linux или macOS — Terminal. Вместо встроенных программ можно использовать любую другую — например, Git Bash в Windows или iTerm2 для macOS.

Как работает терминал: мы вводим команду и получаем ответ компьютера — или всё получилось, или где-то ошибка, или нужно ввести что-то ещё — например, пароль. Поэтому большая часть этой инструкции состоит из команд для терминала. Сначала будет непривычно, но вам понравится.

Но давайте по порядку — установим Git на компьютер.

  • 7 августа 2023

GitHub Desktop: обзор и первая настройка

GitHub Desktop: обзор и первая настройка

Самая короткая инструкция о том, как сохранить файлы в GitHub и ничего не сломать. И самое главное — никакой консоли, всё через окошки и с помощью мышки. Для этого используем GitHub Desktop.

Внимание! GitHub Desktop не работает на Windows 7×32, поэтому если у вас эта версия системы, обновитесь до Windows 10 или воспользуйтесь программой GitKraken.

В этой статье идёт рассказ о системах контроля версий. Если вы совсем ничего о них не знаете, прочитайте статьи «Словарь терминов для Git и GitHub» и «Введение в системы контроля версий», чтобы понять терминологию и разобраться, зачем мы вообще это делаем.

  • 7 августа 2023

Основные команды для работы с Git

Основные команды для работы с Git

Работа с Git через терминал — это обязательная часть практики фронтендера. Однако для начинающих разработчиков этот инструмент может показаться сложным. Чтобы вам было проще учиться, мы собрали основные команды для работы с Git.

☝ В некоторых командах мы будем писать URL-адрес удалённого репозитория и название проекта в квадратных скобках, вот так — [ссылка на удалённый репозиторий] . Мы делаем это только для наглядности. Вам квадратные скобки ставить не нужно.

  • 22 февраля 2023

Как бесплатно залить сайт на GitHub Pages

Как бесплатно залить сайт на GitHub Pages

Допустим, вы сделали какой-то проект, например, собрали себе портфолио по шаблону, и теперь хотите выложить его в интернет. Если вы использовали только HTML и CSS, то необязательно платить деньги, чтобы загрузить сайт куда-то. Вы можете бесплатно выложить сайт на сервис GitHub Pages. Всё, что нужно — аккаунт на Гитхабе.

  • 29 ноября 2022

Регистрация на GitHub

Регистрация на GitHub

Создание нового аккаунта на GitHub состоит всего из 10 шагов — и вся регистрация занимает меньше пяти минут.

�� Обратите внимания, что интерфейс Гитхаба регулярно меняется, так что внешне он может отличаться, когда вы читаете эту статью.

Начало регистрации. Так выглядит главный экран Гитхаба, когда вы не зарегистрированы. Главное, что вам нужно заметить — большое поле для ввода почты и зелёная кнопка. Вводите свой адрес и переходите на следующий шаг.

Ввод почты. На следующем шаге начинается регистрация. Подтвердите свою почту с прошлого шага и нажмите Continue (Продолжить).

Пароль. Придумайте сложный пароль, чтобы его никто не взломал. Например, Гитхаб просит, чтобы в пароле было не меньше 15 символов или 8 символов, но тогда должны быть и латинские буквы, и цифры.

Имя профиля. Теперь выберите имя вашего профиля — оно будет использоваться в интерфейсе, в коммитах и комментариях. То есть именно так вас будет видеть любой пользователь Гитхаба. Для разработчика Гитхаб вместо визитки, так что выбирайте что-нибудь приличное, лучше, если ник будет совпадать с вашими никнеймами на других сайтах.

Если имя недоступно, Гитхаб вам об этом скажет. А если доступно — жмите Continue.

Рассылки. Дальше Гитхаб спросит, хотите ли вы подписаться на рассылку об обновлениях. Впечатайте латинскую У, если хотите, или n, если письма вам не нужны. Готовы спорить, мы знаем, что вы выберете.

Капча, чтобы проверить, что вы не робот. Нам при регистрации пришлось два раза выбрать спиральную галактику — не сильно сложно. А если вы робот — не причиняйте вред человеку своим действием или бездействием.

Подтверждение почты. После капчи вам придёт письмо с кодом на почту. Введите его на следующей странице.

Вот здесь. Главное — не ошибайтесь.

Общая информация о вас и вашей команде. Если вы регистрируете аккаунт для себя, выбирайте Just me. Второй пункт — студент вы или учитель. Выбирайте «Студент», если вы не учитель.

Интересы. Дальше Гитхаб спросит вас об интересах — то есть о том, зачем вы регистрируете аккаунт. Из вариантов:

  • Совместная разработка и код ревью.
  • Автоматизация. CI/CD, API и другие админские вещи.
  • Безопасность. Двухфакторная аутентификация, ревью, сканирование кода и списки зависимостей.
  • Приложения. Выбирайте, если будете использовать GitHub Mobile, CLI, Desktop.
  • Управление проектами. Проекты, метки, ишьи, вики и другие управленческие дела.
  • Управление командами. Организации, приглашения, роли, домены.
  • Сообщество. Выбирайте, если Гитхаб интересен вам как соцсеть.

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

Выбор тарифа. На выбор бесплатный тариф или платный GitHub Pro. Практика показывает, что для большинства личных проектов хватит бесплатного тарифа. В сентябре 2022 в него входили:

  • Безлимитное количество репозиториев.
  • 2000 минут CI/CD в месяц.
  • 500 мегабайт места в хранилище пакетов.
  • Поддержка сообщества.

Выбор тоже можно пропустить, тогда у вас будет бесплатный тариф.

Всё готово. Теперь у вас есть аккаунт. Можете создать репозиторий и работать с ним, или склонировать чужой. А для работы у вас есть несколько удобных вариантов:

  • 28 сентября 2022

Работа с Git в Visual Studio Code

Работа с Git в Visual Studio Code

Если вы вёрстаете сайты или пишете код в редакторе Visual Studio Code, то Git за пять минут настраивается прямо внутри редактора. Не нужно запоминать команды для консоли, не нужно тыкать в лишние приложения.

Следуйте инструкции и всё получится.

  • 16 сентября 2022

Markdown за 5 минут

Markdown за 5 минут

Маркдаун, он же markdown — удобный и быстрый способ разметки текста. Маркдаун используют, если недоступен HTML, а текст нужно сделать читаемым и хотя бы немного размеченным (заголовки, списки, картинки, ссылки).

Главный пример использования маркдауна, с которым мы часто сталкиваемся — файлы readme.md , которые есть в каждом репозитории на Гитхабе. md в имени файла это как раз сокращение от markdown.

Другой частый пример — сообщения в мессенджерах. Можно поставить звёздочки вокруг текста в Телеграме, и текст станет полужирным.

Версии маркдауна отличаются, поэтому перепроверьте, какую вы используете.

  • 5 октября 2021

Шпаргалка по Git. Решение основных проблем

Шпаргалка по Git. Решение основных проблем

Поговорим о решении проблем с Git.

  • 11 декабря 2020

Полезные команды для работы с Git

Полезные команды для работы с Git

Работа с Git через терминал — это обязательная часть практики каждого современного фронтенд-специалиста. Однако, для начинающих это может показаться сложным. Чтобы упростить процесс обучения, мы собрали для вас все самые необходимые команды, которые пригодятся в работе с Git на первое время.

  • 1 января 2020

Как сжимать коммиты в 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-данных
  • GitHub-репозитории, о которых должен знать каждый разработчик
  • Пять алиасов Git, без которых мне не прожить

Сократите последние X коммитов с помощью Git

Мы часто слышим слово «сквош», когда говорим о рабочих процессах Git .

В этом уроке мы кратко расскажем, что такое сжатие Git. Затем мы поговорим о том, когда нам нужно раздавить коммиты. Наконец, мы более подробно рассмотрим, как сквошить коммиты.

2. Что такое Git Squashing?​

Когда мы говорим «сквош» в Git, это означает объединение нескольких непрерывных коммитов в один.

Давайте посмотрим на пример:

 ┌───┐ ┌───┐ ┌───┐ ┌───┐  ... │ A │◄─────┤ B │◄────┤ C │◄─────┤ D │  └───┘ └───┘ └───┘ └───┘   After Squashing commits B, C, and D:   ┌───┐ ┌───┐  ... │ A │◄─────┤ E │  └───┘ └───┘   ( The commit E includes the changes in B, C, and D.) 

В этом примере мы объединили коммиты B, C и D в E.

Далее мы обсудим, когда нам следует подавлять коммиты.

3. Когда скрывать коммиты?​

Проще говоря, мы используем сжатие, чтобы граф ветвлений оставался чистым.

Давайте представим, как мы реализуем новую функцию. Обычно мы фиксируем несколько раз, прежде чем достигнем удовлетворительного результата, например, некоторые исправления и тесты.

Однако, когда мы реализовали эту функцию, эти промежуточные коммиты выглядят излишними. Итак, мы можем захотеть объединить наши коммиты в один.

Другим распространенным сценарием, когда мы хотим раздавить коммиты, является слияние веток.

Скорее всего, когда мы начнем работать над новой фичей, мы запустим ветку фичи. Допустим, мы сделали свою работу с 20 фиксациями в нашей функциональной ветке.

Итак, когда мы объединяем ветку feature с веткой master, мы хотим объединить 20 коммитов в один. Таким образом, мы сохраняем ветку master в чистоте.

4. Как раздавить коммиты?​

Сегодня некоторые современные IDE, такие как IntelliJ и Eclipse , имеют встроенную поддержку общих операций Git. Это позволяет нам сжимать коммиты из графического интерфейса.

Например, в IntelliJ мы можем выбрать коммиты, которые мы хотим раздавить, и выбрать «Squash Commits» в контекстном меню, вызываемом правой кнопкой мыши:

./15eeaf846ad0acef82ac97f289a918a8.png

Однако в этом руководстве мы сосредоточимся на сквошинге с помощью команд Git.

Следует отметить, что squash не является командой Git, даже если это обычная операция Git. То есть « git squash… » — недопустимая команда Git.

Мы рассмотрим два разных подхода к раздавливанию коммитов:

  • Интерактивная перебазировка: git rebase -i …
  • Слияние с параметром –squash : git merge –squash «

Далее давайте посмотрим на них в действии.

5. Сжатие с помощью Interactive Rebase​

Прежде чем мы начнем, давайте создадим псевдоним Git slog (расшифровывается как короткий журнал), чтобы отображать журналы коммитов Git в компактном виде:

 git config --global alias.slog = log --graph --all --topo-order --pretty='format:%h %ai %s%d (%an)' 

В качестве примера мы подготовили репозиторий Git:

 $ git slog * ac7dd5f 2021-08-23 23:29:15 +0200 Commit D (HEAD -> master) (Kai Yuan)  * 5de0b6f 2021-08-23 23:29:08 +0200 Commit C (Kai Yuan)  * 54a204d 2021-08-23 23:29:02 +0200 Commit B (Kai Yuan)  * c407062 2021-08-23 23:28:56 +0200 Commit A (Kai Yuan)  * 29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  * 34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  * cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

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

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

Далее, давайте раздавим последние четыре коммита.

Стоит отметить, что когда мы говорим «последние X коммитов», мы говорим о последних X коммитах из HEAD .

Итак, в данном случае это последние четыре коммита:

 * ac7dd5f ... Commit D (HEAD -> master)  * 5de0b6f ... Commit C  * 54a204d ... Commit B  * c407062 ... Commit A 

Более того, если мы раздавили уже отправленные коммиты и хотим опубликовать раздавленный результат, мы должны сделать принудительную отправку.

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

Кроме того, когда мы действительно хотим сделать принудительную отправку, мы должны убедиться, что принудительно протолкнули только требуемую ветку.

Например, мы можем установить для свойства push.default значение current , чтобы только текущая ветвь была отправлена/принудительно отправлена в удаленный репозиторий.

В качестве альтернативы мы можем принудительно отправить только одну ветку, добавив «+» перед refspec для отправки. Например, git push origin +feature принудительно отправит ветку функций .

5.1. Раздавить последние X коммитов​

Вот синтаксис для удаления последних X коммитов с помощью интерактивной перебазировки:

 git rebase -i HEAD~[X] 

Итак, вот что мы должны запустить:

 git rebase -i HEAD~4 

После того, как мы выполним команду, Git запустит системный редактор по умолчанию (редактор Vim в этом примере) с коммитами, которые мы хотим удалить, и интерактивной справочной информацией по перебазированию:

./968e4a513767adc9c225cbaee22c5e6c.png

Как видно на снимке экрана выше, все четыре коммита, которые мы хотим сжать, перечислены в редакторе с помощью команды pick .

Подробное руководство о том, как управлять каждой фиксацией и сообщением о фиксации, приведено в последующих строках с комментариями.

Например, мы можем изменить команду выбора коммитов на s или squash , чтобы раздавить их:

./6359fa5dd9ce2b6fba9f6fa60c0b3b5e.png

Если мы сохраним изменения и выйдем из редактора, Git выполнит перебазирование, следуя нашим инструкциям:

 $ git rebase -i HEAD~4  [detached HEAD f9a9cd5] Commit A  Date: Mon Aug 23 23:28:56 2021 +0200  1 file changed, 1 insertion(+), 1 deletion(-)  Successfully rebased and updated refs/heads/master. 

Теперь вот что мы увидим, если еще раз проверим журнал коммитов Git:

 $ git slog * f9a9cd5 2021-08-23 23:28:56 +0200 Commit A (HEAD -> master) (Kai Yuan)  * 29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  * 34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  * cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

Как видно из вывода slog , мы сжали последние четыре коммита в один новый коммит, f9a9cd5 .

Теперь, если мы посмотрим на полный журнал фиксации, мы увидим, что сообщения всех раздавленных коммитов объединены:

 $ git log -1  commit f9a9cd50a0d11b6312ba4e6308698bea46e10cf1 (HEAD -> master)  Author: Kai Yuan Date: 2021-08-23 23:28:56 +0200   Commit A   Commit B   Commit C   Commit D 

5.2. Когда X относительно большой​

Мы узнали, что команда git rebase -i HEAD~X довольно проста для уничтожения последних X коммитов.

Однако подсчет большего числа X может быть проблемой, когда в нашей ветке довольно много коммитов. Более того, он подвержен ошибкам.

Когда X подсчитать непросто, мы можем найти хэш коммита, который мы хотим перебазировать «на», и запустить команду git rebase -i hash_onto .

Давайте посмотрим, как это работает:

 $ git slog e7cb693 2021-08-24 15:00:56 +0200 Commit F (HEAD -> master) (Kai Yuan)  2c1aa63 2021-08-24 15:00:45 +0200 Commit E (Kai Yuan)  ac7dd5f 2021-08-23 23:29:15 +0200 Commit D (Kai Yuan)  5de0b6f 2021-08-23 23:29:08 +0200 Commit C (Kai Yuan)  54a204d 2021-08-23 23:29:02 +0200 Commit B (Kai Yuan)  c407062 2021-08-23 23:28:56 +0200 Commit A (Kai Yuan)  29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

Как видно из слога git , в этой ветке у нас есть несколько коммитов.

Теперь предположим, что мы хотели бы удалить все коммиты и выполнить ребазинг на коммит 29976c5 с сообщением: BugFix #1 .

Таким образом, нам не нужно считать, сколько коммитов нам нужно раздавить. Вместо этого мы можем просто выполнить команду git rebase -i 29976c5.

Мы узнали, что нам нужно изменить команды выбора на сквош в редакторе, и Git выполнит сжатие, как мы и ожидали:

 $ git rebase -i 29976c5  [detached HEAD aabf37e] Commit A  Date: Mon Aug 23 23:28:56 2021 +0200  1 file changed, 1 insertion(+), 1 deletion(-)  Successfully rebased and updated refs/heads/master.  $ git slog * aabf37e 2021-08-23 23:28:56 +0200 Commit A (HEAD -> master) (Kai Yuan)  * 29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  * 34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  * cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

6. Сквош путем слияния с параметром –squash ​

Мы увидели, как использовать интерактивную перебазировку Git для сглаживания коммитов. Это может эффективно очистить граф коммитов в ветке.

Однако иногда мы делаем много коммитов в нашей функциональной ветке, работая над ней. После того, как мы разработали функцию, мы обычно хотим объединить ветвь функции с основной ветвью, скажем, «мастер».

Мы хотим, чтобы граф основной ветки оставался чистым, например, одна фича — одна фиксация. Но нас не волнует, сколько коммитов в нашей функциональной ветке.

В этом случае мы можем использовать команду commit git merge –squash для достижения этой цели.

Давайте разберемся на примере:

 $ git slog * 0ff435a 2021-08-24 15:28:07 +0200 finally, it works. phew! (HEAD -> feature) (Kai Yuan)  * cb5fc72 2021-08-24 15:27:47 +0200 fix a typo (Kai Yuan)  * 251f01c 2021-08-24 15:27:38 +0200 fix a bug (Kai Yuan)  * e8e53d7 2021-08-24 15:27:13 +0200 implement Feature2 (Kai Yuan)   | * 204b03f 2021-08-24 15:30:29 +0200 Urgent HotFix2 (master) (Kai Yuan)   | * 8a58dd4 2021-08-24 15:30:15 +0200 Urgent HotFix1 (Kai Yuan)   |/  * 172d2ed 2021-08-23 23:28:56 +0200 BugFix #2 (Kai Yuan)  * 29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  * 34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  * cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

Как видно из приведенного выше вывода, в этом репозитории Git мы реализовали «Feature2» в ветке функций .

В нашей функциональной ветке мы сделали четыре коммита.

Теперь мы хотим объединить результат обратно в основную ветку с помощью одной единственной фиксации, чтобы сохранить основную ветку в чистоте:

 $ git checkout master Switched to branch 'master'   $ git merge --squash feature Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested 

В отличие от обычного слияния, когда мы выполняем команду git merge с параметром –squash , Git не будет автоматически создавать фиксацию слияния.

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

 $ git status On branch master Changes to be committed:  (use "git restore --staged . " to unstage)   modified: readme.md 

В этом примере все изменения «Feature2» относятся к файлу readme.md .

Нам нужно зафиксировать изменения, чтобы завершить слияние:

 $ git commit -am'Squashed and merged the Feature2 branch'   [master 565b254] Squashed and merged the Feature2 branch  1 file changed, 4 insertions(+) 

Теперь давайте проверим граф ветвления:

 $ git slog * 565b254 2021-08-24 15:53:05 +0200 Squashed and merged the Feature2 branch (HEAD -> master) (Kai Yuan)  * 204b03f 2021-08-24 15:30:29 +0200 Urgent HotFix2 (Kai Yuan)  * 8a58dd4 2021-08-24 15:30:15 +0200 Urgent HotFix1 (Kai Yuan)   | * 0ff435a 2021-08-24 15:28:07 +0200 finally, it works. phew! (feature) (Kai Yuan)   | * cb5fc72 2021-08-24 15:27:47 +0200 fix a typo (Kai Yuan)   | * 251f01c 2021-08-24 15:27:38 +0200 fix a bug (Kai Yuan)   | * e8e53d7 2021-08-24 15:27:13 +0200 implement Feature2 (Kai Yuan)   |/  * 172d2ed 2021-08-23 23:28:56 +0200 BugFix #2 (Kai Yuan)  * 29976c5 2021-08-23 23:28:33 +0200 BugFix #1 (Kai Yuan)  * 34fbfeb 2021-08-23 23:28:19 +0200 Feature1 implemented (Kai Yuan)  * cbd350d 2021-08-23 23:26:19 +0200 Init commit (Kai Yuan) 

Мы видим, что мы объединили все изменения в ветке feature с веткой master , и у нас есть один единственный коммит, 565b254 , в ветке master .

С другой стороны, в ветке feature у нас по-прежнему четыре коммита.

7. Заключение​

В этой статье мы говорили о том, что такое сквоширование Git и когда нам следует подумать об его использовании.

Мы также узнали, как сквошить коммиты в Git.

  • 1. Обзор
  • 2. Что такое Git Squashing?
  • 3. Когда скрывать коммиты?
  • 4. Как раздавить коммиты?
  • 5. Сжатие с помощью Interactive Rebase
    • 5.1. Раздавить последние X коммитов
    • 5.2. Когда X относительно большой

    Как объединить несколько коммитов в один

    Есть ветка, в которой последовательно лежит 13 коммитов. Есть нормальный способ их объединить? А по сути, я могу перейти в основную ветку и перекинуть в нее только последний с помощь cherry-pick, т.к. он содержит в себе актуальную версию, что и нужно в итоге. Хотя могу ошибаться

    Отслеживать
    34k 25 25 золотых знаков 130 130 серебряных знаков 222 222 бронзовых знака
    задан 29 окт 2015 в 9:54
    1,297 2 2 золотых знака 12 12 серебряных знаков 21 21 бронзовый знак
    Может быть git rebase ? Что именно вы понимаете по «нормальный способ«?
    29 окт 2015 в 9:57
    И что именно вы хотите объединять? Ветки или коммиты?
    29 окт 2015 в 9:59
    @DmitriySimushev Такое же состояние ветки, только с одним коммитом вместо 13
    29 окт 2015 в 10:00
    И как бы комиты на то и комиты чтоб лежали отдельно и можно было любой достать
    29 окт 2015 в 10:00

    Из обсуждения так и не понял что вам нужно, но если говорить про склеивание коммитов (squash) то это легко гуглится.

    29 окт 2015 в 10:05

    3 ответа 3

    Сортировка: Сброс на вариант по умолчанию

    Пусть вы хотите склеить последние три коммита (для 13-ти коммитов процесс выглядит аналогично). Для этого есть отличный метод с использованием git rebase . Эта команда позволяет изменять историю коммитов. Алгоритм работы выглядит следующим образом:

    1. Сделайте резервную копию. Это совсем не обязательно, но поможет сохранить нервные клетки, если что-то пойдет не так. Варианты:
      1. Копия каталога с файлами в котором развернут git репозиторий.
      2. git branch backup или git tag backup в последнем коммите.
      3. Прочитать справку по командам reflog и reset и знать, что бэкапы уже есть.
      pick bcdca61 Second commit pick 4643a5f The third commit with cool stuff pick e0ca8b9 The last commit # Rebase 48411de..e0ca8b9 onto 48411de # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell 
      pick bcdca61 Second commit squash 4643a5f The third commit with cool stuff squash e0ca8b9 The last commit # Rebase 48411de..e0ca8b9 onto 48411de # # . 

      Вот здесь, есть развернутая информация о том, как перезаписывать историю в git.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *