Irbisa · Шпаргалка
Git и командная работа
Merge и rebase, конфликты, reset и revert, cherry-pick, stash, reflog и bisect, стратегии ветвления, pull request и код-ревью, соглашения о коммитах, секреты в истории, файлы Gradle и keystore
Что такое коммит, ветка и
HEADв Git и что означает «detached HEAD»?В чём разница между
git fetchиgit pullи что меняетgit pull --rebase?git fetch origingit log --oneline main..origin/main # what others pushedgit log --oneline origin/main..main # what only you have git pull --rebase # fetch, then replay your commits on topgit config --global pull.rebase true # the default from now onВ чём разница между merge и rebase и почему нельзя делать rebase ветки, в которой работают другие?
# feature/cart was cut from main, and main has moved sincegit switch feature/cartgit rebase main # your commits replayed on top: new hashesgit push --force-with-lease # only because the branch is yours alone git switch main…Как пошагово разрешить конфликт слияния и чего нельзя делать никогда?
git merge main# CONFLICT (content): Merge conflict in app/src/main/kotlin/Cart.ktgit status --short # UU app/src/main/kotlin/Cart.ktgit log --merge --oneline -- app/src/main/kotlin/Cart.kt # who changed it on each side # edit it: keep both intentions, delete <<<<<<< ||||||| ======= >>>>>>>…Что делают
git stashиgit cherry-pickи какие ловушки есть у каждой из них?Как работает
.gitignoreи почему Git продолжает отслеживать файл, который вы туда добавили?# local.properties is in .gitignore, yet:git ls-files local.properties # prints the path: the file is trackedgit status --short # M local.properties git rm --cached local.propertiesgit commit -m "chore: stop tracking local.properties"…Ваша ветка и
mainобе менялиgradle/libs.versions.toml, и конфликт сидит в[versions]. Как его разрешить и что запустить перед коммитом?# gradle/libs.versions.toml after `git merge main` on feature/offline[versions]<<<<<<< HEADagp = "8.11.1"kotlin = "2.1.21"room = "2.7.2"…Каждая команда ниже выполняется отдельно, начиная с одной и той же запушенной истории. Что покажут
git logиgit statusпосле каждой и какая безопасна для запушенной ветки?# main, already pushed:# c3 Add retry <- HEAD# b2 Add client# a1 Init# c3 changed app/src/main/kotlin/ApiClient.kt; the working tree is clean. git reset --soft HEAD~1 # Agit reset HEAD~1 # B (--mixed is the default)git reset --hard HEAD~1 # Cgit revert HEAD # DКак привести в порядок коммиты ветки интерактивным rebase перед мержем и почему пушить с
--force-with-lease, а не с--force?git fetch origingit rebase -i --autosquash origin/main # the todo list Git opens, after your edits# (--autosquash already moved the fixup! commit under its target):pick 3f9c2e1 # feat: cart badge…После
git reset --hardили неудачного rebase коммиты будто пропали. Как их вернуть и когда это невозможно?$ git reset --hard HEAD~2 # oops: two commits "gone"$ git refloga872130 HEAD@{0}: reset: moving to HEAD~2d6eb664 HEAD@{1}: commit: Debounce search7a7b367 HEAD@{2}: commit: Add search fielda872130 HEAD@{3}: checkout: moving from main to feature/search…Как
git bisectнаходит коммит, который что-то сломал, и как автоматизировать поиск черезgit bisect run?git bisect startgit bisect bad # HEAD: the cart total is wronggit bisect good v3.8.0 # the last release where it was right # CartTotalRegressionTest.kt is new and untracked, under feature/cart/src/test/git bisect run sh -c '…Каким должно быть хорошее сообщение коммита и как Conventional Commits превращают историю в номера версий и changelog?
feat(cart): show a discount badge on eligible items The badge reads the rule from /v2/discounts instead of theclient-side list, so marketing can change rules without a release. Closes #418…Каким должен быть хороший pull request и как вы ревьюите чужой?
Ваша фича-ветка живёт три недели и теперь конфликтует с половиной
main. Как её влить и как избежать такого в следующий раз?Что должно быть в pre-commit хуке и почему CI всё равно должен запускать те же проверки?
# lefthook.yml: committed; `lefthook install` wires .git/hooks after a clonepre-commit: commands: ktlint: glob: "*.{kt,kts}" run: ktlint --format {staged_files}…Вы закоммитили секрет и запушили его. Что делать и почему недостаточно удалить его новым коммитом?
# 0) Revoke the secret at the provider and ship the new one. Only then:git clone git@github.com:acme/shop.git shop-clean && cd shop-clean # drop the file from every commitgit filter-repo --sensitive-data-removal --invert-paths --path app/play-service-account.json# or replace the value wherever it appears ("old==>new" per line):…PR #42 сломал оформление заказа, поэтому его merge откатили в
main. Автор исправил ветку и влил её снова, но скидок вmainпо-прежнему нет. Почему?git switch maingit merge --no-ff feature/discounts # PR #42: two feature commitsgit revert -m 1 HEAD # checkout broke: undo the mergegit push git switch feature/discounts# add a guard in app/src/main/kotlin/Cart.kt, away from the lines the feature changedgit commit -am "fix: skip checkout for an empty cart"git switch maingit merge feature/discounts # merges cleanlyКогда стоит держать несколько приложений и общие библиотеки в одном монорепозитории, а не в отдельных репозиториях, и чего стоит каждый вариант?