Skip to main content
GIT

GIT Mastery

Git is the backbone of modern development. Knowing the right commands is useful - knowing how and when to use them (and how to recover when things go wrong) makes you a dependable engineer.

1. Quick reference — essential git commands and how to use them

Setup & identity
git config --global user.name "Your Name"
git config --global user.email you@example.com
git config --global core.editor "code --wait"   # or vim/nano
CommandPurposeWhy Used
git config --global user.nameSets your Git usernameUsed in commit history so others know who authored commits
git config --global user.emailSets your Git emailLinks commits to your GitHub/GitLab identity
git config --global core.editor "code --wait"Sets VS Code as Git’s default editorEnsures Git waits for you to finish editing commit messages and rebase instructions
Local repo lifecycle
git init                 # start repo
git clone <url>          # clone remote repo
Staging & committing
git status               # what changed / what's staged
git add <file>           # stage file
git add -p               # interactively stage hunks
git commit -m "Short, imperative message"
git commit --amend       # edit last commit (before push)
Branching & switching
git branch               # list branches
git branch <name>        # create branch
git checkout <name>      # switch branch (older syntax)
git switch <name>        # recommended: switch branches
git switch -c <name>     # create + switch
Update from remote
git fetch origin         # fetch remote refs (no merge)
git pull                 # fetch + merge (or rebase if configured)
git pull --rebase        # fetch + rebase local commits on top
Pushing
git push origin main
git push origin feature/xyz  # first push of branch
Inspecting history
git log --oneline --graph --decorate --all
git show <commit>
git blame <file>        # who changed each line
git diff                # unstaged diff
git diff --staged       # diff of staged files
Undoing & cleaning
git restore <file>              # discard unstaged changes (modern)
git restore --staged <file>     # unstage
git checkout -- <file>          # older way to discard changes
git reset --soft HEAD~1         # move HEAD back but keep changes staged
git reset --mixed HEAD~1        # default; keep changes unstaged
git reset --hard <commit>       # WARNING: destroys working tree to that commit
Stash
git stash               # stash local changes
git stash push -m "WIP: reason"
git stash list
git stash apply         # apply most recent stash (keeps stash)
git stash pop           # apply + drop stash
git stash branch new-branch  # create branch from stash and apply
Rebase / merge / cherry-pick
git merge <branch>             # merge branch into current
git rebase <branch>            # move current commits on top of branch
git cherry-pick <commit>       # apply a single commit on current branch
Tags
git tag v1.0.0
git push origin v1.0.0

2. Good practices & workflow recommendations

  • Small, focused commits & PRs. Keep changes digestible (200–400 LOC ideal).

  • Commit message style: short (50 chars) summary + optional body. Use imperative tense: “Fix bug”, not “Fixed bug”.

  • Always fetch before you start work: git fetch then git rebase origin/main or git merge origin/main. This reduces conflicts.

  • Use CI to run tests before merging.

  • Use git pull --rebase if your team prefers linear history and you aren’t sharing local commits.

  • Review diffs, not files: git add -p + git diff --staged help create focused commits.

  • Automate formatting & linting (pre-commit hooks) to avoid style nitpicks in review.

  • Never git push --force to shared branches unless everyone agrees. Use --force-with-lease when rewriting history and you understand the consequences.

3. Understanding conflicts — what happens and why

Conflicts occur when Git cannot automatically reconcile changes to the same lines or the file structure. Common scenarios:

  • Two branches edit the same lines in a file.

  • One branch deletes a file while another edits it.

  • Rebase changes order of commits that touch same areas.

  • Cherry-picking a commit that overlaps changes already applied.

Git marks conflicts in files and pauses the operation (merge/rebase/cherry-pick) until you resolve them.

4. Merge conflict — step-by-step resolution

Scenario: You merge feature into main and encounter conflicts.
  1. Start the merge:

    git checkout main
    git fetch origin
    git merge origin/feature
    # OR: git merge feature
  2. Git detects conflicts and stops. Check status:

    git status
    # Output shows files with "both modified"	
  3. Git detects conflicts and stops. Check status:

    <<<<<<< HEAD
    current branch content
    =======
    incoming branch content
    >>>>>>> feature
  4. Resolve manually:

    1. Decide what should remain: current version, incoming, or a combination.

    2. Edit the file to remove markers and produce the desired final content.

  5. Mark resolved and commit:

    git add path/to/conflicted-file
    git commit    # completes merge commit (git created a commit message by default)
  6. If you want to abort merge:

    git merge --abort
Tips
  • Use git diff to inspect conflict context.

  • git mergetool launches a GUI diff/merge tool (if configured).

  • git checkout --ours <file> / git checkout --theirs <file> can quickly accept one side entirely (older syntax; modern alternative noted below).

  • Modern commands:

    • git restore --source=HEAD --worktree <file> (ours)

    • git restore --source=feature --worktree <file> (theirs)

5. Rebase conflict — how it differs and how to resolve

Rebase rewrites commits and replays them on top of another branch. If a commit being replayed conflicts, Git stops at that commit.

  1. Start rebase:

    git checkout feature
    git fetch origin
    git rebase origin/main
  2. If conflict occurs, Git pauses and shows:

    CONFLICT (content): Merge conflict in file.txt
  3. Resolve conflicts just like merge:

    # edit files, then:
    git add file.txt
    git rebase --continue
  4. If stuck and want to abort rebase:

    git rebase --abort
  5. If you want to skip the commit that is causing the conflict:

    git rebase --skip
Key differences
  • Merge leaves a merge commit; rebase creates a linear history by rewriting commits.

  • Rebase changes commit hashes. Avoid rebasing public branches (shared with others) unless coordinated.

6. Using mergetools and quick acceptance strategies

git mergetool

Configure your preferred mergetool (vimdiff, meld, kdiff3, Beyond Compare, etc.)

git config --global merge.tool meld
git mergetool

Mergetool opens visual interface showing base / ours / theirs — edit and save the merged result then git add and continue.

Accept whole side quickly
  • Accept current branch (ours):

    git checkout --ours file.txt
    git add file.txt
  • Accept incoming branch (theirs):

    git checkout --theirs file.txt
    git add file.txt

7. cherry-pick conflict resolution

When cherry-picking a commit:

git checkout feature
git cherry-pick <commit-hash>
# If conflict:
git status
# resolve files
git add <files>
git cherry-pick --continue
# or abort:
git cherry-pick --abort

If commit was already partially applied, you may need git cherry-pick -x or check for duplicate patches. Use git log/git show to inspect.

8. Stash conflicts & resolving stash application conflicts

When you git stash and later git stash apply a stash that conflicts with current working tree:

git stash list
git stash apply stash@{0}
# If conflicts:
git status
# resolve conflicts like merge/unmerged files
git add <files>
git stash drop stash@{0}   # drop only after you successfully applied

If you want to create a branch from stash (recommended when conflicts are complex):

git stash branch stack-fix-branch stash@{0}
# This creates a new branch, applies the stash and removes it

If git stash pop results in conflicts, stash is dropped by default. Safer: git stash apply then git stash drop after success.

9. Deleted files conflict

Scenario: Branch A deleted a file, Branch B edited it.

During merge/rebase:

  • Git shows deleted by them / modified by us messages.

Resolution options:

  • If deletion is intended: remove file and git add -u then commit.

  • If edits are needed: restore content manually and commit.

Commands:

git rm <file>       # to mark deletion
git add <file>      # if you restored and want to keep

10. Recovering lost work: reflog & reset

If you make a destructive git reset --hard or lose commits, git reflog is lifesaving.

git reflog
# find HEAD@{n} that points to previous commit
git checkout -b recover HEAD@{5}
# OR reset main to it:
git reset --hard HEAD@{5}

11. Team-level policies to reduce conflicts

  • Pull/Fetch frequently and rebase locally before pushing.

  • Use feature toggles to avoid long-lived branches.

  • Code ownership to reduce overlapping edits on the same files.

  • Clear responsibilities: who rebases, who force-pushes, etc.

  • Pre-merge checks: run tests in CI to catch integration issues early.

12. Handy aliases (add to ~/.gitconfig)

[alias]
  s = status -sb
  co = checkout
  br = branch
  ci = commit
  st = stash
  lg = log --oneline --graph --decorate --all
  df = diff
  amend = commit --amend

13. Final checklist for resolving conflicts (quick reference)

  1. git status - see conflicted files.

  2. Open files, look for <<<<<<< markers.

  3. Choose/merge content and remove markers.

  4. git add <file> for each resolved file.

  5. If merging: git commit to finish.

  6. If rebasing/cherry-picking: git rebase --continue / git cherry-pick --continue.

  7. If stuck: git merge --abort or git rebase --abort.

  8. If you need to accept one side entirely: use git checkout --ours / --theirs (or modern git restore --source=).

  9. Push changes (if necessary use --force-with-lease responsibly after rebase).