Git Collaboration Workflow¶
Multi-person, multi-remote workflows: clone, branch, open PRs, merge. Commands: Git Command Set; messages: Commit Conventions.
See also: Git Command Set · Commit Conventions · Gitignore & Hooks
How to read this page¶
- Concepts — remotes, branches, and PRs in teamwork
- Overview — workflow models, naming, commands vs steps
- Scenarios — clone through merge, with pitfalls
- Symptom lookup — at the bottom
What “collaboration” means in Git¶
Collaboration means many people contribute to one history, usually via a host (GitHub, GitLab, Gitee), branches for in-progress work, and Pull Requests (Merge Requests) for review before landing on main.
In plain terms: “Everyone commits on their own branch, then merges into shared main through the remote and PRs—safely.”
Effect: main (or master) represents integratable code; feature branches can be pushed and rewritten (when solo) until CI and reviewers approve merge.
Overview¶
Common workflow models¶
| Model | Who | Remotes | Typical flow | Scenario |
|---|---|---|---|---|
| Shared repository | Team members with push access | One origin | branch → push → PR → merge | Member clone |
| Fork workflow | OSS, no direct push | origin = your fork, upstream = canonical | fork → branch → PR to upstream | Fork |
| Trunk + short branches (GitHub Flow) | Many web teams | Protected main, short features | main ← feature, frequent integration | Feature branch |
| Release branches (Git Flow lite) | Versioned products | main + release/* + hotfix/* | ship from release; hotfix to main | Hotfix |
Follow the target repo’s CONTRIBUTING doc; below covers the most common shared repo + feature + PR and fork + upstream paths.
Remote and branch naming (conventions)¶
| Name | Usual meaning |
|---|---|
origin | Default push/pull remote (team repo or your fork) |
upstream | In fork workflows, the canonical repo (fetch, rarely push) |
main / master | Trunk; protected, always integratable |
feature/*, fix/* | Short-lived work; often deleted after merge |
release/* | Release prep (some teams) |
Git commands used in this doc¶
| Command | Job | Scenario | Command set |
|---|---|---|---|
git clone | Copy remote locally | First clone | git clone |
git remote add upstream | Add canonical remote | Fork | git remote |
git fetch | Download refs, no merge | Sync main | git fetch |
git pull / pull --rebase | Fetch + integrate | Sync | git pull |
git switch -c | Create and switch branch | Feature branch | git switch |
git push -u origin | First push + upstream | Open PR | git push |
git merge | Merge into current branch | Update branch, Conflicts | git merge |
git rebase | Replay onto new base | Linear history | git rebase |
git push --force-with-lease | Safer force push | After rebase | git push |
PR lifecycle (platform-agnostic)¶
Create branch → commit locally → push branch → open PR/MR
→ CI → review comments → push more commits (same branch updates PR)
→ approve → merge (merge / squash / rebase)
→ delete remote feature branch → switch to main and pull
Post-merge message shapes: Commit Conventions — PR merge.
Scenario: first clone as a repo member¶
Typical uses: Company project; you were added as collaborator.
In plain terms: “origin is the team repo—update main, then branch.”
Effect: Avoid committing directly on main unless the team explicitly allows it.
Scenario: fork an OSS project and add upstream¶
Typical uses: No write access; you forked on GitHub and cloned your fork.
git clone git@github.com:YOUR_NAME/APP.git
cd APP
git remote add upstream git@github.com:ORG/APP.git
git remote -v
git fetch upstream
git switch main
git merge upstream/main
In plain terms: “Push to origin (fork); open PRs into upstream (canonical).”
Scenario: sync main before new work¶
Typical uses: Overnight gap; others merged while you were away.
git switch main
git pull origin main
# Fork workflow:
git fetch upstream
git merge upstream/main
git push origin main
In plain terms: “Refresh local main before cutting a new branch.”
Scenario: feature branch development¶
git switch main
git pull origin main
git switch -c feature/oauth-login
git add .
git commit -m "feat(auth): add OAuth callback handler"
git commit -m "test(auth): cover OAuth error paths"
In plain terms: “One feature, one branch—multiple commits OK if each is clear.”
Scenario: push branch and open a Pull Request¶
git push -u origin feature/oauth-login
# On the host: open PR targeting upstream/main (fork) or origin/main (member repo)
# Write PR title per commit conventions—squash merge often uses it as final subject
After review:
Scenario: update a long-lived branch with latest main¶
Option A: merge (simple, may add merge commit)
Option B: rebase (linear history, may need force push)
merge main into feature | rebase feature onto main | |
|---|---|---|
| History | May include merge commits | Linear |
| Push | Normal push | Often --force-with-lease |
| Risk | Lower | Personal branches only |
See Rebase vs merge.
Scenario: choosing rebase vs merge¶
| Situation | Common preference |
|---|---|
| feature → main (PR merge) | Host setting: squash / merge / rebase; many teams squash on PR |
Refresh your feature with main | merge or rebase; forks often rebase for tidy PRs |
| Shared branch many people push | merge; do not rewrite |
Published main | Never force push |
Warning
Force push overwrites remote history. Prefer --force-with-lease and confirm no one else builds on that branch.
Scenario: resolve merge or rebase conflicts¶
git merge origin/main
# CONFLICT (content): Merge conflict in src/app.ts
git status
# Edit conflict markers <<<<<<< ======= >>>>>>>
git add src/app.ts
git commit
# During rebase:
git add src/app.ts
git rebase --continue
# Abort: git rebase --abort
In plain terms: “Git stops so you choose the combined result.”
For merge commits with two parents, see git show.
Scenario: rules on shared branches¶
| Rule | Why |
|---|---|
No force push on main | Breaks others’ history |
| No rebase on shared pushed branches | Same |
| Merge via PR + review + CI | Quality and audit |
| Delete remote feature after merge | Less stale clutter |
| Hotfix from tag or release | See Hotfix |
Mistakes on main: revert with a new commit—see After push.
Scenario: production hotfix¶
git fetch origin
git switch -c hotfix/payment-timeout origin/release/v2.3
git commit -m "fix: handle payment gateway timeout"
git push -u origin hotfix/payment-timeout
In plain terms: “Branch from a stable point—not from half-done feature work.”
Scenario: clean up after PR merge¶
Scenario: push rejected—someone else updated the remote¶
git push origin feature/oauth-login
# rejected (fetch first)
git fetch origin
git merge origin/feature/oauth-login
git push
If main moved, see Update branch.
Quick lookup: symptom → suggestion¶
| Symptom | Suggestion |
|---|---|
| First time on a project | Read CONTRIBUTING → clone → sync main → branch |
| OSS, no write access | Fork → add upstream → sync from upstream |
| Unsure where to push | git remote -v; PR target on the host |
| PR shows conflicts | Merge/rebase main locally → fix → push |
| Stale feature branch | Update with main before review |
| Force push? | Solo feature only; use --force-with-lease |
Committed to main by mistake | revert; don’t rewrite shared history |
| Too many old branches | git fetch --prune; delete merged locals |
Command index: Git Command Set.