Pull Remote Changes Safely with git pull
You will update the current Git branch from its configured upstream, while knowing whether Git will fast-forward, merge or rebase your work. The examples use Git 2.43.0 and the installed git-pull(1) manual. Allow 10 to 15 minutes for a routine pull, or longer if you need to resolve a conflict.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a cloned repository, a network connection to its remote, and a working branch with an upstream configured. These are ordinary user commands. Nothing here needs sudo; using elevated privileges can create root-owned files in your repository.
1. Check the repository before pulling
Change to the repository and inspect the current branch, upstream and working tree:
$ cd /path/to/repository
$ git status --short --branch
## main...origin/main
$ git remote -v
origin [email protected]:EXAMPLE/PROJECT.git (fetch)
origin [email protected]:EXAMPLE/PROJECT.git (push)
The first line should identify the branch you mean to update. A clean status has no extra lines below it. If you see modified, deleted or untracked files, stop and decide what to do with them before pulling. Commit work that belongs in history, or stash it deliberately with git stash push -u -m "before pull". Do not use a blind pull as a way to hide unfinished work.
Checkpoint
Run git branch -vv. It shows the upstream selected for each local branch. If the current branch has no upstream, an argument-less git pull cannot know which remote branch to integrate.
2. Preview the fetch without changing the branch
Fetch is the first half of pull. Use its dry-run option through git pull when you want to check the remote contact and see what would be fetched:
$ git pull --dry-run
From github.com:EXAMPLE/PROJECT
1a2b3c4..5d6e7f8 main -> origin/main
The precise output varies by server and by whether anything changed. --dry-run does not update your branch, but remote communication still occurs. If the remote is unavailable, fix the network, authentication or URL problem first. Check the configured URL with git remote get-url origin.
3. Choose the integration policy
For a branch that is only behind its upstream, the safest explicit choice is fast-forward only:
$ git pull --ff-only
Updating 1a2b3c4..5d6e7f8
Fast-forward
src/report.txt | 4 ++++
1 file changed, 4 insertions(+)
A fast-forward moves your branch pointer to the remote commit and creates no new commit. On Git 2.43.0, --ff-only is also the default when no other reconciliation method has been selected. It fails rather than inventing a merge when both sides have commits.
If your project deliberately uses merge commits, say so:
$ git pull --no-rebase
Merge made by the 'ort' strategy.
This may create a merge commit when the histories have diverged. If the project history is kept linear, rebase your local commits on top of the fetched branch instead:
$ git pull --rebase
Successfully rebased and updated refs/heads/main.
Rebase rewrites the IDs of local commits. Do not use it casually on commits already shared with other people. A repository can record a preference with pull.rebase or pull.ff, but inspect local configuration before trusting an unfamiliar checkout:
$ git config --show-origin --get-regexp '^(pull\.|branch\..*\.(remote|merge|rebase))$'
Command-line options apply to this pull only. That makes them easier to review when you are unsure what a repository configuration does.
4. Pull a named remote branch when needed
An ordinary pull uses the current branch's upstream. To integrate a particular branch explicitly, name the remote and refspec:
$ git pull --ff-only origin main
The refspec selects what to fetch and integrate into the current branch. This does not switch branches first. Confirm your destination with git branch --show-current; pulling origin/main while checked out on a feature branch updates that feature branch.
5. Protect an existing output before redirecting or merging
Pull changes repository history and files. Before accepting a merge, you can stop just before creating its merge commit:
$ git pull --no-rebase --no-commit
Automatic merge went well; stopped before committing as requested
This pause does not stop a fast-forward, because a fast-forward has no merge commit to delay. Use --no-ff --no-commit when you specifically need a review point before a merge commit. Inspect with git diff --cached and then run git commit, or abandon the staged merge with git merge --abort if Git reports a merge in progress.
For a one-off pull with local changes, --autostash creates a temporary stash and applies it after the operation. Treat this as a convenience, not a guarantee that the final application will be clean. The safer recovery is to stash and inspect the work yourself before pulling.
6. Recover when histories conflict
A fast-forward-only pull can fail with a message that the branches have diverged. That is a decision point, not permission to add a random option. Inspect both sides:
$ git log --oneline --graph --decorate --all -20
$ git status
If the project wants a merge, rerun with --no-rebase. If it wants a linear history and your local commits are not shared, rerun with --rebase. If a merge conflict starts and you do not want to resolve it, use:
$ git merge --abort
For a rebase conflict, use:
$ git rebase --abort
These commands return the operation to its pre-operation state as far as Git can. Check git status afterwards. Do not run git reset --hard as a first response: it discards uncommitted changes and is difficult to undo.
7. Verify the result
After a successful pull, check the branch and recent history:
$ git status --short --branch
## main...origin/main
$ git log -1 --oneline
5d6e7f8 Update report parser
$ git rev-list --left-right --count HEAD...@{upstream}
0 0
The final command should report zero commits unique to either side when the upstream is the branch you intended. Run the project's tests or build before publishing the result. A successful pull proves that Git integrated objects; it does not prove that the application still works.
Done means
- You checked the current branch, upstream and working tree before fetching.
- You selected
--ff-only,--no-rebaseor--rebasedeliberately. - Any local edits were committed, stashed or intentionally preserved.
- Conflicts were resolved or aborted with the matching Git command.
git status, the recent log and the upstream count confirm the intended result.