Make a local Git branch match origin—with a recovery path
Fetch the exact remote state, classify commits and uncommitted files, create rescue references, reset deliberately and verify the deployed tree.
“Force pull” is usually the wrong mental model. git pull fetches and then integrates; it is designed to preserve and combine histories, not declare the remote authoritative. If the operational requirement is “make this local branch and tracked working tree exactly match origin/main,” express those steps directly—and build recovery references first.
Confirm repository, branch and remote identity
git rev-parse --show-toplevel
git status --short --branch
git branch --show-current
git remote -v
git config --get branch.main.remote
git config --get branch.main.merge
Do not assume the branch is main or the authoritative remote is origin. On a deployment host, confirm you are in the intended release checkout and not a shared developer worktree.
Fetch without changing the working tree
git fetch --prune origin
git rev-parse --verify origin/main
git log --left-right --graph --oneline --decorate main...origin/main
fetch updates remote-tracking references. The left/right log makes local-only and remote-only commits visible before any branch moves.
Inventory everything reset will not summarize for you
git status --short
git diff --stat
git diff --cached --stat
git ls-files --others --exclude-standard
git submodule status --recursive
A hard reset discards tracked working-tree and index changes. It does not remove ordinary untracked files. Submodules and Git LFS introduce additional state that must be verified separately.
Create a durable recovery point
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
git branch "rescue/main-$stamp" main
git stash push --include-untracked -m "before aligning main to origin/main $stamp"
The rescue branch preserves local commits. The stash preserves tracked modifications, staged changes and untracked files. Ignored files are still excluded; use --all only after reviewing whether ignored build output or secrets would make the stash huge or unsafe.
Move the branch to the fetched remote tip
git switch main
git reset --hard origin/main
This moves main, resets the index, and restores tracked files to the remote-tracking commit. It does not contact the server, which is why the preceding fetch and verification matter.
Handle untracked files separately—and preview first
git clean -nd
git clean -ndX
The first previews untracked, non-ignored paths that git clean -fd would remove. The second previews ignored paths targeted by -X. Never turn a preview into deletion by reflex, especially on deployment hosts where runtime uploads, environment files or generated secrets may sit inside the repository.
If the deployment contract requires a pristine checkout, exclude persistent data from the release directory architecturally. Then, after approving the preview:
git clean -fd
Synchronize submodules and LFS only when the repository uses them
git submodule sync --recursive
git submodule update --init --recursive
git lfs pull
These commands can fetch additional content and change nested working trees. Run them as explicit deployment steps, not as unexplained additions to a generic repair command.
Verify repository state and the running artifact
test "$(git rev-parse main)" = "$(git rev-parse origin/main)"
git status --short --branch
git log -1 --format='%H %cI %s'
git diff --exit-code origin/main --
git diff --cached --exit-code origin/main --
A clean repository does not prove the service deployed successfully. Build or install dependencies through the project’s locked workflow, reload through the service manager, and test the external health and functional routes. Record the deployed commit hash.
Recover local work if the reset was a mistake
git switch -c recovered-work "rescue/main-$stamp"
git stash list
git stash show --stat stash@{0}
git stash apply stash@{0}
Use a separate recovery branch rather than moving main back immediately. Inspect and selectively restore the needed work, then delete the rescue branch and stash only after the recovery window closes.
Choose a less destructive operation when local commits matter
| Desired outcome | Operation |
|---|---|
| Integrate remote changes with local commits | git pull --rebase or fetch then reviewed rebase |
| Keep local changes temporarily | Stash, update, then apply |
| Make tracked state equal remote | Fetch, rescue, reset --hard |
| Remove untracked build debris | Review git clean -nd, then targeted clean |
Destructive synchronization is safe only when “remote is authoritative” is an explicit decision and every other class of local state has a named recovery path.
Sources: the solved Stack Overflow discussion (CC BY-SA), Git’s official fetch, reset, clean, and user manual.
Primary source: Review the official reference ↗