Git Cheatsheet

Базовое

git init
git clone git@github.com:user/repo.git
git status
git add file        # один файл
git add -p          # ★ интерактивно (по hunks)
git commit -m "feat: add X"
git push origin main
git pull --rebase   # подтянуть с rebase

git log --oneline --graph --all      # красиво
git log --stat                       # с измененными файлами
git log -p path/file                 # история файла с diff
git show <sha>

Ветки

git branch                  # список локальных
git branch -a               # включая remote
git switch -c feat/auth     # новая ветка + checkout
git switch main             # переключиться
git switch -                # на предыдущую
git branch -d feat/auth     # удалить (merged)
git branch -D feat/auth     # удалить принудительно
git branch -m new-name      # переименовать текущую

Merge / Rebase

git merge feat/auth
git merge --no-ff feat/auth     # принудительно с merge-commit

git rebase main                 # ребейзить на main
git rebase --continue           # после resolve конфликта
git rebase --abort              # отменить

git rebase -i HEAD~3            # ★ interactive
# в редакторе: pick / reword / edit / squash / drop

Remote

git remote -v
git remote add upstream URL
git fetch origin
git fetch --all --prune

git push origin feat/x
git push -u origin feat/x       # с tracking
git push --force-with-lease     # ★ безопасный force
git push origin --delete feat/x # удалить remote ветку

Stash

git stash                       # отложить
git stash -u                    # включая untracked
git stash list
git stash show -p stash@{0}
git stash pop                   # вернуть последний
git stash apply stash@{2}       # конкретный, не удаляя из stash
git stash drop stash@{0}

Diff

git diff                        # unstaged изменения
git diff --staged               # что в staging
git diff main..feat/x           # между ветками
git diff HEAD~3                 # с коммитом 3 назад
git diff --stat                 # только статистика
git diff -- path/file           # для файла

Откат изменений

git restore file                # отменить unstaged изменения
git restore --staged file       # убрать из staging (но не отменить)
git checkout -- file            # старый способ (= git restore)

git reset --soft HEAD~1         # отменить commit, оставить staged
git reset HEAD~1                # отменить commit и unstage
git reset --hard HEAD~1         # ★ отменить commit И изменения (опасно!)

git revert <sha>                # создать обратный commit (safe)
git revert HEAD                 # отменить последний

git clean -fd                   # удалить untracked файлы и dirs
git clean -fdx                  # включая .gitignore (опасно)

Reflog — спасатель

git reflog                      # история HEAD движений (90 дней)
git checkout -b recovery <sha>  # восстановить удалённое
git reset --hard HEAD@{2}       # вернуться на 2 движения назад

Cherry-pick

git cherry-pick <sha>
git cherry-pick <sha1> <sha2>
git cherry-pick --abort

Bisect — поиск бага

git bisect start
git bisect bad                  # текущий сломан
git bisect good v1.2.0          # этот тег работал
# Git предложит коммит, проверяешь, говоришь:
git bisect good                 # или bad
# ...
git bisect reset                # после нахождения

Tags

git tag v1.0.0                  # lightweight
git tag -a v1.0.0 -m "Release"  # annotated (рекомендуется)
git tag -s v1.0.0 -m "..."      # signed
git push origin v1.0.0
git push origin --tags          # все tags
git tag -d v1.0.0               # локально
git push origin --delete v1.0.0 # на remote

Подпись

# SSH-подпись (с 2022)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git commit -m "signed"

# Проверка
git log --show-signature

Submodule / Worktree

git submodule add git@github.com:user/lib.git path/to/lib
git submodule update --init --recursive
git submodule update --remote   # обновить до последнего remote

# Worktree — несколько веток в разных папках
git worktree add ../feat-x feat/x
git worktree list
git worktree remove ../feat-x

Conventional Commits

feat(auth): add OAuth login
fix(api): handle expired tokens
docs(readme): update setup
refactor(db): extract repository
chore(deps): bump axios
ci: add semgrep
perf(query): use index
test: add integration tests
build: update Dockerfile

# BREAKING change
feat(api)!: change response format
# или в footer:
feat(api): new response
BREAKING CHANGE: wraps data in 'result'

Полезные алиасы

git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.st "status -sb"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.cm "commit -m"
git config --global alias.unstage "restore --staged"
git config --global alias.last "log -1 HEAD --stat"

Если случайно закоммитил секрет

  1. Немедленно отзови секрет (revoke, rotate)
  2. Удали из истории:
    # BFG Repo-Cleaner
    java -jar bfg.jar --delete-files secrets.env
    git reflog expire --expire=now --all
    git gc --prune=now --aggressive
    
    # или git filter-repo
    git filter-repo --path secrets.env --invert-paths
  3. Force push (предупреди команду)