git checkout到外部工作树并删除已删除的文件 [英] Git checkout to external work tree and remove deleted files

查看:311
本文介绍了git checkout到外部工作树并删除已删除的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想使用Git在我们的Web服务器上部署代码.因此,我们在生产服务器上初始化了一个裸仓库.每当发布新版本时,我们都会在网站的DocumentRoot中执行git checkout:

We want to use Git to deploy code on our webserver. Therefore, we have a initialized a bare repository on our production server. Whenever we release a new version, we perform a git checkout into the DocumentRoot of the website:

git --work-tree=/path/to/webroot/ checkout -f master

webroot的子目录中,有一些文件未被Git跟踪(缓存文件,用户上传的文件等).当然,执行结帐时,这些绝对不能由Git删除(到目前为止,这一部分工作正常).

In the subdirectories of webroot, there are several files which are not tracked by Git (Cache files, user-uploaded files etc.). These must of course not be deleted by Git when performing the checkout (and this part works fine so far).

但是,Git也不会删除以前跟踪的文件,但同时已将其删除(例如,由于不再需要它们而在开发过程中将其删除了).这些文件当前在checkout进程中仍然存在,从而导致死"文件的数量稳定增长.有没有办法让Git在执行checkout时删除此类文件?

However, Git also does not delete files which were previously tracked, but have been removed in the meantime (e.g. they were deleted in the development process because they are no longer needed). Such files currently survive the checkout process, leading to a steadily increasing number of "dead" files. Is there a way to make Git delete such files when performing the checkout?

编辑-重现步骤:

# create dirs and repos
cd /base/path
mkdir repo.git
mkdir target
cd repo.git && git init

# create, add and commit two files
touch test1.txt
touch test2.txt
git add test1.txt test2.txt
git commit -m testcommit

# checkout to target directory
git --work-tree=../target checkout master -f
# target directory now contains both files

# remove one file from file system and git repo, commit
rm test2.txt
git rm test2.txt
git commit -m deletecommit

# checkout to target again
git --work-tree=../target checkout master -f
# target still contains both files

推荐答案

但是,Git不会删除以前跟踪的文件,但同时已将其删除

However, Git also does not delete files which were previously tracked, but have been removed in the meantime

是的,使用Git 2.22(2019年第二季度)和git checkout --overlay,确实如此.
"git checkout --no-overlay"可以用于触发一种从树状结构中检出路径的新模式,该模式允许在当前索引和工作树中且不在树状结构中的路径规范匹配路径.

Yes, with Git 2.22 (Q2 2019) and git checkout --overlay, it does.
"git checkout --no-overlay" can be used to trigger a new mode of checking out paths out of the tree-ish, that allows paths that match the pathspec that are in the current index and working tree and are not in the tree-ish.

请参见提交e92aa0e (2019年2月4日),提交091e04b (2019年1月8日)和提交b7033e7 提交5160fa0 提交536ec18 (2018年12月20日)通过 Thomas Gummerer(tgummerer).
推荐人:乔纳森·尼德(Jonathan Nieder,artagnon).
(由 Junio C Hamano-gitster-

See commit e92aa0e (04 Feb 2019), commit 1495ff7, commit 091e04b (08 Jan 2019), and commit b7033e7, commit 5160fa0, commit 6fdc205, commit 536ec18, commit b702dd1, commit a0cc584 (20 Dec 2018) by Thomas Gummerer (tgummerer).
Suggested-by: Jonathan Nieder (artagnon).
(Merged by Junio C Hamano -- gitster -- in commit 7d0c1f4, 07 Mar 2019)

checkout:引入--{,no-}overlay选项

checkout: introduce --{,no-}overlay option

当前'git checkout'被定义为叠加操作,它 表示如果在'git checkout <tree-ish> -- [<pathspec>]'中,我们有一个 与<pathspec>匹配的索引中的条目,但是在<pathspec>中不存在 <tree-ish>,该条目将不会从索引或 工作树.

Currently 'git checkout' is defined as an overlay operation, which means that if in 'git checkout <tree-ish> -- [<pathspec>]' we have an entry in the index that matches <pathspec>, but that doesn't exist in <tree-ish>, that entry will not be removed from the index or the working tree.

引入一个新的--{,no-}overlay选项,该选项允许在非覆盖模式下使用"git checkout",因此,如果在<tree-ish>中不存在但与<pathspec>匹配的文件从工作树中删除.

Introduce a new --{,no-}overlay option, which allows using 'git checkout' in non-overlay mode, thus removing files from the working tree if they do not exist in <tree-ish> but match <pathspec>.

请注意,'git checkout -p <tree-ish> -- [<pathspec>]'已经有效 这样,补丁模式无需更改.
我们禁止使用"git checkout --overlay -p",以免使期望的用户感到困惑 这样就可以在'git checkout -p'中强制叠加模式.

Note that 'git checkout -p <tree-ish> -- [<pathspec>]' already works this way, so no changes are needed for the patch mode.
We disallow 'git checkout --overlay -p' to avoid confusing users who would expect to be able to force overlay mode in 'git checkout -p' this way.

未跟踪的文件不受此更改的影响,因此'git checkout --no-overhead HEAD-untracked'不会从工作树中删除未跟踪的文件.
例如'git checkout --no-overlay HEAD -- dir/'不会删除dir/中的所有未跟踪文件,而只是重置git已知文件的状态.

Untracked files are not affected by this change, so 'git checkout --no-overlay HEAD -- untracked' will not remove untracked from the working tree.
This is so e.g. 'git checkout --no-overlay HEAD -- dir/' doesn't delete all untracked files in dir/, but rather just resets the state of files that are known to git.

您有一个设置:

checkout.overlayMode:

在默认覆盖模式下,git checkout永远不会从索引或工作树中删除文件.
checkout.overlayMode设置为false时,将删除出现在索引和工作树中但未出现在<tree-ish>中的文件,以使其与<tree-ish>完全匹配.

In the default overlay mode, git checkout never removes files from the index or the working tree.
When setting checkout.overlayMode to false, files that appear in the index and working tree, but not in <tree-ish> are removed, to make them match <tree-ish> exactly.


" git restore/checkout --no-overlay"通配符pathspec错误地删除了子目录中的匹配路径,该问题已在Git 2.29(2020年第四季度)中得到纠正.


"`git restore/checkout --no-overlay" with wildcarded pathspec mistakenly removed matching paths in subdirectories, which has been corrected with Git 2.29 (Q4 2020).

请参见提交bfda204 (2020年8月22日)通过 Junio C Hamano-gitster-

See commit bfda204 (22 Aug 2020) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit c57afd7, 31 Aug 2020)

checkout, restore :使pathspec递归

举报人:Sergii Shkarnikov
初始测试者:Sergii Shkarnikov
帮助人:杰夫·金
签名人:RenéScharfe

checkout, restore: make pathspec recursive

Reported-by: Sergii Shkarnikov
Initial-test-by: Sergii Shkarnikov
Helped-by: Jeff King
Signed-off-by: René Scharfe

git checkout git restore ( man )并与都是tree_entry_interesting(通过read_tree_recursive)match_pathspec(通过ce_path_match).

The pathspec given to git checkout and git restore(man) and is used with both tree_entry_interesting (via read_tree_recursive) and match_pathspec (via ce_path_match).

后者有效地仅支持递归匹配,而与pathspec标志"recursive"的值无关(在此未设置).

The latter effectively only supports recursive matching regardless of the value of the pathspec flag "recursive", which is unset here.

这会导致带有通配符的路径规范的匹配结果不同,并且可能导致签出并以无覆盖模式进行还原以删除条目,而不是对其进行修改.

That causes different match results for pathspecs with wildcards, and can lead checkout and restore in no-overlay mode to remove entries instead of modifying them.

为检出和还原启用递归匹配,以使匹配保持一致.

Enable recursive matching for both checkout and restore to make matching consistent.

从技术上在checkout_main()中设置标记也会影响 git switch ( man ),但是因为该命令根本不接受路径规范,所以这没有实际结果.

Setting the flag in checkout_main() technically also affects git switch(man), but since that command doesn't accept pathspecs at all this has no actual consequence.

这篇关于git checkout到外部工作树并删除已删除的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆