Lesson 04 of 8 · Level 2 — Working in a team
Remotes and pull requests
Work with shared repositories: remotes and tracking branches, the difference between fetch and pull, pushing safely, forks, and the pull-request workflow with reviews, status checks and protected branches that keeps the main branch always releasable.
Remotes and tracking branches
A remote is a named URL of another copy of the repository, usually origin. After fetching, Git keeps remote-tracking branches such as origin/main, read-only snapshots of where the remote's branches were last time you looked.
$ git remote -v
origin git@github.com:acme/shop.git (fetch)
origin git@github.com:acme/shop.git (push)
$ git fetch origin
$ git log --oneline main..origin/main # commits on the remote you don't have yet
$ git status -sb
## main...origin/main [behind 3]
git fetchupdatesorigin/*only. Always safe.git pull= fetch + integrate into your current branch (merge, or rebase withpull.rebase true).git pushsends your commits; it's rejected if the remote has commits you don't have, so fetch, integrate, then push again.
The remote is the team's shared noticeboard. Fetching is walking over to read it; pulling is reading it and copying the new notes into your own notebook; pushing is pinning your notes up, which only works if you've read the latest notes first.
Authenticate with SSH keys (or a token)
$ ssh-keygen -t ed25519 -C "asha@example.com"
$ cat ~/.ssh/id_ed25519.pub # add this public key to your Git server account
$ ssh -T git@github.com
Hi asha! You've successfully authenticated...
For HTTPS, use a personal access token or a credential manager, never your account password. For CI, use deploy keys or short-lived tokens scoped to one repository.
Forks
When you can't push to a repository (open source, or a platform team's repo), fork it: your own server-side copy. Push branches to your fork and open a pull request to the original. Keep your fork current:
$ git remote add upstream git@github.com:platform/charts.git
$ git fetch upstream
$ git rebase upstream/main
The pull-request workflow
- Branch from an up-to-date
main. - Commit small, focused changes; push the branch.
- Open a pull request (called a merge request on GitLab) with a description: what, why, how it was tested, risk and rollback.
- CI runs status checks: build, tests, lint, security scans,
terraform plan. - Review: at least one approval, from code owners where they're defined.
- Merge (with the repository's chosen method), delete the branch, and let the pipeline deploy.
A pull-request description template in the repository (.github/pull_request_template.md) makes step 3 automatic.
Protected branches
Set on the Git server for main (and release branches):
| Rule | Why |
|---|---|
| Require a pull request before merging | No direct pushes to main |
| Require N approvals, including code owners | The right people review the right files |
| Require passing status checks | Broken code can't merge |
| Require branches to be up to date before merging | Tests ran against what will actually land |
| Block force pushes and deletion | History can't be rewritten or lost |
| Require signed commits (optional) | Commits are verifiably from their authors (lesson 07) |
Many servers also offer a merge queue, which tests each pull request on top of the others waiting to merge, so a busy main stays green without everyone constantly rebasing.
Try it: a full pull-request cycle
- Create a repository on your Git server (GitHub, GitLab, Gitea) and push a small project.
- Protect
main: pull requests required, 1 approval, a status check (even a simple lint workflow). - Create a branch, change something, push, and open a pull request with a proper description.
- Try
git push origin maindirectly and read the rejection. - Merge through the pull request, then
git fetch --pruneand delete your local branch.
Going deeper: review that scales
- Keep pull requests under a few hundred lines; split refactors from behaviour changes.
- Use CODEOWNERS so reviews route automatically (lesson 07).
- Automate the boring parts (formatting, linting, plan output, security scans) so humans review design and intent.
- Measure review turnaround; slow reviews push people towards bigger, riskier pull requests.
Recap
- origin/main is your last-known view of the remote;
fetchis safe,pullintegrates,pushneeds you to be up to date. - Authenticate with SSH keys or tokens, never passwords.
- Pull requests with description, checks and reviews; forks when you can't push.
- Protect main: PRs, approvals, code owners, checks, no force pushes.
This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.