GitHub Basics and Remote Repositories

SA
StudyAI
AI-generated study notes
· Published Updated Pro Plus model

From the Make notes on docker an GitHub curriculum

TL;DR

You'll learn how your local Git repository connects to a remote one on GitHub, what origin actually means, and how fetch, pull, and push move commits between the two. You'll also understand forks, pull requests, and the branch-based collaboration workflow teams actually use. By the end you can clone, branch, commit, push, and open a pull request confidently.

1. The Mental Model

Git tracks history on your machine; GitHub just hosts a copy of that history somewhere else so others can reach it. A "remote" is nothing magical — it's a nickname pointing at a URL, like a bookmark for another repository. Pulling and pushing are just syncing two independent histories, not some special GitHub feature. GitHub is a shared mailbox for commits, not the place where version control actually happens.

2. The Core Material

2.1 Remotes: what origin really is

Detailed close-up of a Samsung remote control showcasing buttons and logo.
Photo by Geri Tech on Pexels

When you clone a repository, Git automatically creates a remote called origin pointing at the URL you cloned from. "Origin" is just a convention — you could name it upstream, bob, anything.

git clone https://github.com/yourname/myproject.git
cd myproject
git remote -v
# origin  https://github.com/yourname/myproject.git (fetch)
# origin  https://github.com/yourname/myproject.git (push)

You can add more remotes. This matters a lot when you fork someone else's repo: your fork is origin, their original repo becomes upstream.

git remote add upstream https://github.com/original-owner/myproject.git
git remote -v

Each remote also tracks branches via remote-tracking branches — read-only references like origin/main that represent what Git last saw on the server. They update only when you fetch or pull; they don't move on their own, so they can go stale.

2.2 Fetch, pull, and push — the three-way relationship

Energetic Border Collie playing fetch with children in a sunny park, capturing a moment of joy and playfulness.
Photo by Elina Volkova on Pexels

There are three states of truth at any moment: your working directory, your local branch (main), and the remote-tracking branch (origin/main).

  • git fetch downloads new commits from the remote and updates origin/main, but does not touch your local main or your working files. It's the safe, non-destructive move.
  • git pull is git fetch + git merge origin/main (or rebase, if configured) in one step. It actually changes your local branch.
  • git push uploads your local commits to update the remote branch. Git refuses if the remote has commits you don't have locally yet — that's the classic "non-fast-forward" rejection.
git fetch origin              # see what's new, don't merge yet
git log main..origin/main     # inspect incoming commits first
git pull origin main          # fetch + merge in one go
git push origin main          # upload your commits

Why does push get rejected? Because Git enforces a fast-forward by default: your branch pointer can only move forward along a straight line of history. If someone else pushed in the meantime, your local history has diverged, and Git won't silently overwrite their commits. You must pull (merge or rebase) first, resolve any conflicts, then push again.

flowchart LR
    WD["Working Directory"] -- "git add" --> SA["Staging Area"]
    SA -- "git commit" --> LR["Local Repo (main)"]
    LR -- "git push" --> RR["Remote Repo (origin/main on GitHub)"]
    RR -- "git fetch" --> RT["origin/main (tracking ref)"]
    RT -- "git merge" --> LR
    LR -- "git pull = fetch+merge" --> LR

2.3 Forks and pull requests: the collaboration loop

Two black forks creating shadows on a nude background, a minimalist art piece with a focus on kitchenware design.
Photo by Ann Hannes on Pexels

A fork is a full copy of someone else's repository under your own GitHub account. You can't push directly to a repo you don't own, so forking gives you a writable copy. A pull request (PR) is a request asking the original repo's maintainers to pull your changes from your fork (or branch) into theirs — it's a diff plus a conversation thread, not a Git command.

Typical open-source contribution flow:

# 1. Fork on GitHub's website first, then clone your fork
git clone https://github.com/yourname/their-project.git
cd their-project

# 2. Add the original repo as upstream, to stay in sync
git remote add upstream https://github.com/original-owner/their-project.git

# 3. Create a feature branch — never work directly on main
git checkout -b fix-typo-in-readme

# 4. Make changes, commit
git add README.md
git commit -m "Fix typo in installation section"

# 5. Push the branch to YOUR fork (origin), not upstream
git push origin fix-typo-in-readme

Then on GitHub's web UI, you click "Compare & pull request" — this opens a PR from yourname:fix-typo-in-readme into original-owner:main. Maintainers review, comment, request changes, and eventually merge. Before opening the PR (or while it's under review), keep your branch current with upstream:

git fetch upstream
git rebase upstream/main      # or: git merge upstream/main
git push origin fix-typo-in-readme --force-with-lease   # only after rebase

Use --force-with-lease instead of plain --force — it refuses to overwrite the remote branch if someone else pushed to it since your last fetch, protecting you from clobbering collaborators' work.

3. Worked Example

Let's trace a complete small contribution end to end, with exact commands and expected output.

Setup — you want to fix a bug in a team's shared repo acme/widgets, where you already have push access (no fork needed, just branches):

git clone https://github.com/acme/widgets.git
cd widgets
git checkout -b bugfix-null-pointer

Make the change:

# widgets/calculator.py
def divide(a, b):
    if b == 0:
        raise ValueError("division by zero")   # was missing this check
    return a / b

Commit and push the branch:

git add widgets/calculator.py
git commit -m "Guard divide() against division by zero"
git push -u origin bugfix-null-pointer

The -u (--set-upstream) flag links your local bugfix-null-pointer branch to origin/bugfix-null-pointer, so future git push/git pull on this branch need no arguments.

Expected terminal output after push:

Enumerating objects: 7, done.
...
remote: Create a pull request for 'bugfix-null-pointer' on GitHub by visiting:
remote:      https://github.com/acme/widgets/pull/new/bugfix-null-pointer
To https://github.com/acme/widgets.git
 * [new branch]      bugfix-null-pointer -> bugfix-null-pointer

Click that link (or go to GitHub manually), set the base branch to main, write a PR description explaining why (not just what), and submit. A teammate reviews, maybe leaves a comment: "add a test." You respond locally:

# add the test
git add tests/test_calculator.py
git commit -m "Add test for divide-by-zero guard"
git push    # branch already tracks origin/bugfix-null-pointer, so no args needed

GitHub automatically appends the new commit to the same open PR — no new PR needed. Once approved, the maintainer clicks "Merge pull request" on GitHub (squash, merge commit, or rebase — team's choice). Afterward, clean up locally:

git checkout main
git pull origin main
git branch -d bugfix-null-pointer          # delete merged local branch
git push origin --delete bugfix-null-pointer   # delete remote branch

This whole cycle — branch, commit, push, PR, review, merge, cleanup — is the daily rhythm of real collaborative development.

4. Production Pitfalls & Best Practices

4.1 Real-World Best Practices

Three women practicing yoga indoors at a studio in Rishikesh, India.
Photo by Yoga Vidya Mandiram on Pexels

  • Never commit directly to main on shared repos. Always branch, even for tiny fixes — it makes review and rollback trivial.
  • Pull before you push, especially on shared branches, to minimize merge conflicts and avoid rejected pushes.
  • Write descriptive branch names like fix/login-timeout or feature/csv-export, not patch-1 — it helps reviewers and future-you.
  • Keep PRs small and focused. A 40-line PR gets reviewed in minutes; a 2000-line PR gets rubber-stamped or ignored.
  • Use .gitignore before your first commit, not after — once a file like node_modules/ or .env is tracked, removing it from history is painful.
  • Rebase your feature branch on the latest main before opening a PR, so the diff reviewers see is clean and conflict-free.
  • Tag releases (git tag v1.2.0 && git push origin v1.2.0) instead of relying on commit messages to mark shipped versions.

4.2 Common Bugs & Anti-Patterns

Mistake 1: Force-pushing a shared branch and erasing teammates' commits.

# BAD — overwrites origin/main unconditionally
git push --force origin main
# FIXED — fails safely if someone else pushed since you last fetched
git fetch origin
git push --force-with-lease origin main

Mistake 2: Committing secrets then trying to "delete" them.

# BAD — the secret is still in history, just not in HEAD
git rm .env
git commit -m "remove secret"
git push
# FIXED — rewrite history to actually purge it, then rotate the credential
git filter-repo --path .env --invert-paths
git push --force-with-lease origin main
# ALSO: revoke/rotate the leaked key immediately — assume it's compromised

Mistake 3: Cloning with HTTPS and getting stuck on password prompts.

# BAD — HTTPS asks for a password GitHub no longer accepts (removed 2021)
git clone https://github.com/you/repo.git
Password for 'https://you@github.com':
# FIXED — use a Personal Access Token as the password, or switch to SSH
git remote set-url origin git@github.com:you/repo.git
git push   # uses your SSH key instead

Mistake 4: Forgetting which remote-tracking branch is stale.

# BAD — assumes origin/main is current without checking
git merge origin/main
# FIXED — fetch first so the tracking ref is actually up to date
git fetch origin
git merge origin/main

4.3 When to Use What (Decision Matrix

Situation Right approach
You have push access to the repo Create a branch directly, skip forking
You don't own the repo (open source) Fork it, clone your fork, add upstream remote
You just want to see new commits without merging git fetch, then inspect with git log main..origin/main
You want fetch + merge in one step git pull
Your branch is behind main before opening a PR git fetch upstream && git rebase upstream/main
You accidentally pushed a secret Rotate the credential immediately, then rewrite history with git filter-repo

5. Now Try It

Create a new public repository on GitHub called git-practice. Clone it locally, create a branch add-notes, add a file notes.md with one sentence about what a remote-tracking branch is, commit it, and push the branch with git push -u origin add-notes. Then open a pull request on GitHub from add-notes into main, write a one-line description, and merge it yourself. Finally, run git fetch origin and git pull origin main locally to sync.

Success looks like: your local main branch contains the notes.md commit, the PR shows as merged on GitHub, and git remote -v plus git branch -a correctly show your origin remote and both local/remote branches.

Frequently asked about GitHub Basics and Remote Repositories

You'll learn how your local Git repository connects to a remote one on GitHub, what origin actually means, and how fetch, pull, and push move commits between the two. You'll also understand forks, pull requests, and the branch-based collaboration workflow teams actually use. Read the full notes above for the details.

GitHub Basics and Remote Repositories is a core topic in Make notes on docker an GitHub. Most exam papers test it via a mix of definitions, worked examples, and applied problems. The notes above cover the high-yield sub-topics, common pitfalls, and the kind of questions examiners typically set.

Yes — every note in the StudyAI Campus Hub is free to read in full, right here on this page, with no account needed. If you clone the plan into your own dashboard, the free plan shows a preview of each note there; Basic and above unlock the full notes in your dashboard, along with practice quizzes, flashcards and offline study. You can always come back here to read the complete note for free.
Continue with
Branching, Merging, and Collaboration with GitHub

More from Make notes on docker an GitHub


Get the full Make notes on docker an GitHub curriculum

Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.

Save this course free