为什么排除的文件会在我的git稀疏结帐中重新出现?

时间:2012-06-22 00:06:58

标签: git sparse-checkout

我使用GCC git mirror,因为我只使用C和C ++前端,我使用git的稀疏结账功能来排除我不需要的数百个文件:

$ git config core.sparseCheckout
true
$ cat .git/info/sparse-checkout 
/*
!gnattools/
!libada/
!libgfortran/
!libgo/
!libjava/
!libobjc/
!libquadmath/
!gcc/ada/
!gcc/fortran/
!gcc/go/
!gcc/java/
!gcc/objc/
!gcc/objcp/
!gcc/testsuite/ada/
!gcc/testsuite/gfortran.dg/
!gcc/testsuite/gfortran.fortran-torture/
!gcc/testsuite/gnat.dg/
!gcc/testsuite/go.dg/
!gcc/testsuite/go.go-torture/
!gcc/testsuite/go.test/
!gcc/testsuite/objc/
!gcc/testsuite/objc.dg/
!gcc/testsuite/obj-c++.dg/
!gcc/testsuite/objc-obj-c++-shared/

这种方法有一段时间了,但后来我发现其中一些被排除的文件已经返回,有时很多

$ ls gnattools/
ChangeLog  configure  configure.ac  Makefile.in
$ ls  gcc/fortran/ | wc -l 
86

我不确定文件何时重新出现,我做了很多切换到不同的分支(远程跟踪和本地),这是一个非常繁忙的回购,所以有新的变化经常拉。

作为git的相对新手,我不知道如何“重置”我的工作树以再次摆脱这些文件。

作为一个实验,我尝试禁用稀疏结账和拉动,以为我可以再次启用sparseCheckout以某种方式更新树,但这不能很好地工作:

$ git config core.sparseCheckout false
$ git config core.sparseCheckout 
false
$ git pull
remote: Counting objects: 276, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 117 (delta 98), reused 0 (delta 0)
Receiving objects: 100% (117/117), 64.05 KiB, done.
Resolving deltas: 100% (98/98), completed with 64 local objects.
From git://gcc.gnu.org/git/gcc
   7618909..0984ea0  gcc-4_5-branch -> origin/gcc-4_5-branch
   b96fd63..bb95412  gcc-4_6-branch -> origin/gcc-4_6-branch
   d2cdd74..2e8ef12  gcc-4_7-branch -> origin/gcc-4_7-branch
   c62ec2b..fd9cb2c  master     -> origin/master
   2e2713b..29daec8  melt-branch -> origin/melt-branch
   c62ec2b..fd9cb2c  trunk      -> origin/trunk
Updating c62ec2b..fd9cb2c
error: Your local changes to the following files would be overwritten by merge:
        gcc/fortran/ChangeLog
        gcc/fortran/iresolve.c
        libgfortran/ChangeLog
        libgfortran/io/intrinsics.c
Please, commit your changes or stash them before you can merge.
Aborting

显然,我对我从未要求的文件进行了本地修改,AFAIK从未触及过!

但是git status没有显示这些变化:

$ git st
# On branch master
# Your branch is behind 'origin/master' by 9 commits, and can be fast-forwarded.
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       libstdc++-v3/53270.txt
#       libstdc++-v3/TODO

我已经尝试了git read-tree -m -u HEAD但它没有做任何事情。

所以我的问题是:

  • 为什么文件重新出现?
  • 如何让它们再次消失?
  • 如何阻止他们回来?
  • 这可能与我的.git/info/exclude文件包含对!文件中应该被排除(即以sparse-checkout命名)的目录中的文件的引用有关吗?我按照说明ignore the same files that SVN does

    $ git svn show-ignore >> .git/info/exclude

所以我的exclude文件包含

等路径
# /gcc/fortran/
/gcc/fortran/TAGS
/gcc/fortran/TAGS.sub
/gcc/fortran/gfortran.info*

哪个位于sparse-checkout文件中指定的目录之一:

!gcc/fortran/

我试图用测试仓库重现问题,我克隆了几个副本并编辑它们,创建/切换/删除分支并合并它们之间的变化,但它在我的玩具测试用例中永远不会出错。海湾合作委员会的回购有点大(超过2GB),“失败”(大约一周或两周)之间的时间太长,以至于人们不能试图完全重现问题。我尚未尝试在sparse-checkoutexclude中使用相同的路径,因为只有我今天才会遇到可能存在冲突的路径。

几周前我在freenode上的#git问过这个问题,IIRC基本上被告知“这可能是一个错误,没有人使用稀疏结账”,但我希望有更好的答案; - )

更新

最近一次,我看到问题确实发生了(即文件不在那里,然后出现在一个命令之后)从上游原点进行拉动:

   bac6f1f..6c760a6  master     -> origin/master

,显示的更改包括:

 create mode 100644 libgo/go/crypto/x509/root.go
 rename libgo/go/crypto/{tls => x509}/root_darwin.go (90%)
 rename libgo/go/crypto/{tls => x509}/root_stub.go (51%)
 rename libgo/go/crypto/{tls => x509}/root_unix.go (76%)
 create mode 100644 libgo/go/crypto/x509/root_windows.go

在拉出之前,根据需要缺少libgo目录。在dir存在之后,这些文件(没有其他文件)在它之下:

$ ls libgo/go/crypto/x509/root_<TAB>
root_darwin.go  root_stub.go    root_unix.go    

我不知道重命名的文件是否丢失了skip-worktree位,我该怎么检查?

我很确定在重命名时问题并不总是会发生,例如上面示例中显示的libgfortran/ChangeLog文件不是新文件,也不是最近重命名的文件。

3 个答案:

答案 0 :(得分:4)

可以使用git update-index --skip-worktree修改skip-worktree位。当您注意到存在的文件时,您可以检查git ls-files -v |grep ^S(S是标记为skip-worktree的文件)。

但是正如#git的人说的那样,如果你看到奇怪的行为,很可能是git中的一个bug。毕竟,这是一个非常深奥的功能。您应该将您的发现报告给git邮件列表。

修改:另外,如果您使用的是git 1.7.7.6,我强烈建议您升级。 1.7.10树是遥遥领先的,我认为它很有可能解决你的问题。

答案 1 :(得分:1)

就我而言,我正在使用稀疏结账对repo进行一些单元测试。我的一个测试用例创建了包含未包含在稀疏结帐子树列表中的文件的提交。

当我尝试git reset --hard 123456时,我收到以下错误:

error: Entry 'a.c' not uptodate. Cannot update sparse checkout.
fatal: Could not reset index file to revision '123456'.

解决方案是通过重新应用稀疏结帐规则来删除工作树中的文件:

git read-tree -mu HEAD

答案 2 :(得分:1)

检查问题是否仍然存在于最新的Git 2.13(2017年第2季度,5年后) 任何skip-worktree文件都不应该在稀疏结账时修改甚至查看,因为:

  

preload-index code已被教导不要打扰索引   条目未被&#34;稀疏结账&#34;

检出的路径

commit e596accJeff Hostetler (jeffhostetler)(2017年2月10日) Junio C Hamano -- gitster --于2017年2月27日commit c7e234f合并)

  

preload-index:对lstat

避免skip-worktree      

preload-index以避免lstat()调用带有skip-worktree位设置的索引条目。
  这是性能优化。

     

在稀疏结账期间,在项目上设置skip-worktree位   没有填充,因此不存在   worktree。
  每个线程的preload-index循环对每个索引条目执行一系列测试,因为它尝试将工作树版本与索引进行比较并将其标记为最新。   这个补丁捷径可行。

     

在具有非常大的回购(450MB索引)和不同级别的稀疏性的Windows 10系统上,{preloadindex=true, fscache=false}案例的性能提高了80%,{preloadindex=true, fscache=true}案例的性能提高了20%各种命令。