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?
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?
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 --work-tree=/home/thomasg/okcopy rather than --work-tree=~/okcopy (possibly using a relative path while sitting inside the same git tree works too, but that way lies madness and git status outputs in R'lyehian)git status then shows a lot of mods (presumably because the index now matches the other directory and not the untouched normal work tree). git reset got it back to a good state.git status shows a lot of mods, and git reset doesn't help. I had to git checkout -f HEAD to restore the state of my repo.fatal: This operation must be run in a work treegit reset suffices to restore the main working tree to sanity. To safely export repository subdirectories at any SHA1, branch, or tag without modifying the main working tree, see Charles Bailey's infamous git archive solution. Likewise, to safely checkout multiple branches at the same time, the new git worktree add subcommand is your friend.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.
GIT_WORK_TREE=../path/to/place git checkoutgit worktree (see below) imho is the canonical answer today and might be added here.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
git --work-tree=/path/to/outputdir checkout HEAD -- . it doesn't do anything to the index, just copies the selected branch to the specified location (with the addition of a .git file).myrepo_master directorygit worktree remove ../myrepo_masterFor a single file:
git show HEAD:abspath/to/file > file.copy SHA1 ID that can easily be found via gitk. If I only need to "checkout" that file to a temporary location (i.e. not reverting), then I would use the show subcommand: git show 82e54378856215ef96c5db1ff1160a741b5dcd70:MyProj/proguard/mapping.txt > myproj_mapping.txtThe 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 git --work-tree=/path/to/outputdir checkout <tag> -- . didn't work for you?.git/config before git checkout to do autocrlf (and possible other) content changes like the source worktree does.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.git worktree prune. 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
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.
-z! Nice that you provide script that's not vulnerable to certain kinds of injection attacks.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.
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" If you are working in mydir, why not simply cp -r mydir mydir2 and then cd mydir2; git checkout commit#