# Git: restore files or folders from another branch

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:

```shell
git switch main
```

Then restore the file from the source branch:

```shell
git restore --source feature-branch -- src/js/some-file.js
```

The `--` 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:

```shell
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:

```shell
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:

```shell
git checkout main
git checkout feature-branch -- src/js/some-file.js
```

Unlike 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.
