'GIT: Checkout to a specific folder

I want to use something similar to:

git checkout -- <path>/<file>

but I want to checkout the file to some folder I choose, rather than the overwriting the local <path>/<file>.

Any idea?

git


Solution 1:[1]

As per Do a "git export" (like "svn export")?

You can use git checkout-index for that, this is a low level command, if you want to export everything, you can use -a,

git checkout-index -a -f --prefix=/destination/path/

To quote the man pages:

The final "/" [on the prefix] is important. The exported name is literally just prefixed with the specified string.

If you want to export a certain directory, there are some tricks involved. The command only takes files, not directories. To apply it to directories, use the 'find' command and pipe the output to git.

find dirname -print0 | git checkout-index --prefix=/path-to/dest/ -f -z --stdin

Also from the man pages:

Intuitiveness is not the goal here. Repeatability is.

Solution 2:[2]

Another solution which is a bit cleaner - just specify a different work tree.

To checkout everything from your HEAD (not index) to a specific out directory:

git --work-tree=/path/to/outputdir checkout HEAD -- .

To checkout a subdirectory or file from your HEAD to a specific directory:

git --work-tree=/path/to/outputdir checkout HEAD -- subdirname

Solution 3:[3]

If you're working under your feature and don't want to checkout back to master, you can run:

cd ./myrepo

git worktree add ../myrepo_master master

git worktree remove ../myrepo_master

It will create ../myrepo_master directory with master branch commits, where you can continue work

Solution 4:[4]

For a single file:

git show HEAD:abspath/to/file > file.copy

Solution 5:[5]

The above solutions didn't work for me because I needed to check out a specific tagged version of the tree. That's how cvs export is meant to be used, by the way. git checkout-index doesn't take the tag argument, as it checks out files from index. git checkout <tag> would change the index regardless of the work tree, so I would need to reset the original tree. The solution that worked for me was to clone the repository. Shared clone is quite fast and doesn't take much extra space. The .git directory can be removed if desired.

git clone --shared --no-checkout <repository> <destination>
cd <destination>
git checkout <tag>
rm -rf .git

Newer versions of git should support git clone --branch <tag> to check out the specified tag automatically:

git clone --shared --branch <tag> <repository> <destination>
rm -rf <destination>/.git

Solution 6:[6]

Adrian's answer threw "fatal: This operation must be run in a work tree." The following is what worked for us.

git worktree add <new-dir> --no-checkout --detach
cd <new-dir>
git checkout <some-ref> -- <existing-dir>

Notes:

  • --no-checkout Do not checkout anything into the new worktree.
  • --detach Do not create a new branch for the new worktree.
  • <some-ref> works with any ref, for instance, it works with HEAD~1.
  • Cleanup with git worktree prune.

Solution 7:[7]

Use git archive branch-index | tar -x -C your-folder-on-PC to clone a branch to another folder. I think, then you can copy any file that you need

Solution 8:[8]

Addition to @hasen's answer. You might want to use git ls-files instead of find to list files to checkout like:

git ls-files -z *.txt | git checkout-index --prefix=/path-to/dest/ -f -z --stdin

git ls-files ignores uncommitted files.

Solution 9:[9]

I'm using this alias for checking out a branch in a temporary directory:

[alias]
    cot = "!TEMP=$(mktemp -d); f() { git worktree prune && git worktree add $TEMP $1 && zsh -c \"cd $TEMP; zsh\";}; f" # checkout branch in temporary directory

Usage:

git cot mybranch

You are then dropped in a new shell in the temporary directory where you can work on the branch. You can even use git commands in this directory.

When you're done, delete the directory and run:

git worktree prune

This is also done automatically in the alias, before adding a new worktree.

Solution 10:[10]

I defined an git alias to achieve just this (before I found this question).

It's a short bash function which saves the current path, switch to the git repo, does a checkout and return where it started.

git checkto develop ~/my_project_git

This e.g. would checkout the develop branch into "~/my_project_git" directory.

This is the alias code inside ~/.gitconfig:

[alias]
    checkTo = "!f(){ [ -z \"$1\" ] && echo \"Need to specify branch.\" && \
               exit 1; [ -z \"$2\" ] && echo \"Need to specify target\
               dir\" && exit 2; cDir=\"$(pwd)\"; cd \"$2\"; \
               git checkout \"$1\"; cd \"$cDir\"; };f"

Solution 11:[11]

If you are working in mydir, why not simply cp -r mydir mydir2 and then cd mydir2; git checkout commit#

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Adrian Macneil
Solution 3
Solution 4 Tobu
Solution 5
Solution 6
Solution 7 dqthe
Solution 8
Solution 9 Felix Dietze
Solution 10 cb0
Solution 11 user0