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

时间:2015-06-26 15:08:50

标签: git dvcs git-checkout

我们希望使用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

3 个答案:

答案 0 :(得分:2)

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

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

否则你可以:

  • 将存储库直接克隆到webroot。虽然这意味着要开始新的webroot
  • 克隆副本但不在webroot中,并坚持始终使用webroot作为其唯一的工作目录(一旦您将其与您已有的同步那里)。您可以使用git config core.worktree ../target将其设置为存储库默认值。

答案 1 :(得分:1)

  

但是,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 --commit 7d0c1f4中合并,2019年3月7日)

  

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

     

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

     

引入一个新的--{,no-}overlay选项,该选项允许在非覆盖模式下使用'git checkout',因此,如果文件<tree-ish>中不存在但与{ {1}}。

     

请注意,“ <pathspec>”已经可以使用   这样,补丁模式就不需要更改。
  我们禁止使用“ git checkout -p <tree-ish> -- [<pathspec>]”,以免混淆期望的用户   这样就可以在“ git checkout --overlay -p”中强制采用叠加模式。

     

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

您有一个new git config setting

dir/
     

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

答案 2 :(得分:0)

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