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

Jon*_*ely 13 git sparse-checkout

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

$ 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/
Run Code Online (Sandbox Code Playgroud)

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

$ ls gnattools/
ChangeLog  configure  configure.ac  Makefile.in
$ ls  gcc/fortran/ | wc -l 
86
Run Code Online (Sandbox Code Playgroud)

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

作为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
Run Code Online (Sandbox Code Playgroud)

显然,我对我从未要求的文件进行了本地修改,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
Run Code Online (Sandbox Code Playgroud)

我尝试过,git read-tree -m -u HEAD但它没有做任何事情.

所以我的问题是:

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

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

所以我的exclude文件包括诸如的路径

# /gcc/fortran/
/gcc/fortran/TAGS
/gcc/fortran/TAGS.sub
/gcc/fortran/gfortran.info*
Run Code Online (Sandbox Code Playgroud)

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

!gcc/fortran/
Run Code Online (Sandbox Code Playgroud)

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

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

更新:

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

   bac6f1f..6c760a6  master     -> origin/master
Run Code Online (Sandbox Code Playgroud)

以及显示的更改是这些重命名:

 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
Run Code Online (Sandbox Code Playgroud)

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

$ ls libgo/go/crypto/x509/root_<TAB>
root_darwin.go  root_stub.go    root_unix.go    
Run Code Online (Sandbox Code Playgroud)

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

我很确定当有重命名时问题并不总是发生,因为libgfortran/ChangeLog例如上面示例中显示的文件不是新文件或最近重命名.

use*_*062 4

可以使用 修改跳过工作树位git update-index --skip-worktree。当您注意到存在的文件时,您可以检查git ls-files -v |grep ^S(S 是标有“skip-worktree”的文件)。

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

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