Chapter 08Lesson 02~115 minutes

Collaborative Workflows: Forks, Upstreams, Pull Requests, and Reviewable History: Guided Hands-On Workflow and Core Operations

Simulate fork-based collaboration entirely locally: authoritative and fork bare repositories, upstream synchronization, clean topic history, publication, patch-based review, and merge/squash/linear graph outcomes.

Local fork labSynchronize topicMerge vs squashPatch series

Learning objectives

  • Create an authoritative repository and contributor fork using local bare repositories.
  • Add and inspect a conventional upstream remote without confusing it with branch tracking.
  • Synchronize an unpublished topic branch safely against a current authoritative target.
  • Publish a reviewable topic to the fork and export its commits as patches without a hosted account.
  • Compare merge-commit, squash, and rebased-linear integration outcomes at the Git graph level.

1. Build a local fork-equivalent topology

This lab uses filesystem repositories, so no hosted account, token, SSH key, or internet connection is required. The directory layout represents an authoritative repository, a contributor fork, and local working clones.

Git Bash, Bash, or zsh

mkdir git-collab-lab
cd git-collab-lab
git init --bare upstream.git

git clone upstream.git seed
cd seed
git switch -c trunk
git config user.name "Project Maintainer"
git config user.email "maintainer@example.invalid"
printf "# Service\n" > README.md
printf "port=8080\n" > service.conf
git add README.md service.conf
git commit -m "Initialize service project"
git push -u origin trunk
cd ..
git --git-dir=upstream.git symbolic-ref HEAD refs/heads/trunk

git clone --bare upstream.git fork.git
git clone fork.git contributor
git clone upstream.git integrator

What changed: upstream.git and fork.git are bare repositories containing Git database/refs but no checked-out working tree. The two normal clones provide working trees. The fork is simply another repository that initially contains the same history.

2. Give the contributor clone conventional remote names

cd contributor
git remote -v
git remote add upstream ../upstream.git
git remote -v
git fetch upstream
git branch -vv
git for-each-ref --format='%(refname:short) %(objectname:short)' refs/remotes

origin points to fork.git. The newly added upstream points to the authoritative repository. Fetch creates/updates upstream/trunk according to the remote's fetch refspec; it does not change local trunk.

3. Create a focused topic from the authoritative base

git switch -c topic-health upstream/trunk
git config user.name "Contributor"
git config user.email "contributor@example.invalid"

printf "health_endpoint=/healthz\n" >> service.conf
git add service.conf
git diff --staged
git commit -m "Expose health endpoint for probes"

printf "\n## Health check\nUse /healthz for readiness probes.\n" >> README.md
git add README.md
git diff --staged
git commit -m "Document readiness probe endpoint"

git status --short --branch
git log --graph --decorate --oneline --all --max-count=12

The two commits form a small reviewable series: one behavior/configuration change, then documentation describing operational use. They are unpublished so far.

4. Advance the authoritative branch independently

Use the integrator clone to simulate another accepted change.

cd ../integrator
git config user.name "Integrator"
git config user.email "integrator@example.invalid"
printf "owner=platform-team\n" >> service.conf
git add service.conf
git commit -m "Record service ownership"
git push origin trunk
git log --oneline -3

cd ../contributor
git fetch upstream
git log --graph --decorate --oneline --all --max-count=15
git rev-list --left-right --count upstream/trunk...topic-health

The graph now shows divergence: the authoritative branch has work the topic did not start with, and the topic has two proposal commits.

5. Choose a synchronization method from history policy

For an unpublished topic owned by one contributor, rebasing onto the current target can produce a straightforward review series. For a topic already consumed by others, merging the target branch into the topic preserves existing commit identities and is often safer.

Rebase recreates commits and changes their IDs. Use it here only because this topic has not been published or consumed.
git status --short
git rebase upstream/trunk
git log --graph --decorate --oneline --all --max-count=15
git merge-base upstream/trunk topic-health
git log --oneline upstream/trunk..topic-health
git diff --stat upstream/trunk...topic-health

The content is still the proposal, but the two topic commits now have new parentage and therefore new object IDs. Chapter 09 explains rebase reconstruction in depth.

6. Publish the topic to the contributor fork

git push --dry-run -u origin topic-health
git push -u origin topic-health
git branch -vv
git ls-remote --heads origin topic-health

The topic branch now exists in fork.git. A hosting platform could use that ref as a review source, but the local lab needs no review UI to inspect or integrate it.

7. A review can also be represented as refs plus patches

Git can serialize each non-merge commit as a mail-style patch message. This is not a hosted pull request, but it demonstrates that a reviewable change series can travel without a platform account.

mkdir -p review-patches
git format-patch --output-directory review-patches upstream/trunk..topic-health
ls review-patches
git log --reverse --format='%h %s' upstream/trunk..topic-health

Chapter 23 covers patch/email maintainer workflows thoroughly; here the command simply reinforces that commit series and hosted review records are separate concepts.

8. Compare integration graph outcomes in isolated local refs

Create an isolated comparison clone so the authoritative remote is not changed.

cd ..
git clone upstream.git compare
cd compare
git config user.name "Graph Reviewer"
git config user.email "reviewer@example.invalid"
git remote add contributor ../fork.git
git fetch contributor topic-health

git branch integrate-merge trunk
git branch integrate-squash trunk
git branch integrate-linear trunk

Outcome A — merge commit

git switch integrate-merge
git merge --no-ff contributor/topic-health -m "Merge reviewed health topic"
git log --graph --decorate --oneline --max-count=8

The target history records both topic commits plus a two-parent merge commit.

Outcome B — squash

git switch integrate-squash
git merge --squash contributor/topic-health
git status --short
git diff --staged --stat
git commit -m "Add reviewed health endpoint"
git log --graph --decorate --oneline --max-count=8

--squash prepared the combined content but did not create a merge commit or parent relationship to the topic; the explicit commit creates one new single-parent commit.

Outcome C — rebased/linearized topic then fast-forward integration

Comparison branch only. We copy the contributor topic to a temporary local branch before rebasing so the published fork ref is not rewritten.
git switch -c topic-linear contributor/topic-health
git rebase trunk
git switch integrate-linear
git merge --ff-only topic-linear
git log --graph --decorate --oneline --max-count=8

This produces a linear target history. The topic commits may have been recreated if their old base differed from trunk.

9. Once others consume commits, preserve that fact in your decision

If a reviewer has fetched, commented on, tested, or built artifacts from specific commit IDs, rewriting those commits makes the old identifiers stale. A small correction can still be added as a new commit. If policy permits rewriting an unpublished/private series, communicate it and use guarded force updates when publishing the replacement. Chapter 09 provides the full safety model.

10. Challenge — choose collaboration operations from the graph

  1. Your topic is unpublished and the target branch advanced by one commit. Which local integration choice can keep the topic linear?
  2. Your teammate already based work on your published topic commits. Which synchronization choice preserves their existing commit IDs?
  3. You need to show a reviewer only topic commits not in the authoritative target. Which log range answers that?
  4. You have no hosting account. Which Git mechanism can package the series for review/transport?

11. Cleanup

Verify the path before recursive deletion. All repositories in this lab are disposable.

Git Bash / Bash / zsh

cd ../..
pwd
rm -rf git-collab-lab

PowerShell

Set-Location ../..
Get-Location
Remove-Item -Recurse -Force git-collab-lab

12. Knowledge check

Question 1. After git fetch upstream, why might your local trunk still be behind?

Question 2. Why was rebase acceptable for topic-health before its first push?

Question 3. What topology difference does squash integration create?

Question 4. Does git format-patch create a pull request?

13. Summary

You simulated an authoritative project and contributor fork with bare repositories, added an upstream remote, synchronized an unpublished topic, published it to the fork, exported a patch series, and compared merge, squash, and linearized outcomes without changing shared authoritative history.

Next

Turn mechanics into a maintainable collaboration policy

Lesson 3 decides remote conventions, branch freshness, review granularity, integration ownership, merge strategy, signing evidence, and which rules must be enforced by a server rather than hoped for in client conventions.

Authoritative references

 git-clone
 git-remote
 git-fetch
 git-rebase
 git-merge
 git-format-patch

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.