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


Настраиваем али��сы

Git не пытается «догадаться», какую команду вы имели в виду, если вы ввели её не полностью. Поэтому, если вам не хочется каждый раз набирать длинные команды целиком, вы можете настроить для них короткие имена — псевдонимы. Делается это с помощью команды git config.

Схема команды:

git config --global alias.NAME "команда"


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

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

После такой настройки вместо команды:

git commit

Достаточно будет набрать:

git ci

Часто проще редактировать файл конфига руками. Открывать конфиг можно в своей IDE. Используйте следующую команду, чтобы установить VS Code в качестве редактора Git по умолчанию:

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

После этой команды все манипуляции редактора вроде коммит-сообщений, rebase, merge, tag будут запускаться в VS Code.

Если вы используете другой редактор, просто загуглите
git set text editor to <ваш_редактор> , обычно нужная команда находится быстро.

Чтобы вернуть как было:

git config --global --unset core.editor

После этого открываем глобальный конфиг Git командой:

git config --global --edit

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

Например, такие:

#внутри .gitconfig
[alias]
    # status / info
    st    = status -s
    sta   = status
    stats = status

    # config
    conf = config --global --edit
    cge  = config --global --edit

    # commit / checkout
    ci  = commit
    co  = checkout
    cod = checkout .

    # amend
    edit   = commit --amend
    forgot = commit --amend --no-edit
    amend  = commit -a --amend --no-edit
    ciam   = commit -a --amend --no-edit

    # fetch / merge
    fop  = fetch origin --prune
    mofo = merge origin/master --ff-only

    # log / diff / show
    hist = log --oneline -10
    dw   = diff -w
    dws  = diff -w --staged
    swh  = show -w HEAD

    # branch / pull
    br  = branch
    bra = branch -a
    pr  = pull --rebase

    # reset / add / clean
    rh  = reset HEAD
    aa  = add -A
    cdf = clean -df
    
    #unstage
    unstage = reset HEAD --

    # опечатки
    rbanch = branch

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

Хороший пример — операция исключения файла из индекса (staging area). Чтобы упростить эту задачу, можно добавить собственный псевдоним unstage:

git config --global alias.unstage 'reset HEAD --'

После этого следующие две команды становятся эквивалентными:

git unstage myfile
#эквивалентно
git reset HEAD -- myfile

Вариант с unstage обычно воспринимается проще и понятнее, особенно для начинающих.

Git Worktree

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

Git worktree упрощает работу с несколькими ветками. Чтобы перейти на другую, используют команды git checkout или git switch. В большинстве случаев этого достаточно, но возникает проблема, если в рабочей директории есть незакоммиченные изменения.

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

Это нормальная практика, но не оптимальная. Если веток много, то постоянные git stash и git checkout утомляют.

Команда git worktree add <path> <branch> создаёт новую рабочую директорию, связанную с тем же репозиторием. Это не то же самое, что git clone.

Типичные сценарии:
— срочный hotfix, не прерывая текущую работу;
— проверка старой ветки в чистой директории;
— отдельная папка под ревью или эксперимент;

Допустим, мы работаем из ветки dev и мне нужно пофиксить что-то ветке alembic-test. Пишем:

git worktree add ../alembic-test

Таким образом мы создали «копию» репозитория со всеми теми же настройками. Это копия знает, где синхронизироваться. Также произошёл автоматический checkout на ветку с названием alembic-test.

alembic-test указывает туда же, куда и ветка dev

# Переходим в новый worktree
cd ../alembic-test

git status
# On branch alembic-test

# Вносим нужные изменения
vim migration.sql

# Коммитим изменения в ветке alembic-test
git add -A
git commit -m "Fix alembic migration"

# Пушим фикс
git push origin alembic-test

# Возвращаемся к основной работе в dev
cd ../project 

git status
# On branch dev
# Ничего не потеряно, никаких stash / checkout не было

# Если worktree больше не нужен, удаляем его
git worktree remove ../alembic-test

# Или, находясь в директории alembic-test
git worktree remove .

Важно: Git не даст удалить worktree с незакоммиченными изменениями без предупреждения. Это защита от случайной потери данных.

Советую прочитать суперкачественный гайд по использованию git worktree

Уверяю, вы больше не сможете представить жизнь без рабочих деревьев :)

git commit --amend: исправляем ошибочный коммит

Ситуация знакомая: вы сделали коммит, а сразу после этого заметили опечатку в сообщении, забытый файл или мелкое исправление в коде. Создавать новый коммит ради такой мелочи не всегда хочется (и не надо). Для таких случаев и существует git commit --amend

Команда позволяет изменить последний коммит, будто его никогда и не было. Вы можете:

  • поправить сообщение коммита;

  • добавить забытые файлы;

  • слегка изменить код и включить изменения в тот же самый коммит.

Типичный сценарий выглядит так. Вы поняли, что забыли добавить файл:

# Редачите  index.html и styles.css
git add index.html 
git commit  
# Вспоминаете, что забыли добавить в коммит styles.css  
git add styles.css  git commit --amend

Git откроет редактор с предыдущим сообщением коммита. Его можно оставить без изменений или отредактировать. Если сообщение менять не нужно, удобнее использовать флаг --no-edit:

git commit --amend --no-edit

Если нужно поменять ТОЛЬКО сообщение, юзаем -m:

git commit --amend --m "новое сообщение"

Важно помнить простое правило: не используйте --amend для коммитов, которые уже отправлены в общий репозиторий. Эта команда переписывает историю, и если кто-то уже синхронизировался, вы создадите проблемы себе и коллегам.

git cherry-pick: аккуратный перенос

Иногда нужно перенести одно конкретное изменение, не всю ветку целиком. Например, срочный багфикс уже сделан в dev, а его нужно быстро утащить в main, не затрагивая остальные коммиты. Для этого идеально подходит git cherry-pick.

Команда берёт один коммит (или несколько) и применяет его поверх текущей ветки. Базовый сценарий выглядит так:

# Переходим в ветку, куда нужно перенести исправление
git checkout dev

# Применяем изменения из выбранного коммита
git cherry-pick imhash5v

# Если возникли конфликты, исправляем их вручную
# затем добавляем изменённые файлы
git add .

# Завершаем cherry-pick (будет создан новый коммит)
git cherry-pick --continue

# Отправляем изменения в репозиторий
git push origin develop

После этого Git создаст новый коммит в текущей ветке с теми же изменениями. История при этом остаётся аккуратной: вы явно видите, какой именно фикс был перенесён.

cherry-pick особенно полезен, когда:

  • нужно срочно забрать багфикс без лишнего кода;

  • несколько веток развиваются параллельно;

  • вы не хотите делать merge или rebase ради одного изменения.

Как и в случае с rebasecherry-pick может привести к конфликтам, если изменения затрагивают одни и те же строки. Но сами конфликты решаются стандартно: правка файлов, git add, продолжение операции.

Интересный факт: Команда git revert — полная противоположность git cherry-pick. Она создаёт новый коммит, который вносит изменения, противоположные указанному коммиту, по сути отменяя его.

git reflog: возвращаем потерянное

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

Что делает git reflog:

  • показывает историю локальных действий;

  • позволяет найти SHA-коммит до опасной операции;

  • даёт метки вида HEAD@{3}, которыми удобно оперировать.

Разберём сценарий восстановления:

Ты случайно долбанул, например:

git reset --hard HEAD~3

И тем самым похоронил последние 3 коммита.

# Смотрим журнал перемещений HEAD
git reflog

# a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~3
# bbd1234 HEAD@{1}: commit: bug fix
# e4f5g6h HEAD@{2}: commit: анимация кнопки
# i7j8k9l HEAD@{3}: commit: API test
# q4r5s6t HEAD@{4}: pull origin main

# Видим нужную запись, например: bbd1234 HEAD@{1}: commit: bug fix
# Можно сразу переключиться на тот коммит
git checkout bbd1234

# Для безопасности создаём ветку
git branch recover/forgotten bbd1234

# Или сразу вернуть main в нужное состояние (если вы уверены)
git reset --hard bbd1234

Здесь HEAD@{1}HEAD@{2} и HEAD@{3} — как раз те «потерянные» коммиты.

git reflog работает только локально. Если в�� уже запушили изменение и другие клонировали репозиторий, возврат может нарушить корректную работу.

git rebase и git rebase -i

Команда rebase даёт возможность перенести всю последовательность коммитов из одной ветки и применить их к концу другой ветки.

Схема коммитов
Схема коммитов

Допустим, необходимо интегрировать изменения из ветки server в основную ветку master. Это можно сделать, выполнив перебазирование непосредственно из текущей ветки, не переключаясь на целевую. Для этого используется форма команды с указанием двух аргументов:

git rebase <basebranch> <topicbranch>

Она извлечёт тематическую ветку (в данном случае server) и применит изменения в ней к базовой ветке (master):

# применить ветку server поверх master, не переключаясь
git rebase master server

Это повторит работу, сделанную в ветке server поверх ветки master, как показано на рисунке:

Коммиты C3 C4 C10 теперь в master
Коммиты C3 C4 C10 теперь в master

По сути произошло перемещение всей цепочки коммитов server на ветку master.

Редактирование истории коммитов с помощью git rebase -i

Если нужно поправить не последний коммит, а более ранний в истории, стандартных простых команд Git уже недостаточно. Для таких случаев используется git rebase -i.

Git не умеет напрямую переписывать историю, но rebase позволяет заново последовательно применить группу коммитов поверх того же места (HEAD), где они и находились. В интерактивном режиме вы можете останавливать процесс на нужных коммитах, менять их сообщения, добавлять файлы или вносить другие правки.

Чтобы изменить сообщения последних трёх коммитов, выполните:

git rebase -i HEAD~3

Важно понимать: вы указываете не сами три коммита, а коммит перед ними. В результате все коммиты из диапазона HEAD~3..HEAD будут воспроизведены заново, даже если вы не будете их редактировать. Никогда не включайте в такой диапазон коммиты, которые уже отправлены в общий репозиторий — это почти гарантированно создаст проблемы другим разработчикам.

После запуска команды Git откроет редактор со списком коммитов, например:

pick f7f3f6d Change my name a bit
pick 310154e Update README formatting and add blame
pick a5f4a0d Add cat-file


# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

Обратите внимание, что порядок коммитов здесь инвертирован по сравнению с выводом git log. Самый старый коммит находится вверху списка, потому что процесс перебазирования начинается именно с него.

Для сравнения, обычный вывод log выглядит так:

$ git log --pretty=format:"%h %s" HEAD~3..HEAD
a5f4a0d Add cat-file
310154e Update README formatting and add blame
f7f3f6d Change my name a bit

Интерактивный rebase по сути формирует сценарий, который Git выполняет сверху вниз. Вы можете менять команды, переставлять строки или удалять их, но делать это нужно осторожно: удалённая строка означает потерю коммита.

Мы можем соединить несколько коммитов в один. Для этого замените слово pick на squash напротив коммитов. Соединим три коммита в один:

pick f7f3f6d Change my name a bit
s 310154e Update README formatting and add blame
s a5f4a0d Add cat-file

Когда вы сохраните скрипт и выйдете из редактора, Git применит изменения всех трёх коммитов и затем вернёт вас обратно в редактор, чтобы вы могли объединить сообщения коммитов:

# This is a combination of 3 commits.

# The first commit's message is:

Change my name a bit

# This is the 2nd commit message:

Update README formatting and add blame

# This is the 3rd commit message:

Add cat-file

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

Это далеко не все возможности rebase -i.Изучить команду с ног до головы можно здесь.

git log --graph и утилита tig

Визуальное представление всегда упрощает понимание. Команда git log --graph даёт компактную текстовую диаграмму ветвления прямо в терминале.

Полезный алиас для логов:

#[alias]
#компактный и удобный лог
lg = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' --all

Вывод логов алиасом lg:

Компактный однострочный лог
Компактный однострочный лог


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

# установка (для Debian/Ubuntu) 
sudo apt install tig
# установка (пример для MacOS) 
brew install tig  

# запуск 
tig  

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

Вид tig
Вид tig

Кнопка h откроет окно помощи.

За перемещение внутри коммита отвечают кнопки j и k

Перемещение внутри коммита
Перемещение внутри коммита

Весь инструментарий tig можно изучить по ссылке.


Пробуйте свои новоиспечённые алиасы и создайте свой первый worktree.С этого момента вы уже не новичок в Git. Овладев этими инструментами и внедрив их в свой привычный воркфлоу, можете смело называть себя продвинутыми Git-юзером и хвастаться перед коллегами :)

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

© 2025 ООО «МТ ФИНАНС»

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какая фичи для вас наиболее полезные?
18.85%Алиасы49
38.46%git worktree100
42.31%git commit --amend110
39.23%git cherry-pick102
16.92%git reflog44
31.54%git rebase и git rebase -i82
5.77%tig15
19.23%Мне init, commit, push достаточно50
Проголосовали 260 пользователей. Воздержался 31 пользователь.