Irbisa · Cheatsheet

Git & Team Workflow

Merge vs rebase, conflicts, reset and revert, cherry-pick, stash, reflog and bisect, branching strategies, pull requests and code review, commit conventions, secrets in history, .pbxproj and Package.resolved conflicts

Junior Developer · 18 questions

  1. 01

    What are a commit, a branch and HEAD in Git, and what does "detached HEAD" mean?

    A commit is a snapshot of the whole project plus its parent commits, author and message, named by a hash of all of that.

  2. 02

    What is the difference between git fetch and git pull, and what does git pull --rebase change?

    git fetch downloads new commits and moves remote-tracking branches such as origin/main, but never touches your branch or your files.

    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
  3. 03

    What is the difference between merge and rebase, and why should you never rebase a branch other people work on?

    Merge joins two histories with a merge commit and leaves every existing commit as it was.

    # 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…
  4. 04

    How do you resolve a merge conflict step by step, and what must you never do?

    Open each conflicted file, work out what both sides meant, write the version that keeps both intentions and delete the markers.

    git merge main# CONFLICT (content): Merge conflict in Sources/Cart/Cart.swiftgit status --short                  # UU Sources/Cart/Cart.swiftgit log --merge --oneline -- Sources/Cart/Cart.swift   # who changed it on each side # edit it: keep both intentions, delete <<<<<<< ||||||| ======= >>>>>>>…
  5. 05

    What do git stash and git cherry-pick do, and what are the traps of each?

    git stash shelves your uncommitted changes and leaves a clean working tree; git stash pop brings them back.

  6. 06

    How does .gitignore work, and why does Git keep tracking a file after you add it there?

    .gitignore only stops untracked files from being added; a file Git already tracks stays tracked whatever the patterns say.

    echo "xcuserdata/" >> .gitignoregit status --short             # the .xcuserstate file still shows as modified git rm -r --cached '*xcuserdata*'   # every xcuserdata folder in the repogit add .gitignoregit commit -m "chore: stop tracking xcuserdata"…
  7. 07

    Your branch and main both conflict in project.pbxproj and Package.resolved. How do you resolve each, and how do you stop the .pbxproj conflicts coming back?

    In project.pbxproj keep both sides' entries, since each added file appears in several sections, then check that it parses and builds.

    git merge main# CONFLICT (content): Merge conflict in App.xcodeproj/project.pbxproj# CONFLICT (content): Merge conflict in .../swiftpm/Package.resolved # project.pbxproj: keep both sides' entries in every section, thenplutil -lint App.xcodeproj/project.pbxproj    # "OK", or fails on a leftover marker…
  8. 08

    Each command below runs on its own from the same pushed history. What do git log and git status show after each, and which is safe on a pushed branch?

    # main, already pushed:#   c3 Add retry     <- HEAD#   b2 Add client#   a1 Init# c3 changed Sources/Networking/APIClient.swift; 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

    A, B and C all move main back to b2 and differ only in where the change from c3 ends up: staged, unstaged or gone.

  9. 09

    How do you clean up your branch with an interactive rebase before merging, and why push with --force-with-lease instead of --force?

    git rebase -i origin/main lists your branch's commits; changing pick to squash, fixup, reword or drop, or reordering lines, rewrites them into a history worth reading.

    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…
  10. 10

    After a git reset --hard or a rebase gone wrong, your commits seem lost. How do you get them back, and when can you not?

    A reset or a rebase does not delete commits, it only stops pointing at them.

    $ 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…
  11. 11

    How does git bisect find the commit that broke something, and how do you automate it with git bisect run?

    You mark one commit bad and an older one good, and Git binary-searches the commits between them: it checks out the middle one, you test it and answer good or bad, and the range halves until one commit is left.

    git bisect startgit bisect bad                 # HEAD: the cart total is wronggit bisect good v4.2.0         # the last release where it was right # CartTotalRegressionTests.swift is new and untracked, in the Checkout# package's Tests/CheckoutTests folder, so SwiftPM compiles it at every step…
  12. 12

    What makes a good commit message, and how do Conventional Commits turn the history into version numbers and a changelog?

    A good message states in a short imperative subject what the commit does and explains in the body why.

    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…
  13. 13

    What makes a good pull request, and how do you review someone else's?

    A good pull request does one thing, is small enough to read in one sitting, and says why it exists and how it was tested.

  14. 14

    What is the difference between GitFlow, GitHub flow and trunk-based development, and which would you choose?

    GitFlow keeps long-lived develop and main branches plus release and hotfix branches, built for scheduled, versioned releases.

  15. 15

    What belongs in a pre-commit hook, and why must CI run the same checks anyway?

    A pre-commit hook should run fast, self-fixing checks on the staged files only, such as the formatter and a quick lint.

    # lefthook.yml: committed; `lefthook install` wires .git/hooks after a clonepre-commit:  commands:    format:      glob: "*.swift"      run: swiftformat {staged_files}…
  16. 16

    You committed a secret and pushed it. What do you do, and why is deleting it in a new commit not enough?

    Rotate the secret first: revoke it and issue a new one, because it is already in the history and in every clone and fork, and a new commit only hides it from the latest version.

    # 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 fastlane/AuthKey_ABC123XYZ9.p8# or replace the value wherever it appears ("old==>new" per line):…
  17. 17

    PR #42 broke checkout, so its merge was reverted on main. The author fixed the branch and merged it again, yet main still has no discounts. Why?

    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 Sources/Cart/Cart.swift, away from the lines the feature changedgit commit -am "fix: skip checkout for an empty cart"git switch maingit merge feature/discounts           # merges cleanly

    A revert undoes the changes but not the history: main still contains PR #42's two commits, so the second merge brings in only what is new on the branch, the one fix.

  18. 18

    When would you keep several apps and shared libraries in one monorepo instead of separate repositories, and what does each choice cost?

    Choose a monorepo when the code changes together: apps sharing a design system, an API client and models, where one pull request should update a library and every caller at once.