The merge had failed. Files hung in limbo between branches, half-written, half-merged, half-dead. You need them fixed fast, without breaking the working directory, without wasting the day.
Git checkout moves you between branches or commits. rsync moves files between places. Together, they solve a specific pain: pulling only the files you need from another branch or commit, without switching fully, without poisoning your current changes.
Why git checkout and rsync work well together
Switching branches in Git rewrites your working directory. It’s fast, but dangerous when you have local edits you can’t stash or commit yet. Rsync copies files directly from the .git worktree or another location, merging them into your current directory. No branch switch, no full checkout, no overwrite unless you choose.
Common workflow
- Identify the source commit, branch, or tag:
git checkout some-branch -- path/to/file
This pulls the file directly, but if you need multiple files, spanning directories, it’s tedious.
- Use rsync with a temporary checkout:
TMP_DIR=$(mktemp -d)
git --work-tree="$TMP_DIR"checkout some-branch -- .
rsync -av --progress "$TMP_DIR/".
rm -rf "$TMP_DIR"
This method lets you bring over everything (or filter selectively) without touching the Git HEAD.
- Add
--ignore-existing to rsync to avoid overwriting files you want untouched:
rsync -av --ignore-existing "$TMP_DIR/".
Benefits of combining Git checkout and rsync
- Safety: Keep uncommitted changes intact.
- Speed: Avoid branch switch overhead.
- Granularity: Sync only needed files.
- Automation: Scriptable for CI/CD or build pipelines.
Best practices
- Always use a temporary work tree to protect the main repo state.
- Use Git’s pathspec filters to limit what is checked out.
- Use rsync’s flags (
--update, --ignore-existing, --delete) intentionally; they are powerful and irreversible. - Test the rsync command with
--dry-run before executing.
When to avoid this approach
- If you need Git history for merged files — rsync copies only the file contents, not commit data.
- If working with large binary files dependent on exact Git states — a full branch checkout may be safer.
This method is lean and surgical. It moves code without touching branches. It keeps your tree clean, your work safe, and your changes flowing. Test it once, and you’ll never go back to blind checkouts.
See this approach live in minutes with hoop.dev — spin up a repo, run the flow, and watch clean file syncing happen without risking your local state.