Contribute to an upstream repository using the standard open-source collaboration model: fork the repo, clone the fork, configure both origin and upstream remotes, develop on an isolated branch, sync with upstream before submitting, then open a pull request. This is the workflow used in every real engineering team on GitHub.
Upstream Repo (pravinmishraaws/dmi-devops-exercises)
│
│ Fork (GitHub UI)
▼
Your Fork (Ralphlarry/dmi-devops-exercises)
│
│ git clone
▼
Local Machine (WSL/Linux)
├── remote: origin → your fork on GitHub
└── remote: upstream → original repo on GitHub
│
│ git fetch upstream + git rebase upstream/main
▼
Feature Branch → git push origin → Pull Request on GitHub
On GitHub, navigate to the upstream repository and click Fork → Create fork.
This creates https://github.com/Ralphlarry/dmi-devops-exercises — your personal copy.
git clone https://github.com/Ralphlarry/dmi-devops-exercises.git
cd dmi-devops-exercisesgit remote -vExpected output:
origin https://github.com/Ralphlarry/dmi-devops-exercises.git (fetch)
origin https://github.com/Ralphlarry/dmi-devops-exercises.git (push)
git remote add upstream https://github.com/pravinmishraaws/dmi-devops-exercises.gitgit remote -vExpected output:
origin https://github.com/Ralphlarry/dmi-devops-exercises.git (fetch)
origin https://github.com/Ralphlarry/dmi-devops-exercises.git (push)
upstream https://github.com/pravinmishraaws/dmi-devops-exercises.git (fetch)
upstream https://github.com/pravinmishraaws/dmi-devops-exercises.git (push)
Why two remotes?
originis your fork — you have write access.upstreamis the original — you can fetch from it but cannot push directly. This separation lets you pull in updates from the upstream without touching your fork's main branch manually.
git checkout -b feature/add-linux-notesBranch names should be descriptive and kebab-case. Never commit directly to
mainin a collaborative repo.
# Make edits to relevant files
git add .
git commit -m "docs: add Linux command reference notes"git push origin feature/add-linux-notesThis step is critical — always sync before opening a pull request to avoid merge conflicts.
git fetch upstreamgit rebase upstream/mainRebase vs merge: Rebase replays your commits on top of the latest upstream commits, producing a clean linear history. This is preferred over
git merge upstream/mainfor pull request preparation because it eliminates unnecessary merge commits.
# If conflicts occur, Git pauses and lists conflicting files
# Edit the files to resolve conflicts, then:
git add <resolved-file>
git rebase --continue
# To abort if needed:
git rebase --abortgit push origin feature/add-linux-notes --force-with-lease
--force-with-leaseis safer than--force— it fails if someone else has pushed to your branch in the meantime, preventing accidental overwrites.
Navigate to your fork on GitHub. GitHub will display a banner: "Your branch is 1 commit ahead of pravinmishraaws:main — Compare & pull request"
Click Compare & pull request, then:
- Title: Use conventional commit format:
docs: add Linux command reference notes - Description: Explain what was changed and why
- Base:
pravinmishraaws/dmi-devops-exercises→main - Compare:
Ralphlarry/dmi-devops-exercises→feature/add-linux-notes
Click Create pull request.
# After PR is approved and merged on GitHub, sync your local main:
git switch main
git fetch upstream
git merge upstream/main
git push origin main# Delete locally
git branch -d feature/add-linux-notes
# Delete remote branch on your fork
git push origin --delete feature/add-linux-notes| Error in original work | Correct form | Why it matters |
|---|---|---|
Missing git remote add upstream step |
Always add upstream remote after cloning a fork | Without upstream configured, git fetch upstream fails. The fork and upstream remotes are two distinct connections. |
git merge upstream/main before PR |
git rebase upstream/main before PR |
Merge creates an extra merge commit that pollutes PR history. Rebase produces a clean, linear set of commits that reviewers can read clearly. |
git push origin feature/... --force |
git push origin feature/... --force-with-lease |
--force blindly overwrites. --force-with-lease checks the remote first — it fails safely if someone else has pushed. |
| PR title: "my changes" | docs: add Linux command reference notes |
Meaningless PR titles make code review history unsearchable. Use the same Conventional Commit format for PR titles as for commit messages. |
- A fork is not just a copy — it is your writable clone of a repo you don't own.
upstreamis the source of truth;originis yours. - Always rebase onto upstream before opening a PR. A PR opened without syncing is disrespectful to reviewers — it may have conflicts they have to resolve.
git fetch upstreamis a read-only operation — it downloads changes but does not modify your working tree. Safe to run at any time.--force-with-leaseis the professional default whenever force-pushing to a shared branch is unavoidable.- Deleting a merged branch is safe and expected — leaving stale branches around creates confusion on team repos.
- The complete upstream sync workflow:
git fetch upstream→git rebase upstream/main→git push origin <branch> --force-with-lease