Before you type anything, work out which way the commits need to travel. Pushing sends your local commits up to GitHub. Pulling goes the other way and brings remote commits into your clone. On a fork, the Sync fork button handles commits that landed in the original repository.
Git does the first two, and GitHub only stores the remote copy. The Git manual sets fast-forward only as the default for git pull, so a pull on a diverged branch fails until you pick a merge or a rebase.
Pushes authenticate with a personal access token or SSH key, because GitHub stopped accepting account passwords for Git operations on August 13, 2021 (GitHub changelog).
Which method updates a GitHub repository in your situation?
Direction settles it. Git moves the commits and GitHub holds the remote copy, which is worth remembering when an error shows up. Knowing how Git differs from GitHub makes the messages easier to read, since every one below comes from Git.
| Method | Direction | Main tools | Fails when |
|---|---|---|---|
| Push | Local to GitHub | Git, GitHub Desktop, VS Code | Remote has commits you lack |
| Pull | GitHub to local | Git, GitHub Desktop | Local edits overlap incoming changes |
| Sync fork | Original to your fork | Sync fork button, GitHub CLI, Git | Upstream changes conflict with yours |
| Web editor | Browser to GitHub | GitHub file editor | Target branch is protected |
Run git status before choosing anything. Ahead of the remote means push. Behind means pull. A diverged branch needs a pull first and a push afterward.
Your clone tracks a remote repository named origin by default, and git status compares against what that remote looked like at your last fetch. So run git fetch first. Otherwise a branch that is behind can still read as up to date.
How to push local changes to GitHub

You stage, commit, and push, in that order. GitHub Docs gives git push origin main as the usual form for the default branch.
- Run git status to see modified files and whether the branch is behind its remote
- Stage the files with git add FILE (or git add . for everything in the folder)
- Commit with git commit -m “short message”
- Push with git push origin main
- Open the repository on GitHub and confirm the commit shows in the history
Stage and commit changes
git add FILE picks which edits go into the next commit. Everything else stays in the working directory, untouched.
The staging area is what lets you commit a bug fix without dragging along half-finished work from another file.
Keep the commit message to one line that says what changed. “Fix broken link in README” beats “updates” every time.
Push to the default branch or a feature branch
Push takes two arguments, a remote name and a branch name (GitHub Docs). For the default branch that gives you git push origin main.
If the branch already has tracking set, a plain git push is enough.
A new feature branch needs git push –set-upstream origin feature-name, which records the upstream so later pushes need no arguments. The Git manual adds that the push.autoSetupRemote setting makes Git do this on the first push.
From then on, a plain git push sends new commits to the same remote branch.
It breaks when the remote branch holds commits your clone lacks. GitHub Docs calls this a non-fast-forward rejection and says to fetch the upstream changes before pushing again.
How to pull the latest changes into a local clone
Run git pull from the branch you want to update. Git fetches the new commits from the remote and then integrates them into the current branch.
The integration step has a default that catches people out. The Git 2.56 manual names fast-forward only as the behavior when no method is set, so a diverged branch makes the pull fail instead of quietly merging.
- git pull –ff-only updates by fast-forward and fails on a diverged branch
- git pull –rebase replays your local commits on top of the fetched ones
- With git pull –no-rebase you get a merge, including a merge commit when the histories split
Set pull.rebase once in your Git config if you want the same behavior everywhere.
Rebase rewrites your local commits. That’s fine for ones you haven’t pushed, and GitHub Docs advises against rebasing commits already pushed.
Fetch versus pull
Fetch downloads. Pull downloads and integrates.
Fetching first lets you read the incoming commits with git log origin/main before they touch your branch. What git fetch does stops at updating remote-tracking branches, so none of your working files change.
When local changes block the pull
A pull stops when uncommitted edits overlap incoming changes, because Git refuses to overwrite them. The Git manual’s own example shows the standard fix. To keep your edits, run git stash, then git pull, then git stash pop.
What git stash saves is limited by default. Untracked files stay behind unless you add -u, and if stash pop hits conflicts, Git keeps the stash entry until you resolve them and drop it.
git pull –autostash runs the stash and the pop in one command. The manual warns that the final reapply can still produce conflicts.
To discard your edits instead, run git fetch origin and then git reset –hard origin/main. Uncommitted changes to tracked files cannot be recovered afterward, and local commits the remote lacks are dropped from the branch.
If a pull starts a merge or rebase you do not want to finish, git merge –abort or git rebase –abort puts the branch back where it was (Git manual).
How to sync a fork with its upstream repository
Use the Sync fork button when the fork has no conflicting changes, and the upstream remote on the command line when you want control. GitHub Docs says people with write access to the fork can sync it.
Forks don’t update themselves. A fork on GitHub is its own copy of the original repository, so it falls behind the moment the original gets a new commit.
| Method | Pros | Cons |
|---|---|---|
| Sync fork button | No local setup | Conflicts send you to a pull request |
| gh repo sync | One command, scriptable | Cannot sync when conflicts exist, unless –force overwrites the branch |
| Command line | Conflicts resolved locally | Upstream remote needed first |
Sync fork button on GitHub
Open the fork’s main page and select the Sync fork dropdown above the list of files.
The button updates the fork on GitHub only. Pull the branch into your clone afterward, or your local copy stays behind.
When there’s a conflict, GitHub prompts you to create a pull request to resolve it.
GitHub CLI
One command updates a fork from its parent:
gh repo sync owner/cli-fork -b BRANCH-NAMEIt fails when upstream changes conflict with yours. GitHub Docs says the –force flag overwrites the destination branch, and the CLI manual describes that as a hard reset, so any commits that exist only on your fork’s branch are lost. Use it only when you mean to discard them. To keep your own changes, switch to the web prompt or the command line.
Upstream remote on the command line
This route needs the upstream remote configured once per clone. Step 1 below is that one-time setup, and everything after it is the update itself.
- git remote add upstream THEIR\_REMOTE\_URL (first time only)
- git fetch upstream
- git checkout main
- git merge upstream/main
- git push origin main
The last step matters. GitHub Docs states that syncing from the command line updates only your local copy until you push it to your fork on GitHub.com.
Merge conflicts surface at the merge step. Resolve them locally, commit, then push.
How to update a repository without the command line
GitHub Desktop, VS Code, and the web editor all run the same Git operations the terminal does. The web editor suits a quick single-file fix, and a desktop client makes more sense once a local clone is involved.
The VS Code documentation states that the editor and command-line Git work on the same repository, so switching between them needs no import or sync step.
Edit and commit in the browser
Browse to the file and click the pencil icon in the file header. The Preview tab shows the change before you commit it. On the default branch, GitHub Docs recommends committing to a new branch and opening a pull request.
Editing a file in someone else’s repository forks it automatically and opens a pull request for you.
If the branch is protected, the editor refuses the commit. GitHub Docs points to GitHub Desktop for moving the change onto a new branch.
GitHub Desktop
Select the branch in the Current Branch dropdown first, then use the repository bar. Fetch origin checks the remote branch for new commits, and Pull origin brings them into the current branch. Pull origin with rebase does the same with your commits replayed on top. Push origin sends your commits to GitHub.
After a rebase, the push button turns into Force push origin (GitHub Docs). A walkthrough of GitHub Desktop covers the rest of the interface.
Visual Studio Code
Open the Source Control view with Ctrl+Shift+G, stage and commit, then use the sync action in the Status Bar.
Sync pulls first and pushes second, per the VS Code documentation, so a branch that is behind gets updated before the push is attempted.
VS Code uses the Git installation on your machine, so Git must be installed and your name and email configured before the first commit. Connecting VS Code to your GitHub account covers the sign-in side.
Creating or reviewing pull requests needs the GitHub Pull Requests and Issues extension. Plain pushing does not.
Fixing “authentication failed” when you push
GitHub stopped accepting account passwords for Git operations on August 13, 2021, according to its changelog. A password in the prompt fails, so the remote needs a personal access token over HTTPS or an SSH key.
An HTTPS remote takes the token in the password prompt. An SSH remote takes a key pair, with the public half added to your GitHub account.
Check which remote URL you use
Run git remote -v. An address starting with https:// takes a token, and one starting with git@github.com: takes an SSH key.
GitHub Docs says you can only push to those two URL types. Change a remote’s address with git remote set-url.
Switch to a token or an SSH key
On an HTTPS remote, Git asks for your GitHub username and password, and the token goes in the password field. Creating a GitHub personal access token comes first.
A credential helper such as Git Credential Manager remembers the token afterward, so the prompt does not return on every push.
On SSH, generate a key pair, add the public key to your account, and point the remote at the git@github.com: form. The steps for adding an SSH key to GitHub cover the details.
When the credentials are correct and the push still fails
If your organization uses SAML single sign-on, authorize the classic token or SSH key for that organization first. And if port 22 is blocked, GitHub Docs describes running SSH over the HTTPS port.
Why GitHub rejects an update and how to fix it
GitHub rejects an update when the branch is behind the remote, when your changes conflict with the remote’s, or when a rule on the branch blocks the push. The fix differs each time, and the error text tells you which one you hit.
Non-fast-forward rejection
Read the status word first.
A plain “rejected” means Git never sent the update, usually because it is not a fast-forward and you did not force it. “Remote rejected” means the server refused it, typically through a hook or a setting such as receive.denyNonFastForwards (Git manual).
For a plain rejection, integrate first. git pull creates a merge commit that joins both histories, while git pull –rebase places your commits on top of the remote ones.
Either way, the next push fast-forwards, according to the Git manual.
A solo developer can hit this too. Amend a commit you already pushed and the new commit no longer descends from the old one, so the push is refused.
Merge conflicts
Conflicts appear when two changes touch the same lines, or when one side edits a file the other deleted (GitHub Docs).
- Run git status to list the unmerged paths
- Open each file and find the <<<<<<< marker, where the HEAD side sits above ======= and the other branch’s side below it, closed by >>>>>>>
- Delete the three markers and keep the lines you want
- Stage the file with git add, then run git commit
- Push the result
For a file deleted on one side, git status shows “deleted by us” or “deleted by them”. Choose git add to keep the file or git rm to remove it.
GitHub also offers a conflict editor for competing line changes inside a pull request. A longer guide to resolving merge conflicts in Git covers the same loop in more depth.
Force push and when it destroys work
The Git manual reserves a force push for the case where you mean to lose history, such as replacing a commit you amended or rebased after publishing it.
| Option | What it checks | Weak point |
|---|---|---|
| –force | Nothing | Can delete remote commits, including teammates’ work |
| –force-with-lease | Remote still matches your remote-tracking branch | A background fetch refreshes that reference and defeats the check |
| –force-with-lease plus –force-if-includes | Fetched remote commits are integrated locally | A no-op without –force-with-lease, or when –force-with-lease names an expected commit |
GitHub blocks force pushes on protected branches by default. Where a repository enables them, GitHub Docs warns that commits teammates built on can vanish from the branch history, causing merge conflicts and corrupted pull requests.
Branch protection and pull requests
A branch protection rule disables force pushes and deletion on matching branches by default (GitHub Docs). Required reviews mean changes reach the branch only through an approved pull request, and required status checks have to pass before changes land. Admins are exempt by default, unless “Do not allow bypassing” is enabled.
Look for GH006 in the output. GitHub Docs shows “Protected branch update failed” under that code, which points at a rule rather than at your history.
The fix is a feature branch and a pull request. Opening a pull request on GitHub routes the same commits through the review gate.
Branch protection covers public repositories on GitHub Free, and public and private repositories on Pro, Team, and Enterprise plans (GitHub Docs).
Separately, GitHub’s push protection blocks pushes that contain a supported secret. Remove the secret from your commits or follow the URL in the error to see the bypass options.
FAQ About Updating a GitHub Repository
How can I tell that an update reached GitHub?
Open the repository on GitHub and check that your commit tops the commit history.
Locally, git status reports the branch as up to date with origin/main once the push succeeds.
How do I update the original repository from my fork?
Push your changes to the fork, then open a pull request against the original repository.
A direct push to the original needs write access, which outside contributors usually lack.
What is the difference between origin and upstream?
Your clone calls the remote it came from origin by default, which is usually your own repository on GitHub. A second remote that points at the original repository of a fork is conventionally named upstream.
Run git remote -v to list both.
Can I update one branch from another branch?
Yes. Check out the branch you want to update, run git merge OTHER-BRANCH, then push.
GitHub Desktop offers the same route through “Choose a branch to merge into BRANCH”, followed by Push origin.
Why does Git say “refusing to merge unrelated histories”?
The two histories share no common ancestor, which happens when repositories started independently, such as a local git init and a GitHub repository with its own first commit.
The Git manual provides –allow-unrelated-histories to override the check.
Do large files cause a push to fail?
They can. GitHub enforces a 2 GiB limit on a single push, and GitHub Docs has a dedicated troubleshooting page for it.
Git LFS keeps large files out of regular Git history.
What to Check Before Each Update
A rejected push usually traces back to skipping something in a short routine, and the order matters. The working tree should be clean, the remote-tracking branch current, and the pull method should match the target branch’s rules.
- Commit or stash local edits
- Fetch, then pull
- Push to a branch the rules allow
Each step feeds the next. A clean tree lets the pull run, and a finished pull lets the push fast-forward.
The pull method is where branch rules bite. A branch that requires linear history rejects merge commits (GitHub Docs), so git pull –rebase fits there, while a merge-style pull suits branches without that rule.
Rebase keeps history linear but gives your unpushed commits new hashes. Merge keeps them intact at the cost of merge commits.
Verified against the Git 2.56 manual and GitHub Docs on October 4, 2026. Recheck the pull default and branch rules after upgrading Git.
Teams that settle these choices once can write them into a shared Git workflow, so every contributor updates the repository the same way.
- Show Hidden Characters, Spaces, and Line Endings in Notepad++ - October 19, 2026
- Military and Defense UI/UX Design Services Firms to Know in 2026 - October 19, 2026
- How to Manage Your Google Play Subscriptions - October 17, 2026




