Tools, Workflow, and Git
Set up a productive environment, manage dependencies, and collaborate effectively with Git and GitHub.
Content
Branches and merging
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Branches and Merging (without the existential crisis)
Ever been mid-semester, opened your repo, and thought, "Who rewired the router of my app and why is the home page now a potato?" Welcome to collaborative coding — and welcome to branches and merging, the Git tools that stop colleagues (and your future self) from turning your main branch into an emotional support group for bugs.
You already know how to start a repo and save progress with git init, git add, and git commit. Now we’ll use branching so different ideas can live in parallel until you’re ready to combine them. If you remember pip and package management from before, branches are the safe sandbox where you can update dependencies (e.g., bump a package in requirements.txt) without breaking everyone else's environment.
What is a branch? Why care?
- Branch = an alternate timeline. It’s a pointer to a commit. Work on a branch isolates changes from the main line of development (commonly
mainormaster). - Why care? Teams can work on features, bug fixes, or experiments without interfering. You can run tests, iterate, or rollback independently.
"Branches let you try weird ideas without setting your main branch on fire." — your slightly dramatic TA
Common branch workflow (feature branches)
Imagine you need to add a login button.
- Create a feature branch:
git checkout -b feature/login-button
(or git switch -c feature/login-button)
- Make changes, stage, and commit:
git add templates/login.html static/styles.css
git commit -m "Add login button and styling"
- Push your branch to remote to share or create a Pull Request:
git push -u origin feature/login-button
- Open a PR on GitHub/GitLab, request review, run CI.
- After approval: merge the branch into
main.
This keeps main stable and makes reviews easy.
Merging: the how and the why
When you integrate a branch back into main, you perform a merge. Two common merge behaviors:
- Fast-forward merge: If
mainhasn't advanced since you branched, Git just moves themainpointer forward — no new commit is created.- Example:
git checkout mainthengit merge feature/login-buttonmay fast-forward.
- Example:
- Merge commit (true merge): If both
mainand your branch have new commits, Git records a merge commit that has two parents. Keeps history explicit.
Commands:
git checkout main
git pull # update local main from remote
git merge feature/login-button
git push
Want to always create a merge commit (even when fast-forward is possible)?
git merge --no-ff feature/login-button
Want a single squashed commit instead of the whole branch history? Useful for small fixes:
git merge --squash feature/login-button
git commit -m "Add login button (squashed)"
Conflicts: welcome to the negotiation table
A conflict occurs if the same lines in the same file were changed on both branches. Git will stop and ask you to reconcile.
Typical flow when conflict happens:
- Run
git statusto see conflicting files. - Open files — you'll see conflict markers:
<<<<<<< HEAD
console.log('Hello from main');
=======
console.log('Hello from feature');
>>>>>>> feature/login-button
- Edit the file to the desired final version, remove markers.
- Stage the resolved file:
git add path/to/file - Complete the merge:
git commit(if Git didn’t auto-create the merge commit).
Helpful commands:
git diffandgit diff --base fileto inspect.git mergetoolto use GUI tools (e.g., Meld, KDiff3).- After resolving locally,
git pushto update remote.
Pro tip: read the conflict, run tests, and ask the author of the other change if unsure.
Rebase: rewrite history, but carefully
git rebase moves your commits onto another base commit. Commonly used to keep a linear history:
# while on your feature branch
git fetch origin
git rebase origin/main
This replays your commits on top of the latest main. It avoids merge commits and makes git log linear and pretty.
But important rules:
- Never rebase public/shared branches (branches others have based work on) because rebase rewrites history and forces others to re-sync.
- It’s great for private feature branches before opening a PR.
If rebase creates conflicts, resolve them just like merge, then git rebase --continue. If you panic: git rebase --abort.
Pulling: merge vs rebase
git pull = git fetch + git merge by default. You can prefer rebase:
git pull --rebase origin main
This keeps your local commits on top of the updated remote branch.
Branching strategies (choose your vibe)
- Feature-branch workflow (recommended for CS50 projects): branch per feature/PR, merge after review.
- GitFlow: formal; includes
develop, release branches — often overkill for small web projects. - Trunk-based development: small short-lived branches or direct commits to main with feature toggles — requires strict CI.
For CS50 and class projects: feature branches + PRs + CI = safe and simple.
Practical tips & best practices
- Keep branches focused and small: one idea per branch.
- Commit frequently with clear messages (you already learned
git commit -m). - Update your branch often with
git pull --rebaseorgit fetch+git mergeto avoid huge conflicts. - When changing dependencies (pip/requirements), do it on its own branch and run tests locally.
- Use descriptive branch names:
feature/login-button,fix/session-timeout,chore/update-deps. - Delete merged branches locally and remotely:
git branch -d feature/...andgit push origin --delete feature/.... - Visualize history:
git log --oneline --graph --all(very satisfying).
Quick cheat sheet
# create & switch
git checkout -b feature/x
# stage & commit
git add .
git commit -m "message"
# push branch
git push -u origin feature/x
# update main locally
git checkout main
git pull
# merge feature into main
git merge feature/x
# delete branch after merge
git branch -d feature/x
git push origin --delete feature/x
Key takeaways
- Branches let you experiment safely. Use them for features, fixes, and dependency updates.
- Merging integrates work; rebasing cleans history. Choose the one that matches your team norms.
- Conflicts are normal. Resolve carefully, test, and communicate.
"A branch is a promise: I'm going to try something here, and if it works, I'll bring it back." Keep those promises tidy, and your future self (and graders) will thank you.
Happy branching. Merge responsibly.
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!