Beginner · Git in depth · topic 13 of 53 · 30 min
Collaboration: remotes, pull requests and branching strategies
Explanation
Remotes: fetch, pull and push
A remote is a named link to another copy of the repository. When you clone, Git creates a remote called origin pointing at the URL you cloned from. Git also keeps remote-tracking branches such as origin/main: your local record of where main was on the server the last time you talked to it.
git remote -v # list remotes and their URLs
git fetch origin # download new commits; updates origin/main, does NOT touch your files
git pull # fetch + merge origin/main into your current branch
git pull --rebase # fetch + rebase your local commits on top instead
git push -u origin feature/upi # upload a branch and set its upstream
git push # later pushes need no namesfetch is always safe: it only downloads. pull changes your branch, so it can cause conflicts. Many developers fetch first, look at git log main..origin/main to see what is new, and then merge or rebase.
Forks
You cannot push to a repository you do not have write access to, such as an open-source project. A fork is your own copy of it on GitHub. You push to your fork and open a pull request back to the original. By convention, your fork is origin and the original project is added as a second remote called upstream, so you can fetch its latest changes.
Pull requests and code review
A pull request (PR, called a merge request or MR on GitLab) asks to merge one branch into another. It shows the diff, runs automatic checks such as tests and linting, and lets teammates comment line by line. Only after approval and green checks is it merged.
- Keep PRs small: a few hundred lines at most. Reviewers find more problems in small PRs and review them faster.
- Write a description: what changed, why, how you tested it, and screenshots for UI changes. Link the issue or ticket.
- As a reviewer, comment on the code, not the person. Ask questions ("What happens if the UPI callback times out?") rather than giving orders, and label small preferences as "nit:" so the author knows they are optional.
- As an author, reply to every comment, push fixes as new commits, and do not take feedback personally.
Protected branches and required checks
On GitHub and GitLab, an admin can protect main with branch protection rules (GitHub also has the newer rulesets). Typical rules: changes only through PRs, at least one approval, required status checks (the CI pipeline must pass), branch up to date before merging, and no force pushes or deletion. This turns team agreements into rules the platform enforces.
A CODEOWNERS file (in .github/, the root or docs/) maps paths to the people or teams who own them, for example /payments/ @acme/payments-team. GitHub automatically requests their review, and a protection rule can require their approval.
Branching strategies
| Strategy | How it works | Fits |
|---|---|---|
| GitHub flow | main is always deployable. Branch, open a PR, review, merge, deploy. | Most web apps and services |
| Trunk-based development | Everyone merges into main (the trunk) at least daily, using very short-lived branches. Unfinished features hide behind feature flags. | Teams doing continuous delivery, many deploys a day |
| Gitflow | Long-lived main and develop branches, plus feature/*, release/* and hotfix/* branches. | Software shipped in versions, like installed or mobile apps with several supported releases |
A feature flag is a setting in code that switches a feature on or off at runtime. With flags, half-built code can be merged and deployed safely while switched off, and then turned on for 5% of users, then everyone. This is what makes very short-lived branches practical. Gitflow adds overhead and long-lived branches; even its author has said simpler flows suit web apps that deploy continuously.
Conventional Commits
Conventional Commits is a simple, widely used format for commit messages that both humans and tools can read.
type(scope)!: description
feat(cart): add UPI QR payment option
fix: round GST to two decimals on invoices
docs(readme): explain local setup
refactor(api)!: rename /orders to /v2/orders
BREAKING CHANGE: clients must call /v2/ordersfeat (a new feature) and fix (a bug fix) are defined by the specification; teams commonly add docs, chore, refactor, test, ci, build and perf. Because the format is predictable, release tools can work out the next version number and write the changelog automatically, as the next lesson shows.
Common mistakes and how to fix them
- Huge PRs that sit for a week: split them, and use feature flags so parts can be merged early.
- Working on an old copy of main: fetch and update your branch daily.
- Approving without reading: if you approve, you share responsibility. Run the code if the change is risky.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Collaboration: remotes, pull requests and branching strategies · 1/7
Teams share work through remotes, pull requests and an agreed branching strategy.
Prefer a video by a teacher? Find free videos on “git pull request workflow github flow trunk based development” on YouTube ↗
In real life: A payments team using GitHub flow and protected branches
A payments startup in Gurugram protects main: every change needs a PR, one approval from the payments team listed in CODEOWNERS, and a green CI run of unit tests and a security scan. A developer opens a 150-line PR titled "feat(refunds): allow partial UPI refunds". The reviewer asks what happens if the bank callback arrives twice; the author adds an idempotency check and a test. After approval, the PR is squash-merged and the pipeline deploys it behind a feature flag turned on for internal staff first.
# .github/CODEOWNERS
/payments/ @acme/payments-team
/infra/ @acme/platform-team
*.md @acme/docsPractice (0/3 done)
You want to see what your teammates pushed without changing any of your files. Which command?
Write parseCommit(message) for Conventional Commits. The first line has the form type(scope)!: description, where (scope) and ! are optional, and there is exactly one space after the colon. Return { type, scope, breaking, description }, with scope null when missing. breaking is true if there is a ! before the colon OR any later line starts with "BREAKING CHANGE:" or "BREAKING-CHANGE:". If the first line does not fit the format, return null. type is lowercase letters only.
Write the pull request description for this change: you added an "Order again" button to the order history screen of a food delivery app, so users can re-order a past order in one tap. Then write two review comments a good reviewer might leave on such a PR, one important and one marked as a nit.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Semantic versioning, tags and releasesGit in depth · same module
- Git and GitHubFrontend Web Development · Async JavaScript, modules and tools
- CI/CD: shipping every change safelyFull-Stack Development · Deploying and running the app
- Modules, environments and Terraform in CIInfrastructure as code with Terraform
- Deployment strategies, feature flags and GitOpsCI/CD pipelines
- Continuous integration, delivery and deploymentCI/CD pipelines
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is origin/main?
Answer: Your local record of where main was on the remote at the last fetch
Remote-tracking branches like origin/main are updated by fetch and show the server state you last saw.
In trunk-based development, how do teams merge unfinished features safely?
Answer: They hide unfinished work behind feature flags
Feature flags let half-built code be merged and deployed while switched off, so branches stay short-lived.
Which project is the best fit for Gitflow's release and hotfix branches?
Answer: A desktop app with several supported versions released every few months
Gitflow suits software shipped in numbered versions that need parallel maintenance. Continuously deployed web apps usually prefer simpler flows.
Which commit message marks a breaking change in Conventional Commits?
Answer: feat(api)!: remove v1 endpoints
A ! before the colon (or a BREAKING CHANGE: footer) marks a breaking change.
What does a CODEOWNERS file do on GitHub?
Answer: Automatically requests reviews from the owners of the changed paths
CODEOWNERS maps paths to people or teams; GitHub requests their review, and branch protection can require it.
What is a pull request?Related
Answer: A request on GitHub to merge your branch, where others can review it first
A pull request shows your changes, lets teammates comment and approve, and then merges the branch.
From Git and GitHub
main has no new commits since feature was created. What does git merge feature (run on main) do by default?Related
Answer: Moves main forward to the tip of feature (fast-forward)
When main is an ancestor of feature, Git just moves the pointer. Use --no-ff if you want a merge commit anyway.
Since the last release v3.1.4 there are commits: "fix: login timeout" and "feat: export to PDF". What is the next version?Related
Answer: 3.2.0
The feat is the highest change, so MINOR is bumped and PATCH reset: 3.2.0.
What does CI do on every push?Related
Answer: Installs, lints, tests and builds the code on a fresh machine
Continuous integration checks each change automatically, so problems show up within minutes.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Git in depth” before its exam: Semantic versioning, tags and releases.
- Module 3 exam: Git in depth · 13 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Docker. 53 topics left in the course before the final exam.
← Previous: Rebase, undo and rescue: rebase, reset, revert, reflog and stash