更新注册 :使用 Git 2.23(2019 年 8 月),有一个新命令git restore可以执行此操作,请参阅接受的答案。 更新 :从 Git 1.8.3 开始,这将更直观地工作,请参阅我自己的答案。
更新注册 :使用 Git 2.23(2019 年 8 月),有一个新命令git restore可以执行此操作,请参阅接受的答案。
git restore
更新 :从 Git 1.8.3 开始,这将更直观地工作,请参阅我自己的答案。
想象一下以下用例:我想删除 Git 工作树的特定子目录中的所有更改,而保留所有其他子目录不变。
我可以git checkout .,但是git checkout 。添加稀疏结帐排除的目录
git checkout .
有git reset --hard,但它不会让我为子目录这样做:
git reset --hard
> git reset --hard .
fatal: Cannot do hard reset with paths.
再次:为什么 git 不能通过路径进行硬/软重置?
git diff subdir | patch -p1 -R
此操作的正确 Git 命令是什么?
下面的脚本说明了这个问题。在注释下方插入正确的命令How to make files——当前命令将恢复a/c/ac应该被稀疏检出排除的文件。请注意,我 不想 显式恢复a/aand a/b,我只“知道”a并想恢复下面的所有内容。 编辑 :而且我也不“知道” b,或者哪些其他目录与a.
How to make files
a/c/ac
a/a
a/b
a
b
#!/bin/sh rm -rf repo; git init repo; cd repo for f in a b; do for g in a b c; do mkdir -p $f/$g touch $f/$g/$f$g git add $f/$g git commit -m "added $f/$g" done done git config core.sparsecheckout true echo a/a > .git/info/sparse-checkout echo a/b >> .git/info/sparse-checkout echo b/a >> .git/info/sparse-checkout git read-tree -m -u HEAD echo "After read-tree:" find * -type f rm a/a/aa rm a/b/ab echo >> b/a/ba echo "After modifying:" find * -type f git status # How to make files a/* reappear without changing b and without recreating a/c? git checkout -- a echo "After checkout:" git status find * -type f
使用 Git 2.23(2019 年 8 月),您将拥有新命令gitrestore
gitrestore
git restore --source=HEAD --staged --worktree -- aDirectory # or, shorter git restore -s@ -SW -- aDirectory
这将用内容替换索引和工作树HEAD,就像reset --hard一个特定的路径一样。
HEAD
reset --hard
原始答案(2013)
请注意(如Dan Fabulich所评论):
git checkout -- <path>
git checkout HEAD -- <path>
正如Ajedi32回答的那样,两种结帐表格都不会删除在目标修订中删除的文件** 。 如果工作树中有 HEAD 中不存在的额外文件,则不会删除它们。 git checkout HEAD --<path>
git checkout HEAD --<path>
注意:使用[git checkout --overlay HEAD -- <path>(Git 2.22, Q12019),会删除出现在索引和工作树中但不在其中的<tree-ish>文件,以使它们<tree-ish>完全匹配。
git checkout --overlay HEAD -- <path>
<tree-ish>
但是该结帐可以尊重 a git update-index --skip-worktree(对于您想要忽略的那些目录)
git update-index --skip-worktree