Collaboration Model: Local Git + a Shared Remote
In a small project, collaboration usually means: everyone commits locally, then shares work through a remote repository (for example, on a Git server). Instead of pushing directly to main, you push a feature branch and open a pull request (PR). A PR is a reviewable proposal to merge your branch into a target branch (often main), with discussion and automated checks attached.
Adding a Remote
A remote is a named shortcut to a repository URL. Most projects use origin as the default name.
Check existing remotes
git remote -vThis shows remote names and their fetch/push URLs.
Add a remote
git remote add origin https://example.com/your/repo.gitIf you use SSH:
git remote add origin git@example.com:your/repo.gitRename or change a remote URL
git remote rename origin upstreamgit remote set-url origin https://example.com/new/url.gitA common pattern is: origin points to your fork, and upstream points to the main shared repo.
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
Pushing Branches to the Remote
To collaborate via PRs, you typically push a branch (not main) and then open a PR from that branch.
Push a new branch and set upstream tracking
git push -u origin feature/add-searchThe -u flag sets an upstream so future pushes/pulls can omit the remote and branch name:
git pushgit pullPush additional commits to the same branch
After you add more commits locally, pushing updates the remote branch and (if a PR exists) updates the PR automatically:
git pushPush a local branch under a different remote name
If your local branch name differs from the remote branch name:
git push origin feature/add-search:feature/searchFetching and Pulling: Getting Others’ Work
When teammates push changes, your local repository does not automatically know about them. You update your view of the remote with fetch, and you incorporate changes into your current branch with pull.
Fetch: update remote-tracking branches only
git fetch originThis downloads new commits and updates your remote-tracking references (like origin/main), but it does not modify your current branch or working tree.
Pull: fetch + integrate into your current branch
git pullgit pull is essentially git fetch followed by integrating the upstream branch into your current branch. The integration method depends on your configuration and workflow.
Pull a specific branch
git pull origin mainUse this when you want to explicitly pull from a particular remote/branch.
Understanding Remote-Tracking Branches
Remote-tracking branches are your local read-only pointers to the state of branches on the remote. Examples: origin/main, origin/feature/add-search. They move when you fetch/pull.
List remote-tracking branches
git branch -rSee local and remote branches together
git branch -vvThis shows which local branches track which upstream branches and whether they are ahead/behind.
Create a local branch from a remote-tracking branch
If someone pushed origin/feature/api-timeout and you want to work on it:
git switch -c feature/api-timeout --track origin/feature/api-timeoutNow your local branch tracks the remote branch, so git pull and git push behave as expected.
Pull Request Lifecycle (PRs as the Review Mechanism)
A pull request is a collaboration wrapper around a branch: it shows the diff, ties discussion to lines of code, runs checks, and records approvals. While the UI differs across hosting providers, the lifecycle is consistent.
1) Create a PR from your branch
Typical flow:
- Push your branch to the remote.
- Open a PR targeting
main(or the project’s integration branch). - Confirm the “base” (target) and “compare” (your branch) are correct.
Before opening the PR, make sure your branch contains only the intended changes for that feature/fix (see the checklist later).
2) Summarize intent in the PR description
A good PR description helps reviewers understand what to look for and why. Include:
- What changed (high-level summary).
- Why it changed (problem statement, constraints).
- How it works (brief design notes if needed).
- How to test (commands, steps, edge cases).
- Scope boundaries (what you intentionally did not change).
Example structure:
Summary: Add search endpoint with pagination defaults. Why: Clients need server-side filtering; current list endpoint is too slow. How: New /search route, reuses existing query builder, adds index hint. Tests: npm test; added integration test for empty query and pagination. Notes: No UI changes in this PR.3) Link commits to changes (and keep the story readable)
Reviewers see both the overall diff and the commit list. You want commits to map to understandable steps, such as:
- Commit 1: add API contract / types
- Commit 2: implement behavior
- Commit 3: add tests
- Commit 4: docs / small cleanup
When commits are meaningful, reviewers can review commit-by-commit (often easier than one huge diff), and future debugging benefits from clearer history.
4) Respond to review feedback
Reviews usually contain a mix of:
- Blocking issues (bugs, incorrect behavior, security concerns)
- Suggestions (readability, naming, structure)
- Questions (clarify intent, edge cases)
Good response habits:
- Reply to each thread: confirm the change you’ll make, or explain why you won’t.
- If you disagree, focus on tradeoffs and project goals, not personal preference.
- If a comment is resolved by a commit, link the commit in your reply (many platforms auto-link).
5) Update the PR with additional commits
After addressing feedback locally, you typically add new commits and push them to the same branch. The PR updates automatically.
# make changes, run tests, then commit as usual git add -A git commit -m "Fix pagination off-by-one" git pushPrefer additional commits during review rather than rewriting history mid-review, unless your team explicitly asks for a cleanup. Rewriting commits can invalidate earlier review comments because line references may shift.
Keeping PRs Reviewable
Reviewability is a feature. A PR that is easy to review gets merged faster and with fewer defects.
Keep scope small
- One PR should solve one problem.
- If you discover adjacent work, consider a follow-up PR.
- If you must include a prerequisite refactor, isolate it into its own commit(s) and explain why it’s necessary.
Use descriptive PR titles
Titles should describe the outcome, not the activity. Compare:
- Weak: “Updates”
- Better: “Add server-side search with pagination defaults”
- Better (bugfix): “Fix crash when query is empty in search endpoint”
Write clean commit messages
Commit messages should help a reviewer (and future you) understand intent quickly. Practical guidelines:
- Start with a verb and a clear object: “Add…”, “Fix…”, “Refactor…”, “Remove…”.
- Keep the first line focused; add details in the body if needed.
- Avoid “WIP” commits in shared branches unless your team expects them.
Avoid unrelated formatting-only changes
Formatting-only diffs (reindentation, mass whitespace changes, reordering imports without reason) make reviews harder because they hide meaningful changes. If formatting changes are necessary:
- Keep them in a separate commit so reviewers can ignore or quickly approve it.
- Prefer automated formatting tools run consistently across the codebase, not ad-hoc edits.
Before Opening a PR: Practical Checklist
Use this checklist to reduce back-and-forth and avoid preventable review comments.
1) Ensure you’re up-to-date with main
- Fetch the latest remote state.
- Confirm your branch is based on the current
main(or update it according to your team’s workflow).
git fetch originThen verify what you’re comparing against:
git log --oneline --decorate --graph --max-count=202) Run tests (and any required checks)
Run the project’s standard test command(s) locally before opening the PR. If there are linters or type checks, run those too. The goal is: reviewers focus on logic and design, not avoidable failures.
3) Ensure commits are meaningful
Scan your commit list and confirm each commit has a purpose and a clear message.
git log --oneline origin/main..HEADThis shows commits that are in your branch but not in origin/main.
4) Confirm there are no secrets or sensitive data
Double-check you did not commit:
- API keys, tokens, passwords
- Private certificates
- Production config files with secrets
- Large data dumps or logs
Practical checks:
- Search for common secret patterns in changed files.
- Review newly added config files carefully.
5) Do a quick self-review of the diff
Review your changes as if you were the reviewer. Look for accidental edits, debug code, and unclear naming.
git diff origin/main...HEADIf you want a file-by-file summary first:
git diff --stat origin/main...HEADAsk yourself:
- Does the diff match the PR title and description?
- Are there any unrelated changes (formatting, renames, dependency bumps) that should be split out?
- Are edge cases handled and tested?
- Is anything confusing without additional comments or documentation?