Git Fundamentals: Branches, Commits, Merge, Rebase, and Conflict Resolution
Master Git from the inside out ā the object model, branching strategy, merging vs rebasing, conflict resolution, stash, reflog, and the workflow every professional engineering team uses daily.
Git Is Not Optional
Git is the foundation of every professional software workflow. Every code change, every bug fix, every data pipeline, every dbt model goes through Git. This isn't just tool knowledge ā it's the language of engineering collaboration.
1. The Git Object Model (Mental Model)
Git stores snapshots, not diffs. Understanding this makes everything else click.
Working Directory āāāŗ Staging Area (Index) āāāŗ Repository (.git/)
(files) (git add) (git commit)Every commit is a snapshot of all tracked files plus:
- A pointer to the parent commit
- Author, date, message
- A unique SHA hash (e.g.,
a3f4c2d)
git log --oneline
# a3f4c2d feat: add orders pipeline
# b9e12f1 fix: correct null handling in customers
# c4d7a90 init: project setup2. Configuration
# One-time global setup
git config --global user.name "Asma Hafeez"
git config --global user.email "asma@example.com"
git config --global core.editor "code --wait" # VS Code
git config --global init.defaultBranch main
git config --global pull.rebase true # prefer rebase over merge on pull
# Check config
git config --list3. Basic Workflow
# Initialize a repo
git init my-project
cd my-project
# Or clone an existing repo
git clone https://github.com/company/data-pipeline.git
cd data-pipeline
# Check state
git status
git diff # unstaged changes
git diff --staged # staged changes
# Stage and commit
git add src/pipeline.py
git add . # add all changes (use carefully)
git add -p # interactive patch ā stage specific hunks
git commit -m "feat: add orders ingestion pipeline"
# Push to remote
git push origin main
git push -u origin feature/orders # -u sets upstream for this branch4. Branching
# List branches
git branch # local
git branch -a # all including remote
# Create and switch
git checkout -b feature/customer-dim # old style
git switch -c feature/customer-dim # modern (Git 2.23+)
# Switch to existing
git checkout main
git switch main
# Delete
git branch -d feature/done # safe delete (fails if unmerged)
git branch -D feature/abandoned # force delete
# Rename
git branch -m old-name new-name
# Push a new branch
git push -u origin feature/customer-dim5. Merge vs Rebase
This is the most important Git concept to understand.
Merge ā preserve history as-is
git switch main
git merge feature/orders-pipelineCreates a merge commit that ties the two branches together:
main: A āā B āā C āāāāāāāā M
\ /
feature: D āā E āāM is the merge commit. History shows the fork clearly.
Use merge for:
- Merging feature branches into main/develop
- Preserving context of parallel work
- PR merges
Rebase ā replay commits on top of another branch
git switch feature/orders-pipeline
git rebase mainTakes your commits and replays them on top of the latest main:
Before: main: A āā B āā C
feature: D āā E
After: main: A āā B āā C
feature: D' āā E' (new commits, same changes)History looks linear ā no merge commit.
Use rebase for:
- Keeping your feature branch up-to-date with main
- Cleaning up commits before PR
- Producing a clean linear history
The rule: rebase before merging
# Standard workflow
git switch feature/my-feature
git fetch origin
git rebase origin/main # bring your branch up-to-date
# resolve any conflicts
git push --force-with-lease origin feature/my-feature # must force-push after rebaseNever rebase shared branches (main, develop). Rebase only your own feature branches.
6. Interactive Rebase ā Rewrite History
Before submitting a PR, clean up messy commits:
git rebase -i HEAD~4 # last 4 commitsThis opens an editor:
pick a3f4c2d add orders pipeline draft
pick b9e12f1 fix typo
pick c4d7a90 fix another typo
pick d1e2f3g add logging to pipeline
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the message
# e, edit = use commit, but stop for amending
# s, squash = meld into previous commit
# f, fixup = like squash, but discard this commit's message
# d, drop = remove commitChange to:
pick a3f4c2d add orders pipeline draft
s b9e12f1 fix typo
s c4d7a90 fix another typo
r d1e2f3g add logging to pipelineThis squashes the three fix commits into the first one, and lets you reword the logging commit.
7. Conflict Resolution
Conflicts happen when two branches change the same lines.
git merge feature/orders-pipeline
# CONFLICT (content): Merge conflict in src/pipeline.pyThe file will contain:
def process_orders():
<<<<<<< HEAD
return fetch_from_api()
=======
return fetch_from_database()
>>>>>>> feature/orders-pipelineResolve it:
def process_orders():
# Resolved: use API as primary, database as fallback
return fetch_from_api() or fetch_from_database()Then:
git add src/pipeline.py
git commit # or git rebase --continueUsing VS Code merge editor
git config --global merge.tool vscode
git mergetool # opens VS Code's 3-way merge view8. Stash ā Temporary Storage
Stash your in-progress work when you need to switch context quickly:
git stash # stash all changes
git stash push -m "WIP: orders fix" # stash with a name
git stash list # view all stashes
# stash@{0}: WIP: orders fix
# stash@{1}: On main: temp experiments
git stash pop # apply latest stash + remove it
git stash apply stash@{1} # apply specific stash (keep it in list)
git stash drop stash@{0} # delete a stash
git stash clear # delete all stashes
# Stash including untracked files
git stash push -u -m "with new files"9. Useful Git Commands
# View history
git log --oneline --graph --all # visual branch graph
git log --author="Asma" --since="1 week ago"
git show a3f4c2d # view a specific commit
# Undo changes
git restore src/pipeline.py # discard unstaged changes to a file
git restore --staged src/pipeline.py # unstage (keep changes)
git reset --soft HEAD~1 # undo last commit, keep changes staged
git reset --mixed HEAD~1 # undo last commit, unstage changes (default)
git reset --hard HEAD~1 # undo last commit, DISCARD changes (destructive!)
# Find commits
git log -S "def process_orders" # find when this string was added/removed
git log --all --full-history -- "src/deleted_file.py" # find deleted file
# Cherry-pick: apply a specific commit to current branch
git cherry-pick a3f4c2d
# Reflog ā your safety net
git reflog # shows all HEAD movements
git reset --hard HEAD@{3} # go back 3 steps in reflog10. .gitignore
# Python
__pycache__/
*.pyc
*.pyo
.venv/
*.egg-info/
dist/
.pytest_cache/
# Environment
.env
.env.local
.env.production
*.local
# dbt
target/
dbt_packages/
logs/
.user.yml
# IDE
.vscode/
.idea/
*.swp
.DS_Store
# Secrets
*.pem
*.key
*.p12
credentials.json
service_account.json11. Commit Message Conventions
Follow Conventional Commits ā the industry standard:
():
[optional body]
[optional footer] Types:
feat: new feature
fix: bug fix
docs: documentation only
style: formatting (no logic change)
refactor: code change, no feature/fix
test: adding tests
chore: tooling, config, deps
perf: performance improvement
ci: CI/CD changesExamples:
feat(orders): add incremental ingestion from API
fix(customers): handle null email in SCD Type 2 merge
docs: update README with local setup instructions
refactor(pipeline): extract validation into separate module
test(orders): add integration tests for CDC loading
ci: add slim dbt CI with state:modifiedSummary
| Command | Purpose |
|---------|---------|
| git switch -c branch | Create + switch to branch |
| git add -p | Stage specific changes interactively |
| git rebase main | Replay your commits on top of main |
| git rebase -i HEAD~N | Squash/reword last N commits |
| git stash | Temporarily shelve changes |
| git restore file | Discard unstaged changes |
| git reset --soft HEAD~1 | Undo commit, keep changes staged |
| git cherry-pick SHA | Apply one commit to current branch |
| git reflog | View all HEAD movements (safety net) |
Next: Git collaboration ā pull requests, code reviews, and team branching strategies.
Enjoyed this article?
Explore the Cloud & DevOps learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.