Git结帐到外部工作树并删除已删除的文件

问题描述 投票:4回答:3

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

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

webroot的子目录中,有几个文件没有被Git跟踪(缓存文件,用户上传的文件等)。当然,这些必须在执行结账时不被Git删除(到目前为止这部分工作正常)。

但是,Git也不删除以前跟踪过的文件,但同时也删除了这些文件(例如,它们在开发过程中被删除,因为它们不再需要)。这些文件目前在checkout进程中存活,导致“死”文件数量稳步增加。有没有办法让Git在执行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 dvcs git-checkout
3个回答
2
投票

通过对一些工作使用一个工作目录,然后对其余工作使用另一个工作目录,您将使它们与存储库的其余部分不同步。 Git似乎并不打算以这种方式使用。

如果要将多个工作目录与一个git存储库一起使用,可以使用一些解决方案。请参阅stackoverflow问题here

否则你可以:

  • 将存储库直接克隆到webroot。虽然这意味着开始新鲜的webroot
  • 克隆一份副本而不是webroot并坚持使用webroot作为其唯一的工作目录(一旦你将它与你已经拥有的同步)。您可以使用git config core.worktree ../target将其设置为存储库默认值。

2
投票

但是,Git也不删除以前跟踪过的文件,但同时也删除了这些文件

是的,使用Git 2.22(2019年第二季度)和git checkout --overlay,确实如此。 “git checkout --no-overlay”可用于触发从树状结构中检出路径的新模式,该模式允许与当前索引和工作树中的pathspec匹配但不在树中的路径。

参见commit e92aa0e(2019年2月4日),commit 1495ff7commit 091e04b(2019年1月8日)和commit b7033e7commit 5160fa0commit 6fdc205commit 536ec18commit b702dd1commit a0cc584(2018年12月20日)。 建议:Thomas Gummerer (tgummerer)。 (由Jonathan Nieder (artagnon)合并于Junio C Hamano -- gitster --,2019年3月7日)

commit 7d0c1f4:介绍checkout选项

目前'--{,no-}overlay'被定义为叠加操作,这意味着如果在'git checkout'中我们在索引中有一个与git checkout <tree-ish> -- [<pathspec>]匹配的条目,但在<pathspec>中不存在,那么该条目将不会从索引或工作树。

引入一个新的<tree-ish>选项,允许在非叠加模式下使用'--{,no-}overlay',从而从工作树中删除文件,如果它们不存在于git checkout中但匹配<tree-ish>

请注意,'<pathspec>'已经以这种方式工作,因此补丁模式不需要进行任何更改。 我们不允许'git checkout -p <tree-ish> -- [<pathspec>]'避免混淆那些期望能够以这种方式强制'git checkout --overlay -p'覆盖模式的用户。

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

你有一个dir/

new git config setting

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


0
投票

我用git-clean做了类似的事情。如果您不想删除的文件位于gitignore中,则可以删除所有不需要的文件。

© www.soinside.com 2019 - 2024. All rights reserved.