Documentation Index
Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
Use this file to discover all available pages before exploring further.
Git Collaboration
Remote Repositories
A remote is a version of your repository hosted elsewhere (GitHub, GitLab, Bitbucket). Think of it as a shared bulletin board — everyone on the team can post their changes and read everyone else’s. Your local repo is your private workspace; the remote is where work becomes visible to the team.Viewing Remotes
Adding Remotes
Cloning Repositories
Pushing Changes
Pulling Changes
Pull vs Fetch
| Command | What it does |
|---|---|
git fetch | Downloads changes but does not merge — safe, non-destructive |
git pull | Downloads AND merges (fetch + merge) — convenient but can surprise you |
Working with Forks
Forking Workflow
Pull Requests (PRs)
Pull requests are how you propose changes to a repository.Creating a Pull Request
PR Best Practices
Small PRs
Clear Description
Link Issues
Update Branch
PR Template Example
Code Review
As a Reviewer
- ✅ “Consider using a Map here for O(1) lookup”
- ✅ “This could cause a race condition if…”
- ✅ “Great solution! Minor: variable name could be more descriptive”
- ❌ “This is wrong”
- ❌ “Why did you do it this way?”
- ❌ “I would have done it differently”
As an Author
Collaboration Workflows
Centralized Workflow
Feature Branch Workflow
Forking Workflow
Handling Common Scenarios
Syncing Fork with Upstream
Updating PR Branch
Resolving PR Conflicts
SSH vs HTTPS
HTTPS
Cons: Need to enter credentials (or use credential helper)
SSH
Cons: Requires SSH key setup
Setting Up SSH
Tags and Releases
Creating Tags
Semantic Versioning
Semantic versioning (SemVer) communicates the nature of changes to consumers of your software. It is a contract: “I promise this version is safe to upgrade to (or not) based on the version number.”Practical Examples
Example 1: Contributing to Open Source
Example 2: Team Feature Development
Troubleshooting
”Your branch is behind ‘origin/main’"
"Your branch has diverged"
"Permission denied (publickey)"
"Failed to push some refs”
Best Practices
Pull Before Push
Pull Before Push
Small, Focused PRs
Small, Focused PRs
- One feature/fix per PR
- Easier to review
- Faster to merge
Write Good PR Descriptions
Write Good PR Descriptions
- What changed
- Why it changed
- How to test
- Screenshots if UI changes
Review Code Thoughtfully
Review Code Thoughtfully
- Be constructive
- Ask questions
- Suggest improvements
- Approve when ready
Key Takeaways
- Remotes connect local and hosted repositories
- Pull requests enable code review
- Forks allow external contributions
- SSH keys simplify authentication
- Good collaboration requires communication
Interview Deep-Dive
A junior developer runs 'git push --force origin main' and overwrites the last 5 commits that three other developers had already pulled. Describe the blast radius and your recovery plan.
A junior developer runs 'git push --force origin main' and overwrites the last 5 commits that three other developers had already pulled. Describe the blast radius and your recovery plan.
- The blast radius: the remote
mainbranch now points to an older commit. The 5 overwritten commits are no longer reachable from any remote ref. Developers who already pulled those commits have them locally, but their nextgit pullwill see a diverged history. If anyone had branched off the lost commits, their branches now have orphaned parents that do not exist on the remote. - Immediate recovery: any developer who has the original main (before the force push) can restore it. They run
git log origin/mainto confirm they still have the old tip (they might need to check their reflog withgit reflog show origin/main). Then they push the correct history back:git push origin main(or--force-with-leaseif the remote has already been updated by others). - If no developer has the original commits locally, check the hosting platform. GitHub retains force-pushed commits for at least 90 days — you can find the old tip SHA in the repository’s events audit log or by using the GitHub API to inspect the push event. With the SHA, you can reset main to the correct commit.
- Downstream cleanup: all three developers should
git fetch originand thengit reset --hard origin/mainon their local main (orgit pull --rebase). Developers with feature branches based on the lost commits should rebase onto the restored main. - Prevention: enable branch protection on main. In GitHub, this means requiring PR reviews and disabling force pushes entirely. In GitLab, protect the branch at the project settings level. This is the single most important repository configuration for any team.
--force-with-lease vs --force, and add a hook or CI check that rejects force pushes to protected branches. The incident becomes a learning moment that results in a concrete process improvement, not blame.Your company uses a fork-based workflow for an open-source project. An external contributor's PR has merge conflicts with main. Walk me through the correct way to resolve this -- from your perspective as the maintainer.
Your company uses a fork-based workflow for an open-source project. An external contributor's PR has merge conflicts with main. Walk me through the correct way to resolve this -- from your perspective as the maintainer.
- As a maintainer, I have two options. First, I ask the contributor to resolve the conflicts themselves. This is the preferred approach because it keeps the contributor engaged and they understand their code best. I leave a PR comment: “This PR has conflicts with main. Could you rebase onto the latest main?” Most active contributors will do this within a day.
- Second, if the contributor is unresponsive or unfamiliar with conflict resolution, I can resolve it myself. I fetch their branch:
git fetch origin pull/123/head:pr-123, check it out, rebase it onto main (git rebase main), resolve conflicts, and push to the contributor’s fork (if they enabled “allow edits from maintainers”) or to a new branch and update the PR. - A third, more common pattern in larger projects: I use GitHub’s “Update branch” button (which merges main into the PR branch) or the CLI equivalent. This creates a merge commit on the PR branch, which is less clean but avoids the contributor needing to force-push.
- The key consideration is the project’s merge strategy. If the project uses squash merge (most open-source projects do), the intermediate conflict resolution commits do not matter because they will be squashed into one commit on merge. If the project uses rebase-and-merge, the commit history should be clean.
git rebase -i) to remove or amend the commit that introduced the credential, and force-push the cleaned branch. I verify the cleaned PR no longer contains the credential with a search through the diff. If the PR was open for any length of time, I assume the credential was scraped by bots — GitHub public repos are actively scanned. The credential must be rotated regardless of whether we successfully clean the Git history.Explain the difference between 'git pull' and 'git fetch' followed by 'git merge'. When would you prefer one over the other?
Explain the difference between 'git pull' and 'git fetch' followed by 'git merge'. When would you prefer one over the other?
git pullis syntactic sugar forgit fetch+git merge(orgit fetch+git rebaseif configured withpull.rebase=true). Functionally, they produce the same result. The difference is control and visibility.git fetch+ manual merge gives you an inspection step. After fetching, you can rungit log origin/mainto see what your teammates pushed,git diff main..origin/mainto review the actual changes, and then decide how to integrate. This is valuable when working on a shared branch where unexpected changes could conflict with your in-progress work.git pullis more convenient for routine syncing. If you are on a personal feature branch and just want to stay up to date with main,git pull --rebase origin mainis a single command that fetches and replays your commits on top.- In my workflow, I use
git fetch+ manual inspection when integrating from a branch I do not control (e.g., syncing a fork with upstream, or pulling from a coworker’s branch). I usegit pull --rebasefor routine updates to my own feature branches from main. I configurepull.rebase=trueglobally so that accidentalgit pullwithout flags does not create unnecessary merge commits. - The most important thing is understanding that
git pullcan create merge commits that pollute your branch history. Teams that care about clean history should default togit pull --rebaseand only use merge pulls when they intentionally want to record a merge point.
git rerere (reuse recorded resolution): enable it with git config rerere.enabled true. Once you resolve a conflict, rerere records the resolution. If the same conflict pattern appears in subsequent commits, Git applies the recorded resolution automatically. For a branch with many commits, I would also consider squashing into fewer commits before rebasing to reduce the number of potential conflict points.Next: Git Advanced Topics →