GitHub

How to Pull from GitHub: Detalied Guide

How to Pull from GitHub: Detalied Guide

Pulling from GitHub comes down to git pull origin main, run inside a local clone. It downloads whatever is new on the remote and folds it into the branch you have checked out.

Most days that is all there is to it. The day it isn’t tends to be the day a teammate pushed to the same branch you did.

The git-pull manual for Git 2.56 names fast-forward only as the default integration mode when none is configured. So a branch that has diverged from GitHub stops with an error instead of merging silently.

How to Pull From GitHub With git pull

YouTube player

Open a terminal inside your local repository and run git pull origin main. Git downloads the new commits from GitHub and integrates them into the branch you have checked out.

Once a branch tracks a remote branch, a bare git pull does the same job. The git-scm manual defaults the remote to the branch’s upstream, or to origin when none is set.

  1. Open a terminal and move into the repository folder with cd.
  2. Run git status and confirm the working tree is clean.
  3. Run git remote -v to confirm the GitHub URL behind origin.
  4. Run git pull origin main, replacing main with your branch name.
  5. Read the output. “Already up to date.” means nothing changed upstream.

What to check before running git pull

Git has to be installed, and git --version prints a version number if it is. You also need a remote, with origin pointing at the GitHub repository, and the local branch should track a remote branch.

Then there’s the working tree. Commit or stash your edits first, otherwise the pull may refuse to run.

No local copy yet? Cloning the GitHub repository creates one, and Git sets the upstream for the default branch automatically.

Running the command and reading the result

Pull output is short when nothing changed and noisy when something did.

The command above names the remote called origin, which is just the label Git stores for the URL you cloned from.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

A fast-forward lists the changed files and moves your branch pointer. A merge opens an editor for the commit message when the histories had diverged. Errors simply stop the pull and print the reason, and the first line is usually enough to tell what went wrong.

Add --verbose to get detail from both the fetch and the merge step, or --quiet to silence both.

What Does git pull Do Compared With git fetch?

Behind the single command, git pull is really two operations. It runs git fetch and then integrates the fetched branch into your current branch.

Fetch on its own downloads commits and updates remote-tracking branches such as origin/main. Your checked-out files and your local branch stay exactly as they were.

CommandUpdatesTouches your filesBest use
git fetch originRemote-tracking branches, FETCH\_HEADNoSeeing what changed first
git pullRemote-tracking branches, then the current branchYesSyncing in one step
git fetch then git merge origin/mainSame result as a merge pullYes, at the merge stepReviewing commits before integrating

What fetch writes locally

Read-only copies like origin/main end up under refs/remotes/origin/. The fetched ref names and object IDs go into .git/FETCH_HEAD, which gets overwritten on every fetch unless you pass --append.

Looking to sharpen your Git skills? Branching, merging, rebasing, and everything else you need - including git rebase, git stash, and commit workflows - is on one page in the Git Cheat Sheet.

That split explains what git pull does when it fails. The fetch already succeeded, and only the integration step stopped.

When fetch and merge beats a single pull

Plain git pull is fine when you work alone on one branch, or when you have no local commits yet.

On a shared, busy branch, fetch first. Same goes for the case where you have local commits and want to see the incoming ones before they land, or you aren’t sure which integration mode applies.

Fetching without merging costs nothing. Run git log HEAD..origin/main afterward to list the commits a pull would bring.

How to Pull a Specific Branch or All Branches

Run git pull origin branch-name to merge that remote branch into the branch you are on. Pulling every branch is not a single command, because each local branch needs its own pull.

▶ GIT EXPLAINED

If you commit, branch, or merge code every day, it helps to know how Git came to be. This video covers how Linus Torvalds created Git in just 10 days after a license dispute and explains how its data model actually works.

Linus Torvalds Built Git in Days Out of Spite
Built in 10 Days Out of Spite. Git and its data model explained in plain language.

Pulling a named branch

The manual’s own example is git pull origin next. It merges the remote branch next into your current branch and updates origin/next on the way.

That detail catches people. Standing on main and pulling feature-x merges feature-x into main.

If you meant to update feature-x itself, switch first with git switch feature-x and then run git pull. And name only one remote branch per pull, since two names build an octopus merge.

Setting the upstream branch

A clone sets the upstream for the default branch. Checking out a remote-tracking branch creates the local branch and sets its upstream too.

For anything else, the first push does it: git push --set-upstream origin branch-name. With push.autoSetupRemote turned on, you can skip the flag.

The upstream branch lives in .git/config as a remote field and a merge field. A bare git pull reads both.

Pulling every branch

One command cannot do it.

Run git fetch origin to refresh every remote-tracking branch, then check out each local branch you care about and pull it.

With several remotes, git fetch --all covers all of them. git pull --all only passes that flag to the fetch step and still integrates just the current branch’s upstream.

Merge, Rebase or Fast-Forward Only: Which git pull Mode Fits?

If a pull should fail whenever the branches diverge, use fast-forward only. If both histories need to survive, merge. Rebase is for private branches that should end up in a straight line.

The git-scm manual (Git 2.56 documentation) covers --ff-only, --rebase, --no-rebase (merge) and --squash.

Tutorials often describe pull as fetch plus merge. The manual names --ff-only as the default when no reconcile method is set, so a diverged branch stops until you choose a mode.

ModeFlag and configOn divergenceHistory
Fast-forward only--ff-only, pull.ff=onlyStops with an errorLinear, untouched
Merge--no-rebase, pull.rebase=falseCreates a merge commitBoth lines kept
Rebase--rebase, pull.rebase=trueReplays local commits on topLinear, local commits rewritten

Fast-forward only

You get no surprise merge commits and no rewritten history. The catch is that the pull fails the moment local and remote commits diverge.

There’s one dated caveat. The Git 2.33.1 release notes (12 October 2021) fix a bug where git pull --ff-only rebased instead of stopping on non-descendant history. Check git --version on old machines.

Merge

Merge keeps every commit exactly as written. The merge commit records where the two lines joined, which is what git merge does on any branch.

It’s the safe choice for shared branches, and the full history stays intact. On a busy branch, though, frequent pulls multiply the merge commits and clutter git log.

Rebase

Rebase replays your local commits on top of the fetched ones. The manual flags rebase as potentially dangerous for history you already published, because the commits get new IDs.

The payoff is a straight-line history. The cost is a force-push if those commits were already on GitHub.

Setting the mode once

Set it globally so every pull behaves the same way.

  • git config --global pull.ff only for fast-forward only
  • git config --global pull.rebase false for merge
  • git config --global pull.rebase true for rebase

The manual also points to branch.name.rebase and branch.autoSetupRebase for per-branch control.

A workable rule is to rebase your own feature branches and use fast-forward only on shared ones like main. If you cannot say who else has pulled a branch, do not rebase it.

How to Authenticate a Pull Over HTTPS or SSH

HTTPS pulls need a personal access token in place of a password, while SSH pulls need a key pair whose public half sits on your GitHub account. GitHub Docs states that password-based authentication for Git has been removed.

MethodSetupCredentials kept inTypical failure
HTTPS with tokenCreate a token, paste it at the password promptCredential helper such as Git Credential ManagerRepeated prompts, rejected token
SSH keyGenerate a key pair, add the public keyssh-agent and passphrasePermission denied (publickey)
GitHub CLI logingh auth login, then gh auth setup-gitGitHub CLI credential storeGit still using another credential

HTTPS with a personal access token

Your GitHub username goes in the username prompt. At the password prompt, paste the token, never the account password.

Organizations that enforce SAML single sign-on require a classic personal access token to be authorized for that organization first. A credential helper stops the prompt from returning on every pull.

No token yet? Here is how to go about generating a personal access token on GitHub.

SSH with a key pair

Generate the key pair on your machine and upload only the public key. The private key stays local.

The setup itself is covered in a guide on adding your public SSH key to GitHub.

  1. Run ssh -T git@github.com. A working setup answers with “Hi USERNAME! You’ve successfully authenticated”.
  2. If it fails, run ssh -vT git@github.com and read the identity file lines.
  3. Run ssh-add -l -E sha256 to confirm the key is loaded in the agent.

Two traps are worth knowing, and both are documented. Every SSH remote must use the git user (git@github.com:USER/REPO.git), and keys generated without sudo are not the keys sudo git pull uses.

Switching a remote between HTTPS and SSH

One command changes the protocol.

git remote -v shows the current URL, and git remote set-url origin git@github.com:USER/REPO.git switches it to SSH.

HTTPS remotes work behind firewalls and proxies, and GitHub documents SSH over the HTTPS port for networks that block port 22.

Why git pull Fails and How to Fix It

Most failed pulls trace back to a merge conflict, divergent branches, unrelated histories, local changes in the way, or a rejected SSH key. The first line of Git’s error names which one you hit.

ErrorCauseFix
Automatic merge failed; fix conflicts and then commit the resultBoth sides edited the same linesEdit the markers, git add, commit
Need to specify how to reconcile divergent branchesLocal and remote both gained commitsPass --rebase, --no-rebase or --ff-only, or set pull.rebase
refusing to merge unrelated historiesNo common ancestor between the two historiesCheck git remote -v first
Your local changes would be overwritten by mergeUncommitted edits overlap incoming filesCommit or stash, then pull
Permission denied (publickey)GitHub rejected the SSH keyTest with ssh -T git@github.com

Resolving merge conflicts

  1. Run git status to list the conflicted files.
  2. Open each file and find the <<<<<<<, ======= and >>>>>>> markers.
  3. Keep the lines you want and delete the markers.
  4. Run git add on each file, then git commit or git merge --continue.

To back out instead, git merge --abort tries to restore the pre-pull state. The git-merge manual warns it can fail to rebuild changes that were uncommitted when the merge began.

GitHub’s guide to getting changes points to git merge --abort, which fits a merge pull. After a pull with rebase, the git-pull manual names git rebase --abort instead.

A fuller walkthrough covers resolving merge conflicts in Git file by file.

Pulling with uncommitted changes

Git refuses to pull when local edits overlap the files it must update.

It also aborts when the index differs from HEAD, so staged changes block a pull even if no files overlap.

The usual way out is git stash to shelve the edits, then git pull, then git stash pop to bring the edits back.

Knowing what git stash does to your working tree explains the last step. If pop hits conflicts, the stash entry stays in the list until you run git stash drop yourself.

Add --include-untracked to stash new files too. The --autostash pull flag does the same dance automatically, but the manual says to use it with care because the final stash application can conflict.

Divergent branches and unrelated histories

Divergent branches happen when you and a teammate each committed since the last sync. Pick a mode for that pull, or set it once in config and stop thinking about it.

Unrelated histories mean the two repositories share no common ancestor. Confirm the remote URL before anything else, because a wrong remote produces the same error.

The manual says --allow-unrelated-histories exists for the rare case of joining two projects that started independently. No config variable enables it by default, and none will be added.

When git pull is the wrong tool

On a detached HEAD there is no current branch to integrate into, so check out a branch first. With no remote configured, add one using git remote add origin URL and then pull.

And if you want to discard local commits, pull won’t do it, since it keeps them. Throwing them away takes a separate, destructive reset.

How to Pull From GitHub in GitHub Desktop and Visual Studio Code

In GitHub Desktop, click Fetch origin, then Pull origin. In Visual Studio Code, open the Source Control view, choose More Actions (…), and select Pull.

VS Code’s documentation states that the editor and command-line Git work on the same repository. You can switch between them mid-task without importing anything.

ToolPull actionMode controlBest for
Command linegit pull origin mainAny flag or configScripts, full control
GitHub DesktopFetch origin, then Pull originPull origin with rebase optionFewer commands to remember
Visual Studio CodeMore Actions, then PullSeparate Pull (Rebase) commandStaying inside the editor
GitHub CLIgh repo syncFast-forward unless --forceA fork synced from its parent

GitHub Desktop

  1. Select the local branch in the Current Branch drop-down.
  2. Click Fetch origin to check for commits on the remote branch.
  3. Click Pull origin or Pull origin with rebase.
  4. Resolve any conflicts in a text editor, the command line or another tool.

A pull only updates your local copy. GitHub receives nothing until you push, per GitHub Docs.

Newer to the app? A guide to using GitHub Desktop covers the rest of the daily workflow.

There are no commands to remember, and rebase is one click away. Conflicts, though, get resolved outside the app.

Visual Studio Code

Pull sits under More Actions in the Source Control view. It fetches and integrates, and uploads nothing.

Pull (Rebase) runs from the Command Palette and replays your local commits on top of the fetched ones. Sync Changes pulls first and then pushes, so use it only when you want both. If conflicts show up during the pull, it stops before the push.

The status bar shows incoming and outgoing commit counts against the upstream branch, so a reading of 2 outgoing and 1 incoming means one commit waits to be pulled.

Not signed in yet? Connecting VS Code to GitHub sets up the authentication the pull needs.

GitHub CLI

The GitHub CLI manual lists gh repo sync, not a pull command.

The command updates a destination repository from a source, and the source defaults to the parent of a fork. Run without an argument, it targets your local repository.

It fast-forwards by default. With --force it hard resets the branch to match the source, which throws away local commits on that branch.

Use gh repo sync for the default branch, or gh repo sync --branch v1 for another one.

A repository that is not a fork has no parent to sync from, so an ordinary clone still pulls with git pull.

When to Pull and How Often

Pull before you start work, before you push, and after a teammate merges into your base branch.

Starting from current code means conflicts surface early. A push gets rejected when the remote holds commits you lack, and VS Code’s documentation says not to force push past that rejection.

After a merged pull request, your base branch has moved and your feature branch has not noticed.

Small, frequent pulls keep each conflict small. One pull after days of local work stacks every overlap into a single session.

Your team’s Git workflow sets the real cadence. Long-lived branches need more pulls, not fewer.

The repository you view on GitHub.com is the remote itself, so nothing needs pulling there. Pulls apply to local clones.

VS Code can fetch in the background through git.autofetch, which is off by default in the editor window. The documented interval is 180 seconds, and automatic fetch never pulls or pushes.

Status bar counts reflect the last known remote state, so a stale count means a stale fetch.

git pull FAQ

How do I undo a git pull?

Run git reset --hard ORIG_HEAD right after a merge pull. Git records the branch tip in ORIG_HEAD before it merges, so the reset restores that commit.

The hard reset discards uncommitted changes, so stash them first. Run it before another merge overwrites ORIG_HEAD.

Is a pull request the same as git pull?

No. A pull request is a GitHub feature that asks maintainers to merge one branch into another after review, while git pull downloads commits into your local branch.

The names overlap, the operations do not.

How do I make git pull overwrite my local changes?

It will not, by design. To match GitHub exactly, run git fetch origin, then git reset --hard origin/main.

That discards local commits and uncommitted edits to tracked files. Stash or branch off anything you want to keep first.

How do I sync a fork with the original repository?

Add the original repository as a remote named upstream, then run git pull upstream main on your local main. That fetches and merges in one step.

Push the result to your fork afterward, since the pull only updates your local copy.

What to Do After git pull Succeeds

Push your local commits with git push once the branch is current, but inspect the integrated result first. A clean merge is not proof of a correct one.

The git-pull manual documents the reason. When a change landed on both branches and one side later reverted it, the three-way merge restores the change.

Compare with git log origin/main..HEAD and git diff origin/main, run the project’s test suite, and then run git push.

Tests come before the push because a pushed merge commit becomes shared history.

This advice was verified against the Git 2.56 documentation on 4 October 2026. Set pull.ff or pull.rebase explicitly, so a future change to the default mode cannot alter how your pulls behave.

The push side of the workflow has its own walkthrough on pushing commits to GitHub.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.