Почему исключенные файлы продолжают появляться в моем git sparse checkout?

Я использую зеркало git GCC, а поскольку я использую только внешние интерфейсы 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, я не знаю, как «сбросить» мое рабочее дерево, чтобы снова избавиться от этих файлов.

В качестве эксперимента я попытался отключить sparse checkout и pull, думая, что смогу потом снова включить 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 ..." 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? Я следовал инструкциям игнорировать те же файлы, что и SVN

    $ 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/

Я попытался воспроизвести проблему с тестовым репозиторием, клонировав несколько копий и отредактировав каждую из них. их, создавать/переключать/удалять ветки и объединять изменения между ними, но в моих игрушечных тестовых примерах это никогда не пойдет не так. Репозиторий GCC немного велик (более 2 ГБ), а время между «сбоями» (порядка недели или двух) слишком велико, чтобы ожидать, что люди попытаются точно воспроизвести проблему.Я неэкспериментировал с одинаковыми путями в sparse-checkoutи exclude, так как только сегодня мне пришло в голову, что там может быть конфликт.

Я спрашивал об этом в #git на freenode несколько недель назад, и 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отсутствовала, как и хотелось. После извлечения этот каталог присутствовал, и эти файлы (и никакие другие) находились в нем:

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

Я не знаю, потеряли ли переименованные файлы свой бит skip-worktree, как мне это проверить?

Я почти уверен, что проблема не всегда возникает при переименовании, потому что, например. файл libgfortran/ChangeLog, показанный в приведенном выше примере, не является новым или недавно переименованным.

13
задан Jonathan Wakely 25 June 2012 в 17:05
поделиться