You can copy a single file or an entire folder from another Git branch without
switching to that branch or merging it. Modern versions of Git provide
git restore for this purpose.
Suppose you want to copy a file from feature-branch into main. First, switch
to the branch that should receive the file:
git switch mainThen restore the file from the source branch:
git restore --source feature-branch -- src/js/some-file.jsThe -- separates the branch name from the path. It prevents ambiguity if a
branch and a file have the same name. The command overwrites uncommitted changes
to the selected path, so commit or stash anything you want to keep first.
By default, git restore updates only the working tree, so you can review the
change before staging it:
git status --short
git diff -- src/js/some-file.js
git add src/js/some-file.js
git diff --staged -- src/js/some-file.js
git commit -m "Restore file from feature branch"If the file is new to main, it appears as untracked in git status and does
not appear in git diff until you stage it. The staged diff therefore provides
the final review in both cases.
To restore an entire folder, pass the folder path instead:
git restore --source feature-branch -- src/js/
git diff -- src/js/
git add src/js/
git commit -m "Restore JavaScript files from feature branch"Restoring a folder makes its tracked contents match the source branch. That can
also remove tracked files that exist on main but not on feature-branch, so
review the diff carefully.
You can also use a commit hash or tag in place of feature-branch. This copies
the selected paths as they existed at that revision; it does not merge the
branch or preserve the copied changes as a separate piece of history.
Using git checkout on older Git versions
Git versions older than 2.23 do not have git restore. The older equivalent is:
git checkout main
git checkout feature-branch -- src/js/some-file.jsUnlike the git restore example above, this form updates both the working tree
and the index, so the file is staged immediately. Review the staged change with
git diff --staged before committing it.