Skip to content

Git: Comprehensive Guide

Terminal window
git config --global user.name "CJ Steiner"
git config --global user.email "csrhinoserver@gmail.com"
git config --global core.editor vi
git config --global core.pager "less -FRXS"
git config --global color.ui true
git config --global svc.rmdir true
git config --global merge.tool vimdiff
git config --global merge.summary true
git config --global push.default simple
git config --global format.pretty fuller
git config --global pull.rebase true
Terminal window
alias ..='cd ../'
alias ...='cd ../../'
alias ....='cd ../../../'
Terminal window
alias gd='git diff'
alias gds='git diff --staged'
alias gs='git status'
alias ga='git add'
alias gr='git restore'
alias grs='git restore --staged'
alias gc='git commit'
alias gcm='git commit -m'
alias gca='git commit --amend --no-edit --date=now'
alias gb='git branch'
alias gbdates="git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents-subject) - %(authorname) (%(color:green)%(committerdate:short)%(color:reset))'"
alias gbresethard='git reset --hard @{u}'

A merge conflict occurs when Git cannot automatically resolve differences between two commits. This happens when:

  • Both branches modify the same lines in a file
  • One branch deletes a file that another branch modifies
  • Two branches add different files with the same name
Terminal window
# Branch A modifies line 10-15
# Branch B modifies line 10-15
# Result: Conflict when merging
git merge feature-branch
# Conflict in README.md
Terminal window
# Branch A: deletes config.json
# Branch B: modifies config.json
# Result: Delete/modify conflict

When a conflict occurs, Git marks the conflicting sections:

<<<<<<< HEAD
This is the version from the current branch (HEAD)
=======
This is the version from the branch being merged
>>>>>>> feature-branch

Sections marked:

  • <<<<<<< HEAD — Current branch version
  • ======= — Separator
  • >>>>>>> branch-name — Incoming branch version
Terminal window
git status
# Shows "Unmerged paths" with conflicted files

Open conflicted files and manually decide which changes to keep. Remove conflict markers and edit the code.

Terminal window
# Example: resolving in config.json
<<<<<<< HEAD
{
"environment": "production"
}
=======
{
"environment": "staging"
}
>>>>>>> update-config
# Resolved version:
{
"environment": "production-staging"
}
Terminal window
git add <resolved-file>
Terminal window
git commit -m "Resolve merge conflict in config.json"
# Or if already staged:
git merge --continue
Terminal window
# Use vimdiff
git config --global merge.tool vimdiff
# Use VSCode
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# Use meld (visual tool)
git config --global merge.tool meld
Terminal window
git mergetool

The tool opens each conflicted file for visual resolution. After resolving:

Terminal window
git add .
git commit
Terminal window
git merge feature-branch

Works best for most scenarios. Takes multiple common ancestors into account.

Always prefer current branch changes:

Terminal window
git merge -s ours feature-branch

Use with caution — discards changes from the merged branch.

Take changes from the branch being merged (requires creating a temporary commit):

Terminal window
git merge -X theirs feature-branch

Simpler algorithm, useful for 2-way merges:

Terminal window
git merge -s resolve feature-branch
Terminal window
git merge -X ours feature-branch
Terminal window
git merge -X theirs feature-branch

Abort the merge entirely:

Terminal window
git merge --abort
Terminal window
# Reset to before merge
git reset --hard HEAD~1

For merged commits already pushed to shared branches:

Terminal window
git revert -m 1 <merge-commit-hash>

The -m 1 flag specifies merging with mainline.

Conflicts can also occur during rebasing. The process is similar:

Terminal window
git rebase main
# Conflicts occur
# ... resolve conflicts ...
git add <resolved-files>
git rebase --continue
# Or abort:
git rebase --abort

Create a portable repository snapshot:

Terminal window
git bundle create repo.bundle --all
git clone repo.bundle /tmp/repo/
Terminal window
git fetch upstream
# if no upstream git remote add upstream <url>
git merge upstream/master
git push origin master

Alternative using rebase:

Terminal window
git fetch upstream
git rebase upstream/master
git push origin master
Terminal window
git gc
git remote prune origin
git fetch --prune # clean up refs

Smaller, focused commits reduce conflict surface area.

Terminal window
# Good: Specific commit
git commit -m "Fix authentication bug in login handler"
# Avoid: Large commit touching many areas
git commit -m "Various fixes and updates"
Terminal window
git fetch origin
git rebase origin/master
# or
git merge origin/master
  • Discuss major changes before starting work
  • Review related PRs before starting similar work
  • Notify team when working on shared files

Keep feature branches short-lived (days, not weeks).

Terminal window
# Create focused feature branch
git checkout -b fix/auth-bug
# ... make changes ...
# Merge quickly to avoid divergence
git push origin fix/auth-bug
# Create PR and merge
  • Separate concerns into different files
  • Avoid modifying shared utility files unnecessarily
  • Use configuration files for shared settings
CommandPurpose
git statusShow working tree status
git diffView differences
git diff --stagedView staged changes
git add <file>Stage changes
git commit -m "msg"Create commit
git pushPush to remote
git pullFetch and merge
git fetchDownload remote changes
git merge <branch>Merge branch
git rebase <branch>Rebase current branch
git branchList branches
git checkout -b <branch>Create and switch branch
git logView commit history
git reset --hard HEAD~1Undo last commit
git checkout --ours <file>Take current branch version in conflict
git checkout --theirs <file>Take incoming branch version in conflict
git mergetoolOpen visual merge tool
git merge --abortCancel merge in progress
git revert -m 1 <hash>Revert merge commit
git bundle createCreate repository bundle
git gcGarbage collection
git remote prune originClean up stale remote refs