GIT:检出到特定文件夹


Answers:


57

按照是否进行“ git export”(例如“ svn export”)?

您可以git checkout-index为此使用,这是一个低级命令,如果要导出所有内容,可以使用-a

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

引用手册页:

最后的“ /”(在前缀上)很重要。导出的名称实际上只是以指定的字符串作为前缀。

如果要导出某个目录,则涉及一些技巧。该命令仅接收文件,而不接收目录。要将其应用于目录,请使用“ find”命令并将输出通过管道传递到git。

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

同样在手册页中:

直觉不是这里的目标。重复性是。


遗憾的是,即使使用--prefix设置,这也无法从裸露的git仓库中运行:-((使用git 1.9.1测试)
apeiros

1
如果您想签出裸git仓库的分支/提交,请使用GIT_WORK_TREE=../path/to/place git checkout
allicoder

4
git worktree(请参阅下文)imho是今天的规范答案,可能会在此处添加。
geek-merlin

213

另一个更干净的解决方案-只需指定其他工作树即可。

要检出从HEAD(不是索引)到特定out目录的所有内容,请执行以下操作:

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

要将子目录或文件从HEAD检出到特定目录,请执行以下操作:

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

4
次要说明-您确实需要绝对路径,因为不会发生shell波浪号扩展,--work-tree=/home/thomasg/okcopy而不是--work-tree=~/okcopy((坐在同一git树中也可以使用相对路径也可以,但是这种方式git status在R'lyehian中是疯狂和输出的)
Tom Goodfellow 2014年

10
它也可以与旧提交(如使用SHA代替HEAD)一起按预期工作,但是git status随后显示了很多mod(大概是因为索引现在与其他目录匹配,而不是未修改的常规工作树)。git reset恢复到良好状态。
汤姆·古德费罗

2
同样,这里git status显示了很多mod,git reset但无济于事。我不得不git checkout -f HEAD恢复我的仓库状态。
DUzun

11
仅供参考:您需要自己创建目录,否则会出现此错误:fatal: This operation must be run in a work tree
timaschew

13
这灾难性地修改了主要工作树的索引,这通常是不好的。正如@TomGoodfellow所建议的,git reset足以使主要的工作树恢复理智。要在任何SHA1,分支或标记处安全地导出存储库子目录而无需修改主工作树,请参阅Charles Bailey的 臭名昭著的git archive解决方案。同样,为了安全地同时签出多个分支,新的git worktree add子命令是您的朋友。
塞西尔·库里

25

对于单个文件:

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

2
+1并阐明“某些先前的提交”(而不是HEAD):它是指SHA1 ID可以通过轻松找到的gitk。如果我只需要将该文件“检出”到一个临时位置(即不还原),则可以使用show子命令:git show 82e54378856215ef96c5db1ff1160a741b5dcd70:MyProj/proguard/mapping.txt > myproj_mapping.txt
ef2011 2012年

19

上面的解决方案对我不起作用,因为我需要检查树的特定标记版本。cvs export顺便说一下,这就是应该使用的方式。 git checkout-index不使用tag参数,因为它从索引中检出文件。 git checkout <tag>无论工作树如何,索引都会改变,所以我需要重置原始树。对我有用的解决方案是克隆存储库。共享克隆速度非常快,并且不会占用太多空间。所述.git如果所需的目录可以被移除。

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

较新版本的git应该支持git clone --branch <tag>自动签出指定的标签:

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

3
git --work-tree=/path/to/outputdir checkout <tag> -- .没为你工作吗?
warvariuc

1
不,不是。原始工作目录中的实际文件未更改,但是暂存的版本丢失并被标记中的版本替换。如果暂存版本包含一组精心挑选的要提交的更改,则尤其糟糕。我不希望export命令触及索引,句号。
proski 2015年

19

如果您正在使用自己的功能,并且不想结帐回master,则可以运行:

cd ./myrepo

git worktree add ../myrepo_master master

git worktree remove ../myrepo_master

它将创建../myrepo_master带有master分支提交的目录,您可以在其中继续工作


1
最佳答案-简单,并且与git --work-tree=/path/to/outputdir checkout HEAD -- .对索引不执行任何操作不同,只需将所选分支复制到指定位置(添加.git文件)。
罗杰·迪克

我将如何撤消此更改?
Scott P.

@ ScottP.just删除myrepo_master目录
itsnikolay

1
撤消此操作是工作树的子命令:git worktree remove ../myrepo_master
Martijn

8

Adrian的回答是“致命的:此操作必须在工作树中运行”。以下是对我们有用的。

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

笔记:

  • --no-checkout 不要将任何内容签出到新的工作树中。
  • --detach 不要为新的工作树创建新的分支。
  • <some-ref>适用于任何ref,例如,适用于HEAD~1
  • 使用清理git worktree prune

+1评论如何清理-其他所有人都乐于将当前的仓库弄得一团糟。只有这一点没有副作用。
安德鲁·希尔

1

除了@hasen的答案。要列出要签出的文件,您可能要使用git ls-files而不是 find

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

感谢您正确使用-z!很高兴您提供了不易遭受某些类型的注入攻击的脚本。
ErikE

0

我定义了一个git别名来实现这一目的(在我发现这个问题之前)。

这是一个简短的bash函数,可保存当前路径,切换到git repo,进行检出并返回其开始位置。

git check开发〜/ my_project_git

例如,将检出develop分支到“〜/ my_project_git”目录中。

这是里面的别名代码~/.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"

0

我正在使用此别名来签出临时目录中的分支:

[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

用法:

git cot mybranch

然后,将您放入临时目录中的新Shell中,您可以在其中使用分支。您甚至可以在此目录中使用git命令。

完成后,删除目录并运行:

git worktree prune

在添加新的工作树之前,这也将自动在别名中完成。


0

用于git archive branch-index | tar -x -C your-folder-on-PC将分支克隆到另一个文件夹。我认为,那么您可以复制所需的任何文件

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.