# Git

Система контроля версий Git

# Команды Git

Отображение непроиндексированных изменений - `git diff`

Отображение списка отличающихся файлов - `git diff --name-only <em>branch1 branch2</em>`

Отображение статуса отличающихся файлов (добавлен/удалён/модифицирован) - `git diff --name-status <em>branch1 branch2</em>`

Отображение проиндексированных изменений, входящих в следующий коммит - `git diff --staged` или `git diff --cached`

Удаление файла из индекса - `git rm --cached <em>file</em>`

Отмена изменений в файле - `git checkout <em>file</em>`

Удаление последнего локального коммита - `git reset --hard HEAD~`

Принудительная отправка изменений в удалённую ветку (в т.ч. после удаления локального коммита) - `git push -f`

Отправка всех веток в удалённый репозиторий - `git push --all origin`

Отправка ветки *branch* в удалённый репозиторий - `git push origin <em>branch</em>`

Отправка ветки *branch* в удалённый репозиторий, если ранее её там не существовало - `git push origin <em>branch:remotebranch</em>`

Создание новой ветки с переключением на неё - `git switch -c <em>branch</em>`

Создание новой ветки из удалённой ветки с переключением на неё - `git switch -c <em>branch origin:remotebranch</em>`

Сохранение изменений во временное хранилище (к примеру, чтобы переключиться в другую ветку) - `git stash`

Извлечение изменений из временного хранилища - `git stash pop`

Синхронизация изменений с удалённым сервером - `git fetch origin`

Удаление ветки на удалённом сервере - `git push origin --delete <em>remotebranch</em>`

Генерация номера сборки - `git describe master`

# Cheat Sheet

[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/RZximage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/RZximage.png)

# Как конфигурировать Git

Какие настройки `git config` сейчас следует устанавливать по умолчанию? Ниже рассмотрены избранные настройки, менять которые не стесняются даже разработчики самого Git.

Несколько недель назад я [написал](https://blog.gitbutler.com/why-is-git-autocorrect-too-fast-for-formula-one-drivers/) о настройке Git help.autocorrect и поведал странную историю о том, как её значение стали задавать в децисекундах.

Эта статья заставила меня поразмыслить и о других настройках git config, вероятно, не известных широкому кругу пользователей. Возможно, для этих настроек стоит задать по умолчанию иные значения, чем действуют сейчас.

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

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

#### TLDR

Начнём с вопроса, который, возможно, не особо занимал кого-то из вас, а именно с чудесной и печальной истории значений rerere или ей подобных. Возможно, кого-то из вас посещает мысль «просто сообщите мне настройки — и я не глядя кину их в мой файл `~/.gitconfig`».

Что ж, ценю вашу честность. А теперь начинается интересное:

```
# Явно пойдёт на пользу git 

[column]
        ui = auto
[branch]
        sort = -committerdate
[tag]
        sort = version:refname
[init]
        defaultBranch = main
[diff]
        algorithm = histogram
        colorMoved = plain
        mnemonicPrefix = true
        renames = true
[push]
        default = simple
        autoSetupRemote = true
        followTags = true
[fetch]
        prune = true
        pruneTags = true
        all = true

# чёрт возьми, почему бы и нет?

[help]
        autocorrect = prompt
[commit]
        verbose = true
[rerere]
        enabled = true
        autoupdate = true
[core]
        excludesfile = ~/.gitignore
[rebase]
        autoSquash = true
        autoStash = true
        updateRefs = true

# дело вкуса (раскомментируйте, если не боитесь)

[core]
        # fsmonitor = true
        # untrackedCache = true
[merge]
        # (just 'diff3' if git version < 2.3)
        # conflictstyle = zdiff3 
[pull]
        # rebase = true
```

Копипаста, друзья мои.

#### Как разработчики ядра Git конфигурируют свои Git-ы?

Прежде, чем углубиться в каждую из этих опций по очереди, зададимся интересным вопросом: есть ли среди разработчиков Git наши единомышленники, также считающие, что эти заданные по умолчанию значения стоит поменять?

Этот вопрос не так давно всплыл в почтовой рассылке Git. Честно говоря, о некоторых из этих настроек я сам узнал только из mailing [этого треда](https://lore.kernel.org/git/60b5d281552d6_e359f20828@natae.notmuch/?ref=blog.gitbutler.com), озаглавленного «Spring Cleaning» (Весенняя уборка), в котором Фелипе Контрерас бросил вызов команде разработчиков ядра Git. Он спросил, готовы ли те удалить все накопившиеся у них конфигурационные опции и псевдонимы и на своей шкуре попробовать, каково работать с немодифицированным Git, «из коробки».

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

[Результаты](https://lore.kernel.org/git/60df97ed24687_34a92088a@natae.notmuch/?ref=blog.gitbutler.com) оказались очень интересными: получился весьма компактный список из 9 конфигурационных настроек и 3 псевдонимов, по поводу которых все участники эксперимента более-менее сошлись как по новым желательным умолчаниям. Рассмотрим изменения, которые было предложено внести в настройки конфигурации.

```
merge.conflictstyle = zdiff3
rebase.autosquash = true
rebase.autostash = true 
commit.verbose = true
diff.colorMoved = true
diff.algorithm = histogram
grep.patternType = perl
feature.experimental = true
branch.sort = committerdate
```

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

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

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

Сгруппирую эти настройки в три категории:

- Определённо пойдёт на пользу Git
- Чёрт возьми, почему бы и нет?
- Дело вкуса

Что ж, приступим.

#### Определённо пойдёт на пользу Git

Настройки из первой группы явственно улучшают Git, если включены по умолчанию. Активировав любую из них, вы просто ничего не потеряете.

#### Перечисление веток

В более раннем посте я уже упоминал о «советах Git» (Git Tips) в разделе «[Branch Stuff](https://blog.gitbutler.com/git-tips-2-new-stuff-in-git/#some-git-branch-stuff)», но, поскольку эта информация была и в списке «Spring Cleaning», думаю, все согласятся: перечисление веток Git по умолчанию не должно упорядочиваться по алфавиту.

Есть две настройки, помогающие улучшить эту ситуацию: `branch.sort` и `column.ui`. Первая из них сортирует список не по алфавиту, а по свежести дат коммитов (поэтому самые интересные коммиты должны находиться в верхней части списка). Вторая выстраивает имена веток в формате столбцов так, чтобы на экране было видно больше такой информации.

```
git config --global column.ui auto
git config --global branch.sort -committerdate
```

Настройка `column.ui` также влияет на вывод других списковых команд (очистка, статус, тег), но в целом я полагаю, что она лучше, чем действующая по умолчанию сейчас.

[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/6pNimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/6pNimage.png)

Можно сортировать записи не только по дате коммита, но я считаю, что это определённо полезнейшая из опций.

#### Перечисление тегов

Затрагивая тему перечисления, остаётся только удивляться, что опция перечисления тегов по умолчанию не включена — хотя именно она нужна практически кому угодно.

Как правило, попытавшись перечислить теги в алфавитном порядке, вы получите нечто подобное:

```
$ git tag
nightly/0.5.100
nightly/0.5.1000
nightly/0.5.1001
nightly/0.5.101
nightly/0.5.1010
```

Никому не нравится, когда 0.5.101 идёт после 0.5.1000, но таков алфавитный порядок. Можно исправить ситуацию, установив следующую опцию:

```
git config --global tag.sort version:refname
```

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

#### Ветка по умолчанию

Этот пример, возможно, чуть более противоречив, поскольку во многом обусловлен сложившимися привычками. Но в Git лучше предусмотреть для ветки определённое имя по умолчанию, на которое система не будет ругаться всякий раз, когда вы создаёте новый репозиторий при помощи `init`.

```
git config --global init.defaultBranch main
```

Лично меня вполне устраивает master, и я использую такое имя в большинстве из моих репозиториев по умолчанию. Но меня вполне устраивает и main. Поэтому простой выберите наиболее устраивающий вас вариант и установите его.

Мне кажется, просто тупо, что в настоящее время Git отвлекает наше внимание на это, тогда как можно было бы просто обновить значение по умолчанию. Хотелось бы, чтобы в Git в данном случае было лучше со вкусом, поэтому только и остаётся установить тот вариант, который вам самим кажется наиболее разумным. Но выбор за вами.

#### Улучшенная разность

На самом деле, можно написать целый пост об алгоритмах `git diff`, но, если коротко — по умолчанию Git использует для вычисления разности коммитов старый, быстрый и довольно надёжный «алгоритм Майерса».

Чтобы вы понимали, что такое «старый» — уточню, что этот алгоритм был впервые описан в статье, опубликованной в 1986 году, почти 40 лет назад. Если мы с вами примерно ровесники, могу напомнить, как ощущались те времена. По телевизору тогда показывали комедию «Три амиго», мультфильм «Американский хвост», а в кинотеатрах вышел первый «Горец».

В любом случае, с тех пор были достигнуты некоторые результаты (не без уступок), и вы, возможно, удивитесь, что в базовой комплектации Git встроено 4 готовых к использованию алгоритма вычисления разности: myers, minimal, [patience](https://blog.jcoglan.com/2017/09/19/the-patience-diff-algorithm/?utm_source=chatgpt.com) и histogram.

Почти не сомневаюсь, что вы будете пользоваться алгоритмом histogram (инкрементная усовершенствованная версия «patience»), а не «myers», действующим по умолчанию. Можно глобально изменить этот алгоритм вот так:

```
git config --global diff.algorithm histogram
```

Вот пример простого перемещения кода с разницей в myers и histogram, позволяющий составить краткое впечатление о том, насколько умнее можно всё это организовать:

Допустим, мы сдвигаем класс css под другой подобный ему класс, немного его изменяем, а затем выполняем команду `git diff `при помощи алгоритма `myers`, заданного по умолчанию. Получим нечто подобное:

[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/yntimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/yntimage.png)

Да, немного запутанно. Вот что в таком же сценарии нам дал бы histogram:

[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/8DAimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/8DAimage.png)

Теперь становится немного яснее, что именно здесь произошло.

Не далее, чем в прошлом году Элия (из нашей команды [Git Merge](https://www.youtube.com/watch?v=KXPmiKfNlZE&ref=blog.gitbutler.com)) предположил, что  
[histogram или patience](https://lore.kernel.org/git/CABPp-BEmgOAj17DozyXNaf-9CawDic4uTpMbckef3+zHf7URqQ@mail.gmail.com/?ref=blog.gitbutler.com) лучше подошли бы в качестве вариантов по умолчанию. Фелипе, написавший «Spring Cleaning», в целом предлагал то же самое, но в реальности маловероятно в какой-либо обозримой перспективе этот вызов будет принят.

Здесь много материала, но можно внести в `git diff` и некоторые более мелкие корректировки:

```
git config --global diff.colorMoved plain
git config --global diff.mnemonicPrefix true
git config --global diff.renames true
```

Вариант colorMoved также был в списке предложений из «Spring Cleaning», поэтому данное изменение также, пожалуй, следует внести по умолчанию.

Рассмотрим предыдущий пример с переносом кода при включённой опции `colorMoved`:

<figure class="full-width" id="bkmrk--3">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/RLgimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/RLgimage.png)

</figure>Вы видите, чем отличается перемещённый код и добавленная строка. При включённой опции colorMoved перемещение кода будет отображаться разными цветами, в зависимости от того, были какие-то строки добавлены или удалены.

Опция diff.renames позволяет выявить, был ли файл переименован, и обычно это хорошо (пусть и немного затратно), а diff.mnemonicPrefix заменяет` a/` и `b/ `в выведенном заголовке разности фрагментов на информацию о том, откуда пришло различие, вот так: `i/` (индекс), `w/` (рабочий каталог) или `c/` (коммит).

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

```
❯ git diff
diff --git i/apps/web/page.js w/apps/web/page.js
index 7568be2ef..b9e9a00d7 100644
--- i/apps/web/page.js
+++ w/apps/web/page.js
```

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

#### Улучшаем пуш

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

Есть три обновлённые настройки, задавая которые по умолчанию, можно значительно повысить удобство работы с инструментом. Первая (`push.default simple`) назначена по умолчанию, начиная с Git 2.0, но другие по-прежнему нужно устанавливать явно.

```
git config --global push.default simple # (по умолчанию с версии 2.0)
git config --global push.autoSetupRemote true
git config --global push.followTags true
```

Этот момент всегда был в Git болевой точкой. Новое умолчание simple более или менее рассчитано на работу с централизованными потоками задач, стандартно пуш осуществляется в текущую ветку и в одноимённую ветку на удалённой машине. Я думаю, это очень разумное умолчание.

Однако, если эта ветка не существует, а отслеживание веток не настроено, то вы всё равно получите следующую ошибку:

```
$ git push
fatal: The current branch my-branch-name has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin my-branch-name
```

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

Если установить `push.autoSetupRemote` в `true`, то эту ошибку вы более получать не будете. Если вышестоящая ветка не установлена, то программа её автоматически установит. Просто не передать, как мне нравится эта настройка.

Наконец, настройка `push.followTags` запушит все теги, имеющиеся у вас на локальной машине, но отсутствующие на сервере. Это происходит при каждой пуш-операции. Я на этом несколько раз обжигался. Но, если вы создаёте теги на локальной машине, то активируйте эту настройку, тогда сможете не беспокоиться, что ваших тегов не увидят другие люди.

#### Улучшенная выборка

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

Лично я считаю, что по умолчанию Git должен работать так: держать ссылки на ваш код, расположенные на локальной машине, максимально схожими на ссылки, находящиеся на удалённой машине. Отсекайте всё устаревшее, т.д.

Поэтому я поставил бы по умолчанию следующие настройки выборки:

```
git config --global fetch.prune true
git config --global fetch.pruneTags true
git config --global fetch.all true
```

На самом деле, всё это позволяет нам не сомневаться, что мы удалим `origin/blah`, если `blah` будет удалено на сервере. Причём всё это будет автоматически делаться на всех удалённых машинах, если правильно сконфигурировать такие настройки. Мне кажется, это очень разумно.

#### Чёрт возьми, почему бы и нет?

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

Я не уверен, что здесь обязательно менять умолчания, но и не думаю, что приведённые здесь варианты кому-то повредят. В некоторых случаях они даже очень пригодятся. Поэтому включу их в мой список.

#### Предложения автозамены

Как я подробно объяснял в одном из моих [предыдущих постов](https://blog.gitbutler.com/why-is-git-autocorrect-too-fast-for-formula-one-drivers/), в Git есть такая довольно приятная возможность: если случайно механически ошибётесь при наборе команды, система попробует догадаться, что вы имели в виду, и запустить именно нужную команду.

По умолчанию мы попытаемся этого избежать, а сделать наоборот: чтобы программа сама предлагала вам, что ввести.

```
git config --global help.autocorrect prompt
```

Если вы хотите подробнее почитать об этой настройке, чем она обоснована, а также какова её история, то вот [дотошный пост о ней](https://blog.gitbutler.com/why-is-git-autocorrect-too-fast-for-formula-one-drivers/).

#### Коммиты с указанием разности

Это предложение содержалось в списке «Spring Cleaning» — думаю, оно попало туда в основном потому, что с его помощью можно расширить контекст и добавить информацию, с которой затем можно будет сверяться, когда будете писать в редакторе сообщения о коммитах.

По умолчанию `git commit` будет выдавать сообщение, которое выглядит примерно так:

<figure class="full-width" id="bkmrk--4">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/1aUimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/1aUimage.png)

</figure>Здесь мы видим только список изменившихся файлов. Если установить `commit.verbose` в значение `true`, то сюда будет записан весь вывод `diff`, и вы сможете сверяться с ним, когда будете писать ваше сообщение.

```
git config --global commit.verbose true
```

Вот какой вид это примет теперь, когда вы перейдёте к коммиту:

<figure class="full-width" id="bkmrk--5">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/X0zimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/X0zimage.png)

</figure>Всё это будет удалено из сообщения о коммите (всё, что расположено ниже этой забавной «линии разреза» `-- >8 --` ), но зато вы получите гораздо более подробный контекст, когда будете писать сообщение.

#### Повторное использование ранее записанных разрешений конфликтов

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

```
git config --global rerere.enabled true
git config --global rerere.autoupdate true
```

Опция `enabled` гарантирует, что система будет записывать состояния «до» и «после» конфликтов при перебазировании. После этого `autoupdate` будет автоматически раз за разом применять проверенные разрешения конфликтов, с которыми сталкивается не в первый раз. Я достаточно подробно написал об этом [здесь](https://blog.gitbutler.com/git-tips-1-theres-a-git-config-for-that/#reuse-recorded-resolution), поэтому не буду здесь заново утомлять вас этой темой.

#### Глобальный файл ignore

Эта настройка даже не простая, а тупая, но, поскольку есть файл `~/.gitconfig` с глобальными значениями, было бы круто иметь и файл `~/.gitignore` с глобальными значениями. Благодаря этой настройке достигается следующее:

```
git config --global core.excludesfile ~/.gitignore
```

На самом деле, в этом, мягко говоря, нет необходимости, поскольку Git и так ищет глобальные ignore-значения в двух следующих местах: `~/git/ignore` и `~/.config/git/ignore`. Но, поскольку они выглядят немного непонятно, полагаю, было бы хорошо проложить туда более логичный путь.

#### Чуть более аккуратное перебазирование

В этом разделе рассмотрим преимущественно тот практический случай, в котором вы исправляете и ужимаете ваши комментарии. Если вы не знаете, что это такое, можете почитать мой более ранний пост на тему [autosquashing](https://blog.gitbutler.com/git-autosquash/).

Правда, если этой работой приходится заниматься в больших масштабах (или даже время от времени), вам определённо помогут и не повредят следующие настройки.

```
git config --global rebase.autoSquash true
git config --global rebase.autoStash true
git config --global rebase.updateRefs true
```

Настройка `updateRefs` практически наверняка должна выставляться по умолчанию, честно. Она просто организует в виде ветки стопку ссылок и гарантирует, что при перебазировании ветки эти ссылки также будут правильно перемещены.

#### Дело вкуса

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

#### Улучшенная обработка конфликтов при слиянии

Итак, хотя эта тема и затрагивается в треде «Spring Cleaning» как потенциальная новая настройка по умолчанию, я не уверен, что с этим можно согласиться.

Когда в Git возникает конфликт при слиянии веток, лучше не расставлять маркеры конфликтов слева и справа, можно попросить вставить ветку, которая выглядела бы как новая база. Иногда это бывает по-настоящему полезно, но некоторых весьма раздражает.

```
git config --global merge.conflictstyle zdiff3
```

В почтовой рассылке Git шли дискуссии о том, не активировать ли эту настройку по умолчанию. Кстати, в GitButler при работе с маркерами конфликтов используется стратегия `diff3` — и, будем честны, далеко не всем она нравится.

Рассмотрим пример с установкой простого маркера при конфликте слияния, который может возникнуть в файле при слиянии или перебазировании:

<figure class="full-width" id="bkmrk--6">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/2NHimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/2NHimage.png)

</figure>Если включить настройку `merge.conflictStyle zdiff3`, получим:

<figure class="full-width" id="bkmrk--7">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/4fuimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/4fuimage.png)

</figure>В сущности, кроме секций &lt;&lt;&lt;&lt;&lt;&lt; и &gt;&gt;&gt;&gt;&gt;&gt;, в которых вы видите, как вы изменили блок, и как его изменил кто-то другой, здесь также добавляется блок |||||||, демонстрирующий, как выглядела ветка до вышеупомянутых изменений.

Этот дополнительный контекст (позволяющий судить, как выглядела ветка до того, как в неё были внесены изменения) иногда бывает крайне полезен, но, как правило, это всего лишь дополнительные данные, в которых можно запутаться.

На самом деле, именно от вас зависит, хотите ли вы иметь под рукой эти дополнительные данные.

<details class="spoiler" id="bkmrk-%D0%A1%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D0%B9-%D1%82%D0%B5%D0%BA%D1%81%D1%82-%D0%A1%D1%82%D1%80%D0%B0%D1%82%D0%B5"><summary>Скрытый текст</summary>

Стратегия `diff3` применялась в Git почти всегда. Я рекомендую здесь zdiff3, что означает "ревнивое `diff3`" и чуть лучше на практике, но этот вариант доступен только начиная с версии Git 2.35 (январь 2022). Если вы работаете с более старой версией Git — просто уберите "`z`".

</details>#### Улучшенное подтягивание

Конечно, в споре о слиянии и перебазировании едва ли можно прийти к общему мнению, но, как правило, у нас есть предпочтения. Возможно, вы не знали, что, если установить `git pull` по умолчанию, то делаться будет только один или другой вариант. Нет необходимости в `git pull --rebase`, можно просто задать по умолчанию следующее:

```
git config --global pull.rebase true
```

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

#### Выполняйте процессы fsmonitor

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

Может быть, эту настройку и не стоит задавать по умолчанию, но она неплоха, и в определённых случаях, что называется «делает разницу». Может быть, стоит спрашивать в `git clone`, хотите ли вы её задействовать. В любом случае, такая опция существует.

```
git config --global core.fsmonitor true
git config --global core.untrackedCache true
```

Так будет запускаться процесс для мониторинга файловой системы (по одному на каждый репозиторий), который будет замечать изменения в файлах и обновлять кэш, так, что `git` `status` не придётся заново индексировать каждый файл тысячами статистических вызовов `mtime`, лишь чтобы проверить, не появились ли элементарные изменения в логах.

Подчеркну, что в данном случае запускается по одному процессу на каждый репозиторий, в котором вы работаете — может получиться немало. Обычно, правда, работают они не так активно, поскольку основаны на событиях, и поэтому они не оказывают заметной нагрузки на память или ЦП, даже если таких процессов сотни. Но стоит иметь в виду такую возможность. Также просто можете убрать опцию `--global` и активировать её только в больших репозиториях.

#### Заключение

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

Есть и множество других способов пришпорить Git (псевдонимы, классные внешние инструменты [pager](https://github.com/dandavison/delta?ref=blog.gitbutler.com) и [diff](https://github.com/so-fancy/diff-so-fancy?ref=blog.gitbutler.com), другие подобные вещи), но я думаю, что вам было бы лучше всего придерживаться глобально полезных и относительно простых стандартных настроек Git.

P.S. В конфигурационный файл для соблюдения правила "1 строка = 1 запись" можно добавить:

```
[format]
	pretty = format:%C(cyan bold)%H%C(reset) %ci %C(italic)(%cr)%C(reset) %C(blue)%cn%C(reset) %C(auto,bold)%G?(%GT)%C(reset) %C(green)%s%C(magenta)%d%C(reset) %C(red)(%an)%C(reset) %C(yellow)[%p]%C(reset)
```

Выглядит так:

[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/scaled-1680-/sphimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2025-11/sphimage.png)

# Основные команды GIT

### О чем статья

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

### Что такое GIT

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

### Предустановка

Необходимые инструменты для работы:

1. `git`. Скачать `git` можно по ссылке [https://git-scm.com/downloads](https://git-scm.com/downloads).
2. Текстовый редактор. Можете использовать любой. В моем случае `VS Code`. Ссылка: [https://code.visualstudio.com/download](https://code.visualstudio.com/download).
3. Зарегистрировать аккаунт на [Github](https://github.com/) и создать новый репозиторий на странице [https://github.com/new](https://github.com/new). Вы можете оставить все по умолчанию, указав только название репозитория. Я же назову его `<strong><em>Guide</em></strong>`. Затем выйдет страница, которая также описывает как начать пользоваться `Git`-ом.
4. Два каталога (папки) для наглядной работы некоторых `git`-команд (имитации командной работы). Я расположил их на рабочем столе и назвал `root` — будем работать в основном в ней, и `addon` — имитация командной работы.

### Содержание

#### Первые шаги, первый push

1. [`git init` — Инициализация репозитория](#bkmrk-1.-%D0%98%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D1%80%D0%B5%D0%BF)
2. [`git config` — Настройки параметров конфигурации Git.](#bkmrk-2.-%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8-%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82)
3. [`git status` — Состояние рабочего каталога и индекса.](#bkmrk-3.-%D0%A1%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%87%D0%B5%D0%B3)
4. [`git add` — Добавление изменений в индекс.](#bkmrk-4.-%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5)
5. [`git reset` — Отмена изменений в репозитории.](#bkmrk-5.-%D0%9E%D1%82%D0%BC%D0%B5%D0%BD%D0%B0-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-)
6. [`git commit` — Сохранение изменений в локальном репозитории Git.](#bkmrk-6.-%D0%A1%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5)
7. [`git log` — Просмотр истории коммитов](#bkmrk-7.-%D0%9F%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B8-)
8. [`git push` — Отправка коммитов в удаленный репозиторий](#bkmrk-8.-%D0%9E%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B0-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2)

#### Вторые шаги

9. [`git branch` — Управление ветками](#bkmrk-9.-%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0%D0%BC)
10. [`git switch` — Переключение между ветками](#bkmrk-10.-%D0%9F%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BC%D0%B5%D0%B6)
11. [`git clone` — Создание копии удаленного репозитория](#bkmrk-11.-%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BF%D0%B8%D0%B8-%D1%83)
12. [`git stash` — Временное хранилище](#bkmrk-12.-%D0%92%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5-%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB)
13. [`git config alias` — Создание псевдонимов](#bkmrk-13.-%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BF%D1%81%D0%B5%D0%B2%D0%B4%D0%BE%D0%BD)
14. [`git checkout` — Работа с ветками, восстановление файлов и переключение на конкретные коммиты](#bkmrk-14.-%D0%A1%D1%82%D0%B0%D1%80%D1%88%D0%B8%D0%B9-%D0%B1%D1%80%D0%B0%D1%82-%D0%BA%D0%BE%D0%BC)
15. [`git merge` — Слияние изменений веток](#bkmrk-15.-%D0%A1%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8)
16. [`git fetch` — Загрузка обновлений из удаленного репозитория](#bkmrk-16.-%D0%97%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5)
17. [`git pull` — Извлечение и слияние изменений](#bkmrk-17.-%D0%98%D0%B7%D0%B2%D0%BB%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8-%D1%81%D0%BB%D0%B8)
18. [`Работа с текстовым редактором`](#bkmrk-18.-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2)
19. [`git rebase` — Ашалеть, что это за ЗВЕРЬ?](#bkmrk-19.-%D0%90%D1%88%D0%B0%D0%BB%D0%B5%D1%82%D1%8C%2C-%D1%87%D1%82%D0%BE-%D1%8D%D1%82%D0%BE)
20. [`git diff` — Просмотр различий между файлами](#bkmrk-20.-%D0%9F%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80-%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%B8)

#### Менее юзаемые команды

21. [`git difftool` — Просмотр различий и редактирование файлов](#bkmrk-21.-%D0%9F%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80-%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%B8)
22. [`git remote` — Работа с удалёнными репозиториями](#bkmrk-22.-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%83%D0%B4%D0%B0%D0%BB%D1%91%D0%BD%D0%BD)
23. [`git tag` — Теги](#bkmrk-23.-%D0%A2%D0%B5%D0%B3%D0%B8)
24. [`git restore` — Восстановления файлов из индекса или коммитов](https://wiki.kuksa.dev/24)
25. [`git cherry-pick` — Применение коммитов из одной ветки на другую](#bkmrk-25.-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8)
26. [`git revert` — Откат изменений](#bkmrk-26.-%D0%9E%D1%82%D0%BA%D0%B0%D1%82-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9)

#### Основные команды

[Обзор](#bkmrk-%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%8B-1)

#### Вывод

---

### Первые шаги, первый push

---

#### 1. Инициализация репозитория

```
git init

```

Команда используется для создания нового репозитория Git. Она инициализирует пустой репозиторий в указанной директории, создавая все необходимые файлы и директории для работы с Git.

---

#### 2. Настройки параметров конфигурации Git.

```
git config

```

Команда, используемая для настройки параметров конфигурации Git. Эти параметры могут быть настроены для текущего пользователя, всего репозитория или глобально (флаг `--global`) для всех репозиториев на компьютере.

При помощи следующей команды, Вы укажете имя (ТОЛЬКО для текущего репозитория), которое будет отображаться на отправленных Вами коммитами:

```
git config user.name "Ivan"

```

Если Вы хотите указать имя также и для будущих проектов, то используйте флаг `--global`:

```
git config --global user.name "Ivan"

```

Тоже самое можно проделать и с почтой. Она также будет отображаться в дальнейших коммитах:

```
git config user.email "your@gmail.com"
    или глобально
git config --global user.email "your@gmail.com"

```

Если Вы пропустите этот пункт, не указав `user.email` и `user.name`, то на этапе использования команды `git commit` Вас попросят их ввести.

---

#### 3. Состояние рабочего каталога и индекса

```
git status

```

Команда используется для отображения состояния рабочего каталога и индекса (staging area). Она показывает изменения, которые были добавлены в индекс и готовы для коммита, а также изменения, которые еще не были добавлены. Это помогает разработчикам отслеживать текущие изменения в проекте.

Добавим в текущий каталог файл `index.html`:

```
echo "<p>Hello Git!</p>" > index.html

```

Теперь можно использовать команду `git status`, после которой Вы увидите следующее:

```
git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        index.html

nothing added to commit but untracked files present (use "git add" to track)

```

Мы можем увидеть:

1. Мы находимся на ветке `master` (On branch master).
2. У нас до сих пор нет коммитов (No commits yet).
3. У нас имеются неотслеживаемые файлы (Untracked files).
4. Ничего не добавлено в commit, но имеются неотслеживаемые файлы (nothing added to commit but untracked files present).

Флаг `-u` отслеживает только `Untracked files`. Используется, когда необходимо увидеть только неотслеживаемые файлы и каталоги.

---

#### 4. Добавление изменений в индекс

```
git add

```

<div class="code-explainer" id="bkmrk-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D1%82%D1%81%D1%8F-2">Команда используется для добавления изменений в рабочем каталоге (working directory) в индекс (staging area), подготавливая их для следующего коммита. Это первый шаг в процессе сохранения изменений в Git.</div>Чтобы добавить файлы в индекс, мы должны указать какие именно файлы мы хотим добавить. Давайте добавим `index.html`:

```
git add index.html

```

Теперь можем прописать команду `git status`:

```
...
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   index.html
...

```

Как мы можем видеть, файл index.html добавился в индекс.

Основные команды:

1. `git add index.html index.css` — добавить сразу несколько файлов;
2. `git add . (-A)` — добавить все файлы

---

#### 5. Отмена изменений в репозитории

```
git reset

```

Команда используется для отмены изменений в репозитории. Она может изменять как индекс (staging area), так и рабочий каталог. `git reset` имеет несколько режимов, которые определяют степень отката изменений: `--soft`, `--mixed` и `--hard`.

1. `--soft` — оставляет изменения в рабочем каталоге и в индексе. Перемещает указатель текущей ветки к указанному коммиту.
2. `--mixed` (по умолчанию) — Оставляет изменения в рабочем каталоге, но удаляет их из индекса.
3. `--hard` — удаляет изменения из рабочего каталога и индекса, возвращая состояние файлов к указанному коммиту.
    
    Будьте аккуратны, когда используете флаг `--hard` !!!
4. `--soft HEAD~1` — откатить коммит, оставить изменения в индексе.
5. `git reset --keep HEAD~1`: откатить, сохранив локальные изменения.

Если Вы хотите удалить какой либо файл (допустим `index.js`) из индекса пропишите:

```
git reset index.js

```

После чего он снова станет неотслеживаемым.

Если хотите удалить все файлы из индекса, просто пропишите `git reset`.

---

#### 6. Сохранение изменений в локальном репозитории Git

```
git commit

```

<div class="code-explainer" id="bkmrk-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D1%82%D1%81%D1%8F-4">Команда используется для сохранения изменений в локальном репозитории Git. Когда вы выполняете `git commit`, Git сохраняет текущие изменения, добавленные в индекс (staging area), в виде коммита с уникальным идентификатором (SHA-1 хэшем), который содержит информацию о всех изменениях, авторе, времени и сообщении коммита.</div>Создадим `commit`:

```
git commit -m "Initial commit"

```

Предположим, что мы забыли добавить index.css. Для начала создадим его, затем добавим его в индекс, используя команды:

```
echo "* { margin: 0; }" > index.css
git add index.css
git commit --amend --no-edit

```

Основные команды:

1. `git commit --amend --no-edit` — изменить коммит без изменения его сообщения.
2. `git commit -a -m "Обновил все изменённые файлы"` — добавление всех изменённых файлов (не добавляет новые файлы) и создание коммита.
3. `git commit --author="Ivan <ivan@example.com>" -m "Добавил новые функции"` — создание коммита с указанием автора.
4. `git commit --allow-empty -m "Пустой коммит"` — создание пустого коммита (без изменений).

---

#### 7. Просмотр истории коммитов

```
git log

```

Команда используется для просмотра истории коммитов в репозитории Git. Эта команда предоставляет информацию о каждом коммите, включая SHA-1 хэш коммита, автора, дату и сообщение коммита. С помощью различных опций можно фильтровать и форматировать вывод для более удобного анализа истории проекта.

Если мы введем данную команду, то увидим следующее:

```
git log

commit c136c5185822bf95b6636851cf6e67a8f732cfeb (HEAD -> master, origin/master)
Author: Ivan <ivan@gmail.com>
Date:   Mon Jul 22 16:30:24 2024 +0700

    Initial commit

```

`c136c5185822bf95b6636851cf6e67a8f732cfeb` является хэшом.

Основные команды:

1. `git log --oneline` — компактный вывод
2. `git log -p` — просмотр коммитов с определенными изменениями
3. `git log -n` — количество выводимых коммитов
4. `git log --graph` — вывод изменений в виде дерева
5. `git log --stat` — вывод статистики изменений
6. `git log --author="Ivan"` — фильтрация коммитов по автору
7. `git log --since="2024-22-07"` (с) и `--until="2024-22-08"` (до) — фильтрация коммитов по дате
8. `git log index.html"` — показывает коммиты, затрагивающие конкретный файл
9. `git log --name-only"` — показывает только имена изменённых файлов

---

#### 8. Отправка коммитов в удаленный репозиторий

```
git push

```

Команда используется для отправки коммитов из локального репозитория в удаленный репозиторий. Эта команда обновляет удаленные рефы вместе с объектами, необходимыми для полного копирования истории изменений.

Если мы введем команду:

```
git push

```

То получим:

```
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

```

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

Вы должны будете скопировать строку с

`https://github.com/<Ваш аккаунт>/<Ваш репозиторий>.git` и добавить удаленный репозиторий:

```
git remote add origin https://github.com/<Ваш аккаунт>/<Ваш репозиторий>.git

```

> Вместо `origin` можете дать свое название, но по умолчанию обычно используется `origin`.

Если мы снова попробуем ввести команду `git push`, то получим:

```
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

```

Сообщение, которое вы получили, означает, что ваша текущая ветка `master` не связана с удаленной веткой в вашем удаленном репозитории (origin). Upstream ветка — это удаленная ветка, с которой ваша локальная ветка синхронизируется при выполнении команд `git push` и `git pull`.

Если вы хотите, чтобы Git автоматически устанавливал upstream ветку при первом пуше новой локальной ветки, вы можете настроить параметр push.autoSetupRemote. Для этого выполните команду:

```
git config --global push.autoSetupRemote true

```

Теперь перейдя по ссылке `https://github.com/<Ваш аккаунт>/<Ваш репозиторий>` Вы увидите следующее:

<figure id="bkmrk--9">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/image.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/image.png)

</figure>##### Поздравляю с Вашим первым push-ем!!!🎉🎉🎉

Основные команды:

1. `git push -force`(`-f`) — принудительно перезаписывает историю на удалённом репозитории. **Осторожно!** Может сломать работу других разработчиков.
2. `git push --force-with-lease` — то же, что `--force`, но проверяет, не изменилась ли удалённая ветка за время твоей работы. Более безопасно
3. `git push --set-upstream <удаленный репозиторий> <удаленная ветка>`(`-u`): устанавливает связь между локальной и удалённой веткой. Полезно при первом пушинге новой ветки.

---

### Вторые шаги

---

#### 9. Управление ветками

```
git branch

```

Команда используется для управления ветками в репозитории Git. С её помощью можно создавать, удалять и перечислять ветки. Ветки в Git позволяют вам изолировать работу на различных функциях, исправлениях или версиях проекта.

Так как мы имеем только одну ветку, то при выполнении данной команды увидим:

```
* master

```

Создадим новую ветку `develop`:

```
git branch develop

```

Основные команды:

1. `git branch --delete`(`-d`) — удаляет указанную ветку (только если она объединена с другой)
2. `git branch -D` — принудительно удаляет ветку, даже если она не была объединена
3. `git branch --move`(`-m`) — переименовывает ветку
4. `git branch --all`(`-a`) — показывает все ветки: локальные и удалённые
5. `git branch --remotes`(`-r`) — показывает только удалённые ветки
6. `git branch <name> <commit>` — создаёт ветку на указанном коммите или теге

---

#### 10. Переключение между ветками

```
git switch

```

Команда `git switch` используется для переключения между ветками.

Переключимся на ветку, которую мы только что создали:

```
git switch develop

```

Мы также могли создать ветку при помощи `git switch` и сразу переключиться на нее при помощи флага `-c`:

```
git switch -c develop

```

Добавим файл `index.js`:

```
echo "console.log('Hello')" > index.js

```

Добавим файлы в индекс, сделаем `commit` и `push` данной ветки:

```
git add .
git commit -m "First commit on develop"
git push

```

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

Основные команды:

1. `git switch --create <имя>`(`-c`) — создаёт новую ветку и переключается на неё
2. `git switch --track`(`-t`) — устанавливает связь с отслеживаемой удалённой веткой

---

#### 11. Создание копии удаленного репозитория

```
git clone

```

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

Клонируем наш репозиторий в каталог `addon`, который мы создали на этапе [предустановки](https://habr.com/ru/articles/918386/#section30) в 4 пункте. Советую открыть новое окно VS Code и уже в нем клонировать репозиторий.

```
git clone `https://github.com/<Ваш аккаунт>/<Ваш репозиторий>.git` .

```

Если мы выполним команду `git branch -a`, то увидим:

```
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master

```

Нам нужно клонировать ветку:

```
git switch --track origin/develop
    или
git checkout -b develop origin/develop
    или можно было сразу
git clone -b develop https://github.com/<Ваш аккаунт>/<Ваш репозиторий>.git` .

```

<div class="code-explainer" id="bkmrk--14"></div>---

#### 12. Временное хранилище

```
git stash

```

Команда используется для временного сохранения (stash) изменений в рабочем каталоге, которые еще не готовы для коммита. Это полезно, когда нужно переключиться на другую ветку или работу, но текущие изменения не должны быть потеряны. С помощью `git stash` изменения сохраняются в специальное место, откуда их можно восстановить позже.

> ***Отступление***
> 
> Представим ситуацию:
> 
> Вы офисный работник, выполняете 3-ий день подряд Task-у с Azure (TFS) `#111 Добавление печати пропуска` вместе со своими коллегами и сидите на локальной ветке `feature/111_add_print`, которой соответствует удаленная `origin/feature/111_add_print`. Вы уже перелопатили половину кода, что-то в текущий момент перестало работать.
> 
> Как вдруг вбегает начальник и говорит: "Мы теряем ***бабки***!!! Бросай свои дела и быстро исправляй ошибки! Кто умудрился в `console.log()` выводить пароль?".
> 
> У Вас код перестал работать, а он со своими проблемами. Не пошлешь же начальника, хотя скорее всего очень хочется. Что ж, придется исправлять. Для этого нужно создать новую ветку `hotfix/change_clg`, переключиться на нее и убрать эту лишнюю строку.
> 
> Давайте попробуем это сделать.

1. Для начала создадим удаленную ветку `origin/feature/111_add_print`. Для этого переключимся на новую ветку `feature/111_add_print`, добавим немного кода в `index.js` и в `index.css`, сделаем коммит и запушим:
    
    ```
    git switch -c feature/111_add_print
    
    echo "function Print(){}" >> index.js
    echo "p { text-align: center; }" >> index.css
    
    git add .
    git commit -m "Add print function"
    git push
    
    ```
2. "Перелопатим" код (добавим изменения в файл `index.js`):
    
    ```
    echo "const y = true;" >> index.js
    echo "console.log(y)" >> index.js
    
    ```
3. Так как нам нужно исправлять код рабочий — наследоваться от ветки `develop`, а не от `feature/111_add_print`, то нам для начала необходимо переключиться на develop и от него создать ветку `hotfix/change_clg`:
    
    ```
    git switch develop
    
    error: Your local changes to the following files would be overwritten by checkout:
            index.js
    Please commit your changes or stash them before you switch branches.
    Aborting
    
    ```
    
    Но увидим ошибку, которая говорит о том, что мы сделали локальные изменения и их нужно либо запушить, либо отправить в `stash`, прежде чем мы сможем переключиться.
4. Для этого используем команду:
    
    ```
    git stash
    
    ```
    
    Если мы пропишем `git status`, то увидим, что наши изменения пропали. На деле они находятся в `stash`.
    
    Теперь мы сможем переключиться на `develop`.

Основные команды:

1. `git stash` — отправка изменений в стэш;
2. `git stash push -m "Временные изменения"` — Отправка изменений в стэш с указанием сообщения;
3. `git stash list` — список сохранённых стэшей;
4. `git stash apply` — применение последнего стэш;
5. `git stash pop` — применение и удаление последнего стэша;
6. `git stash apply stash@{n}` — применение конкретного стэша;
7. `git stash drop stash@{n}` — если 0, то удаление всех стэшей, другое число — удаление определенного стэша;
8. `git stash clear` — очистка всех стэшей.

---

#### 13. Создание псевдонимов

```
git config alias

```

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

Если Вы заметили, то мы часто используем команду `git commit -m ""`. Мы можем упростить ее написание создав для нее алиас:

```
git config --global alias.ctm 'commit -m'

```

Теперь вместо `commit -m` мы будем использовать `ctm`.

Создадим еще парочку алиасов:

```
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --decorate --all"

```

Получить список созданных алиасов можно командой:

```
git config --get-regexp alias

```

Удалить ненужный алиас (допустим `ctm`):

```
git config --global --unset alias.ctm

```

<div class="code-explainer" id="bkmrk--17"></div>---

#### 14. Старший брат команды git switch

```
git checkout

```

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

Переключимся на новую ветку, унаследовавшись от последнего коммита в `develop`:

```
git log develop --oneline -1
126dadc (HEAD -> develop, origin/develop) First commit on branch develop

```

Во 2-ой строке получили хэш. Теперь создаем ветку на основе этого хэша:

```
git checkout -b hotfix/change_clg 126dadc

```

Изменим файл `index.js` на:

```
console.log("Вы успешно вошли")

```

Сделаем commit и push при помощи созданного алиаса:

```
git add .
git ctm "Убрал `pass` в console.log()"
git push

```

Основные команды:

1. `git checkout <branch-name>` — создание новой ветки
2. `git checkout -b <branch-name>` — создание новой ветки и переключение на нее
3. `git checkout <commit-hash>` — переключение на конкретный коммит
4. `git checkout <branch-name> <commit-hash>` — создание новой ветки от определенного коммита
5. `git checkout -- <file-path>` — восстановление файла до состояния последнего коммита
6. `git checkout -- .` — восстановление всех файлов до состояния последнего коммита

---

#### 15. Слияние изменений веток

```
git merge

```

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

Вольем наши изменения из ветки `hotfix/change_clg` в `develop`:

```
git switch develop
git merge --no-ff hotfix/change_clg -m "Слияние изменений из hotfix/change_clg в develop"
git push

```

Очень важно писать `--no-ff`, чтобы сохранить структуру разработки.

Наглядный пример работы:

<figure id="bkmrk--20">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/u4timage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/u4timage.png)

</figure>Теперь на ветке `develop` в удаленном и локальном репозитории файлы будут обновлены.

Основные команды:

1. `git merge <from-branch> --no-ff` — создаёт новый коммит слияния, даже если возможно быстрое слияние (fast-forward). Полезно для сохранения истории слияния.
2. `git merge <from-branch> --no-commit` — объединяет изменения, но не делает коммит автоматически.
3. `git merge <from-branch> --squash` — объединяет все коммиты из сливаемой ветки в один коммит в текущей ветке. Полезно для объединения истории коммитов перед слиянием.
4. `git merge --continue` — продолжает слияние после разрешения конфликтов
5. `git merge --abort` — прерывает начатое слияние при возникновении конфликтов

---

#### 16. Загрузка обновлений из удаленного репозитория

```
git fetch

```

Команда используется для загрузки обновлений из удаленного репозитория в ваш локальный репозиторий. В отличие от `git pull`, `git fetch` не сливает изменения автоматически в вашу текущую ветку. Вместо этого она загружает все обновления, которые затем можно просмотреть и слить вручную.

Переключимся обратно на каталог `root`.

Загрузим обновления из удаленного репозитория командой `git fetch`.

В консоли видим:

```
...
  652b6ff..b585d2a  develop               -> origin/develop
* [new branch]      feature/111_add_print -> origin/feature/111_add_print
* [new branch]      hotfix/change_clg     -> origin/hotfix/change_clg

```

Здесь видим краткую информацию, что `develop` обновился и появились две новые ветки

Пишем `git log -1 --oneline` и видим, что коммит не соответствует тому, что должно быть в удаленном репозитории.

Пишем `git log origin/develop -1 --oneline` и видим последний коммит.

Если запускать с флагом `--prune`, то он уберет локальные ссылки на удалённые ветки, которых уже нет на сервере.

---

#### 17. Извлечение и слияние изменений

```
git pull

```

Команда используется для извлечения и слияния изменений из удалённого репозитория в вашу текущую ветку. Эта команда объединяет две операции: `git fetch` и `git merge`. Сначала она извлекает изменения из удалённого репозитория (аналогично `git fetch`), а затем автоматически сливает их с текущей веткой (аналогично `git merge`).

Выполним команду `git pull` и наша локальная ветка `develop` будет соответствовать удаленной ветке `origin/develop`.

Переключимся на ветку `feature/111_add_print` и вытянем изменения, которые мы сделали в `develop`:

```
git switch -t origin/feature/111_add_print
git merge develop 

```

Как мы можем увидеть, у нас конфликты:

```
warning: Cannot merge binary files: index.js (HEAD vs. develop)
Auto-merging index.js
CONFLICT (content): Merge conflict in index.js
Automatic merge failed; fix conflicts and then commit the result.

```

Сам же файл:

```
<<<<<<< HEAD
console.log("Вы успешно вошли")
=======
console.log(pass)
function Print(){}
>>>>>>> 2c0279a (Add print function)

```

Вы можете отредактировать файл вручную, удалив строки `<<<<<<< HEAD`, `=======`, `>>>>>>> 742b087 (Add print function)` и внести нужные изменения, сохраняя только те строки, которые вы хотите оставить.

Или Вам предложат открыть `Merge editor` (возможно автоматически откроется), чтобы решить данный конфликт. В нем `current` будет ветка `develop`, `incoming` — `feature/111_add_print`, а `result` — результат слияния. Можно выбрать оба изменения, либо одно, нажав на соответствующие галочки, либо написать что-то свое и нажать на `Complete Merge`. Я добавлю оба изменения:

```
console.log("Вы успешно вошли")
function Print(){}

```

Если мы пропишем `git status`, то увидим:

```
git status
On branch feature/111_add_print
Your branch is up to date with 'origin/feature/111_add_print'.

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   index.js

```

Как видно мы в состояния `merging` (you are still merging), нужно завершить `merge`, просто пишем:

```
git merge --continue

```

<div class="code-explainer" id="bkmrk--23"></div>---

#### 18. Работа с текстовым редактором vim

У вас откроется редактор, в котором Вы можете поменять сообщение коммита. Строки начинающиеся с `#` считаются комментариями. По умолчанию `merge` создает `commit`: `Merge branch 'develop' into feature/111_add_print`. Чтобы изменить его, нужно перейти в интерактивный режим — нажмите `i`, выйти из режима без сохранения `:q!`. Чтобы сохранить изменения необходимо нажать клавишу `Esc` затем ввести `:wq!` (Посимвольно означает: Перейти в командный режим + Записать + Выйти + Принудительно выполнить).

---

Оставлю название `commit` по умолчанию. Осталось только запушить эти изменения.

```
git push

```

Переключимся на `addon`. Пропишем `git switch feature/111_add_print`, `git pull`. У нас подтянутся изменения — строка с `console.log`.

Наконец-то возвратимся к изменениям, которые сохраняли в стэш. Применим их:

```
git stash pop

```

Опять конфликты, но мы на опыте, решаем их.

Добавим изменения в индекс, закоммитим и запушим:

```
git add .
git ctm "Make print"
git push

```

Вольем наши изменения в ветку `develop` и запушим:

```
git switch develop
git merge --no-ff feature/111_add_print -m "Слияние изменений из feature/111_add_print в develop"
git push

```

<div class="code-explainer" id="bkmrk--26"></div>---

#### 19. Ашалеть, что это за ЗВЕРЬ?

```
git rebase

```

Команда используется для интеграции изменений из одной ветки в другую. Она позволяет перенести или "переписать" серию коммитов из одной ветки в другую, сохраняя линейную историю. Это полезно для упрощения истории проекта и устранения ненужных коммитов слияния.

В Visual Studio Code (VS Code) можно наглядно увидеть графическую визуализацию истории коммитов на ветке `develop`:

<figure id="bkmrk--28">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/1xLimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/1xLimage.png)

</figure>Или при помощи этих команд:

```
git log --oneline
    или
git log --oneline --graph --decorate --all

```

Возьмем последние два коммита:

```
git rebase -i HEAD~2

```

Выйдет такая страница:

```
pick abac516 Add print function
pick 5201b7f Убрал pass в console.log()
pick 8699ff2 Make print

# Rebase 1e6c9c2..aeba1fd onto 1e6c9c2 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
...

```

Основные команды:

1. `p, pick <commit>` — оставить коммит как есть
2. `r, reword <commit>` — оставить изменения, но изменить сообщение коммита
3. `e, edit <commit>` — остановиться на этом коммите для правок (можно добавить/изменить файлы)
4. `s, squash <commit>` — объединить с предыдущим коммитом (сохраняя сообщение текущего)
5. `f, fixup [-C | -c] <commit>` — объединить с предыдущим, но игнорировать его сообщение
6. `d, drop <commit>` — удалить коммит (опасно — приведёт к потере изменений)

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

Как мы можем увидеть у нас не попали `merge` (слияния веток). Merge `commit`-ы — это специальные коммиты, которые Git обрабатывает особо при `rebase`.

Попробуем переименовать один из коммитов. О том как пользоваться `vim` найдете в [Работа с текстовым редактором `<strong><em>vim</em></strong>`](#bkmrk-18.-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2):

```
pick abac516 Add print function
r 5201b7f Убрал pass в console.log()
pick 8699ff2 Make print
...

```

У нас появится опять конфликт, решаем, пишем `git rebase --continue`, и далее меняем сообщение в редакторе у `commit` на:

```
Убрал pass в console.log(). UPD: git rebase

```

Делаем отправку:

```
git push --force-with-lease

```

`--force-with-lease` безопаснее, чем `--force`: он проверит, не поменялась ли удалённая ветка за время твоей работы.

<figure id="bkmrk--29">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/lIuimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/lIuimage.png)

</figure>Как мы видим многие коммиты потерлись. Это происходит потому, что цель `rebase` — сделать историю линейной, а не сохранять информацию о слияниях.

`git rebase` лучше всего использовать, когда ты работаешь один над своей веткой, не публичной и тебе нужно изменить коммит, его сообщение, объединить несколько в один. Но как показывает практика, чтобы применять эту команду — нужно больше работы с ней.

Конечно, можно вернуться к предыдущему состоянию, но оно уже будет немного видоизменено:

```
git reset --hard origin/develop
git merge feature/111_add_print
git push

```

<figure id="bkmrk--30">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/F5zimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/F5zimage.png)

</figure>---

#### 20. Просмотр различий между файлами

```
git diff

```

Команда используется для отображения различий между состояниями файлов в вашем репозитории Git. Она позволяет сравнивать изменения, которые произошли в файлах между различными состояниями, такими как рабочий каталог, индекс (staging area) и коммиты.

Давайте добавим различия, что увидеть работу данной команды. Добавим в файл `index.html` строку:

```
echo "<span>What is diff!</span>" >> index.html

```

И в файл `index.css`:

```
echo "span { color: red; }" >> index.css

```

При выполнении команды `git diff` получим:

```
diff --git a/index.css b/index.css
index 6dd919a..9e7b7bf 100644
Binary files a/index.css and b/index.css differ
diff --git a/index.html b/index.html
index db400e4..8ea75d9 100644
Binary files a/index.html and b/index.html differ

```

Если у Вас что-то подобное значит у Вас файл сохранен в неверном формате.

Если напишем команду `git diff --text`, то увидим строки, которые нельзя прочитать. Все дело в кодировке и русские символы будут видны как кракозябры. Исправить это можно, сохранив файл с определенной кодировкой.

> В VS CODE меняется так: нажмите `Ctrl+Shift+P`, введите `Change File Encoding`, затем выберите `Save with Encoding` и наконец-то `UTF-8`.

После изменения вызов `git diff` покажет читаемую информацию:

```
diff --git a/index.css b/index.css
index b36d0b9..99d90d6 100644
--- a/index.css
+++ b/index.css
@@ -1,2 +1,3 @@
 * { margin: 0; }
 p { text-align: center; }
+span { color: red; }
diff --git a/index.html b/index.html
index 410a29a..acd0531 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
 <p>Hello Git!</p>
+<span>What is diff!</span>

```

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

```
git status -v

```

При сравнении с веткой `master` вдобавок получим `index.js`:

```
git diff master

...
+<p>I made my first push!</p>
\ No newline at end of file
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..43d2c75
--- /dev/null
+++ b/index.js
@@ -0,0 +1 @@
+console.log(pass)

```

Основные команды:

1. `git diff index.html` — вывести изменения только для определенного файла.
2. `git diff --staged` — просмотр изменений, добавленных в индекс
3. `git diff <commit1> <commit2>` — сравнение изменений между двумя коммитами по их хэшам
4. `git diff <branch1> <branch2>` — сравнение изменений между ветками
5. `git diff --name-only` — вывести только имена файлов, в которых произошли изменения.
6. `git diff -- *.css` — сравнивает все файлы с расширением `.css` .

---

### Менее юзаемые команды

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

---

#### 21. Просмотр различий и редактирование файлов

```
git difftool

```

Команда позволяет использовать внешние дифф-утилиты для просмотра различий между файлами, а также менять код внутри файла.  
Команда `git difftool` является дополнением команды `git diff`, но главное отличие — она умеет также и редактировать файлы.

Теперь используем команду.

```
This message is displayed because 'diff.tool' is not configured.
See 'git difftool --tool-help' or 'git help config' for more details.
'git difftool' will now attempt to use one of the following tools:
kompare emerge vimdiff nvimdiff

Viewing (1/2): 'index.css'
Launch 'vimdiff' [Y/n]?

```

Вводим `Y` и `Enter`, попадаем в редактор ***vim*** для редактирования файла.

<figure id="bkmrk--34">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/OzXimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/OzXimage.png)

</figure>Как работать в данном редакторе описано ранее в [Работа с текстовым редактором `<strong><em>vim</em></strong>`](https://habr.com/ru/articles/918386/#section18):

При помощи данной команды мы также можем сравнивать ветки, коммиты и отдельные файлы.

Основные команды:

`git difftool --tool-help`: Показывает список доступных инструментов. Так как я работаю в VS Code, то в списке доступных покажется `vscode`. Вы можете установить его как дефолтный инструмент командой:

```
git config --global diff.tool vscode

```

И тогда будет открываться не в консоли, а во вкладке VS Code. Закрытие вкладки — выход из difftool.

---

#### 22. Работа с удалёнными репозиториями

```
git remote

```

Команда `git remote` используется для управления удалёнными репозиториями в Git.

Основные команды:

1. `git remote -v` — выводит список имён удалённых репозиториев c URL-ом.
2. `git remote add <name> <url>` — добавление удалённого репозитория
3. `git remote remove <name>` — удаление удалённого репозитория
4. `git remote rename <old-name> <new-name>` — переименование удалённого репозитория
5. `git remote set-url <name> <new-url>` — изменение URL удалённого репозитория

---

#### 23. Теги

```
git tag

```

Команда `git tag` используется для создания, просмотра и управления тегами в Git. Теги — это метки, которые обычно используются для обозначения стабильных версий проекта (например, `v1.0.0`, `v2.1.3` и т.д.).

Выведем все коммиты:

<figure id="bkmrk--37">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/0hzimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/0hzimage.png)

</figure>Добавим для коммита `fb07e9c Убрал pass в console.log(). UPD: git rebase` тег:

```
git tag -a v1.0.0 fb07e9c -m "Рабочая версия v1.0.0"

```

Команда `git tag -n` выводит информацию:

```
v1.0.0          Рабочая версия v1.0.0

```

Команда `git show v1.0.0` выводит информацию:

```
tag v1.0.0
Tagger: Ivan <ivan@gmail.com>
Date:   Fri Jun 13 20:20:22 2025 +0300

Рабочая версия v1.0.0

commit fb07e9cdd9c778bb52bb4b3b08f9fc37f512dba4 (tag: v1.0.0)
Author: Ivan <ivan@gmail.com>
Date:   Thu Jun 12 23:37:23 2025 +0300

    Убрал pass в console.log(). UPD: git rebase

diff --git a/index.js b/index.js
index 2db8952..913f3b6 100644
Binary files a/index.js and b/index.js differ

```

Отправим в репозиторий тег:

```
git push origin v1.0.0

```

Теперь перейдя в удаленный репозиторий, мы увидим наш тег:

<figure id="bkmrk--38">[![image.png](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/scaled-1680-/zDhimage.png)](https://wiki.kuksa.dev/uploads/images/gallery/2026-02/zDhimage.png)

</figure>Основные команды:

1. `git tag` — выводит список всех тегов
2. `git tag -a <tagname> -m "message"` — создаёт аннотированный тег с сообщением
3. `git tag <tagname> <commit>` — создаёт тег на определённом коммите
4. `git show <tagname>` — показывает информацию о теге: автор, дата, сообщение, изменения
5. `git tag -n` — показывает список тегов с кратким сообщением (если есть)
6. `git push origin <tagname>` — отправляет указанный тег на удалённый репозиторий
7. `git tag -d <tagname>` — удаляет тег из локального репозитория
8. `git push origin --delete <tagname>` — удаляет тег из удалённого репозитория

---

#### 24. Восстановления файлов из индекса или коммитов

```
git restore

```

Команда `git restore` предназначена для восстановления файлов из индекса или коммитов, заменяя собой некоторые функции `git checkout` и `git reset`. Она делает работу с откатом изменений более понятной и явной.

Основные команды:

1. `git restore <file>` — отменяет локальные изменения. Никак не влияет, если файл в индексе
2. `git restore --staged <file>` — убирает файл из индекса (не трогает рабочую директорию)
3. `git restore --staged .` — убирает все файлы из индекса (не трогает рабочую директорию)
4. `git restore -- .` — похоже на команду `git checkout -- .`. Восстанавливает все файлы в текущем каталоге и подкаталогах

---

#### 25. Применение коммитов из одной ветки на другую

```
git cherry-pick

```

Команда `git cherry-pick` позволяет применить один или несколько конкретных коммитов из одной ветки на другую. Это удобно, если ты хочешь перенести только определённые изменения, а не всю ветку целиком.

Переключимся на ветку `master` для наглядной демонстрации, получим коммиты `develop` и выполним:

```
git log develop --oneline --reverse     
60c5923 (HEAD -> master, origin/master, origin/HEAD) Initial commit
efd81d6 First commit on develop
abac516 Add print function
5201b7f (origin/hotfix/change_clg, hotfix/change_clg) Убрал pass в console.log()
f709a7b Слияние изменений из hotfix/change_clg в develop
040f399 Merge branch 'develop' into feature/111_add_print
8699ff2 (origin/feature/111_add_print, feature/111_add_print) Make print
fb07e9c (tag: v1.0.0) Убрал pass в console.log(). UPD: git rebase
a4433a3 Make print
e5d24be (origin/develop, develop) Merge branch 'feature/111_add_print' into develop

```

Возьмем допустим коммит `8699ff2`:

```
git cherry-pick --edit 8699ff2

```

Откроется редактор, пропишем `Cherry-pick from feature/111_add_print` и запушим `git push`. Как видим, наша ветка стянула состояние ветки `feature/111_add_print`, имеющееся на данном коммите.

Если необходимо откатить коммит и убрать его из истории, то просто делаем следующие шаги:

```
git log --oneline
3dd9bb9 (HEAD -> master, origin/master, origin/HEAD) Cherry-pick from develop
60c5923 Initial commit

git reset --hard 60c5923
HEAD is now at 60c5923 Initial commit

git push -f

```

Основные команды:

1. `git cherry-pick <commit>` — применяет указанный коммит на текущей ветке
2. `git cherry-pick <commit1>..<commit2>` — применяет все коммиты между `commit1` и `commit2` (включая `commit2`, исключая `commit1`)
3. `git cherry-pick <commit1>^..<commit2>` — применяет все коммиты от `commit1` до `commit2` включительно
4. `git cherry-pick --edit (-e)` — позволяет редактировать сообщение коммита перед применением
5. `git cherry-pick --no-commit (--n)` — применяет изменения в индекс, но не создаёт коммит
6. `git cherry-pick --continue` — продолжает процесс после разрешения конфликтов
7. `git cherry-pick --abort` — отменяет cherry-pick и возвращает всё к исходному состоянию
8. `git cherry-pick --quit` — выходит из процесса cherry-pick без изменений

---

#### 26. Откат изменений

```
git revert

```

Команда `git revert` используется для отката изменений, создавая новый коммит, который "отменяет" изменения, внесённые ранее указанным коммитом. Это безопасный способ отката, потому что он не переписывает историю (в отличие от `git reset`).

Добавим какие-нибудь данные `echo "<span>git revert</p>" > index.html` и запушим. Мы можем откатить последний коммит через HEAD или через его хэш:

```
git log --oneline
f5ecd54 (HEAD -> master, origin/master, origin/HEAD) Git revert test
60c5923 Initial commit

git revert HEAD
    или
git revert f5ecd54

```

В редакторе можем поменять сообщение коммита у `revert` и можем пушить. Сам же файл `index.html` откатился к предыдущей версии.

Основные команды:

1. `git revert <commit>` — откатывает указанный коммит, создавая новый коммит с обратными изменениями
2. `git revert --edit (-e)` — позволяет редактировать сообщение коммита перед сохранением
3. `git revert --no-edit` — применяет revert без изменения сообщения
4. `git revert --no-commit (-n)` — применяет изменения в рабочую область, но не создаёт коммит
5. `git revert --continue` — продолжает процесс после разрешения конфликтов
6. `git revert --abort` — прерывает процесс revert и возвращает всё к исходному состоянию
7. `git revert --quit` — выходит из режима revert без изменений
8. `git revert --mainline <n>` — используется при откате merge-коммита; указывает, какую родительскую ветку считать основной (например, 1 или 2)

---

### Основные команды

1. Клонирование репозитория — `git clone https://github.com/<Ваш аккаунт>/<Ваш репозиторий>.git .`
2. Cписок имён удалённых репозиториев c URL-ом — `git remote -v`
3. Добавление файлов в индекс — `git add .`
4. Удаление файлов из индекса — `git reset`
5. Создание коммита — `git commit -m "Сообщение коммита"`
6. Добавить забытые файлы в предыдущий коммит без изменения сообщения:
    
    ```
    git add .
    git commit --amend --no-edit
    
    ```
7. Отправить изменения в удаленный репозиторий — `git push`
8. Создание ветки и переключение на нее — `git switch -c <новая_ветка>`
9. Просмотр локальных и удалённых веток — `git branch -a`
10. Принудительное удаление ветки — `git branch -D <ветка>`
11. Переименовать ветку — `git branch --move (-m) <старая_ветка> <новая_ветка>`
12. Состояние рабочего каталога и индекса — `git status`
13. Просмотр истории коммитов в удобном виде — `git log --graph --oneline`
14. Восстановление всех файлов, не вошедших в индекс, до состояния последнего коммита — `git checkout -- .`
15. Убирает все файлы из индекса — `git restore --staged .`. `.` - все файлы, можно заменить на название определенного файла.
16. Слияние изменений веток — `git merge --no-ff <ветка, которую хотим слить в текущую> -m "<Сообщение>"`
17. Извлечение и слияние изменений — `git pull`
18. Удаление файла из индекса (staging area) и из remote репозитория при следующем push, но сохранение в рабочей директории — `git rm --cached <имя-файла>`. `-r` флаг действует для папок.
19. Если необходимо откатить коммит и убрать его из истории, то просто делаем следующие шаги:
    
    ```
    git log --oneline
    3dd9bb9 (HEAD -> master, origin/master, origin/HEAD) Cherry-pick from develop
    60c5923 Initial commit
    
    git reset --hard 60c5923
    HEAD is now at 60c5923 Initial commit
    
    git push -f
    
    ```
    
    <div class="code-explainer">  
    </div>

---

### Вывод

Вот и всё! Мы разобрали основные команды Git, которые помогут тебе эффективно управлять проектами и работать с кодом. Надеюсь, эта статья помогла тебе разобраться в базовых принципах работы с Git.