Почему исключенные файлы продолжают появляться в моем git sparse checkout?
я использую GCC git зеркало и поскольку я использую только интерфейсы 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
я не уверен, когда точно появятся файлы, я много переключаюсь на разные ветви (оба remote-tracking и local), и это очень занятое РЕПО, поэтому часто возникают новые изменения.
как относительный новичок в 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
файл содержит ссылки к файлам в каталогах, которые должны быть исключены (т. е. названы с!
) в ? Я последовал инструкциям игнорировать те же файлы, что и SVN$ git svn show-ignore >> .git/info/exclude
мой exclude
файлы включают в себя пути, такие как
# /gcc/fortran/
/gcc/fortran/TAGS
/gcc/fortran/TAGS.sub
/gcc/fortran/gfortran.info*
который будет ниже одного из каталогов, названных в :
!gcc/fortran/
я попытался воспроизвести проблему с тестовым РЕПО, которое я клонирую несколько копий и редактировать каждый из них, создавать/переключать/удалять ветви и объединять изменения между ними, но это никогда не идет неправильно в моих игрушечных тестах. РЕПО GCC немного велико (более 2 ГБ), а время между "сбоями" (порядка недели или двух) слишком долго, чтобы ожидать, что люди попытаются точно воспроизвести проблему. Я!--27-->не экспериментировал с теми же путями в sparse-checkout
и exclude
, поскольку мне только сегодня пришло в голову, что там может быть конфликт.
I спросил об этом на #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
директория отсутствовала, как и хотелось. После вытягивания, что dir присутствовал и эти файлы (и никакие другие) были под ним:
$ ls libgo/go/crypto/x509/root_<TAB>
root_darwin.go root_stub.go root_unix.go
я не знаю, если переименованные файлы потеряли свои skip-worktree
бит, как мне это проверить?
я уверен, что проблема не всегда возникает, когда есть переименования, потому что, например,libgfortran/ChangeLog
файл, показанный в примере выше, не является новым файлом или недавно переименованным.
3 ответов
бит skip-worktree можно изменить с помощью 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 дерево способ впереди, и я думаю, что есть большой шанс, что это исправит ваши проблемы.
в моем случае я выполнял некоторые модульные тесты на репо, используя разреженную проверку. Один из моих тестовых случаев создал коммиты, содержащие файлы, которые не были включены в мой разреженный список под-дерева checkout.
когда я попытался 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
Проверьте, сохраняется ли проблема в последнем Git 2.13 (Q2 2017, 5 лет спустя).
Любой файл skip-worktree не должен быть изменен или даже просмотрен во время разреженной проверки, потому что:
на
preload-index
код был научен не беспокоиться об индексе записи, которые являются путями, которые не проверяются "разреженной выпиской".
посмотреть совершить e596acc (10 Feb 2017) by Джефф Хостетлер (jeffhostetler
).
(слитый Junio C Hamano -- gitster
-- на совершить c7e234f, 27 февраля 2017)
preload-index
: во избежаниеlstat
наskip-worktree
предметынаучить
preload-index
избежатьlstat()
вызовы для индексных записей с набором битов skip-worktree.
Это оптимизация производительности.во время разреженной проверки бит skip-worktree устанавливается для элементов этого не было. населены и поэтому не присутствуют в worktree.
Цикл preload-index для каждого потока выполняет серию тестов для каждой записи индекса, поскольку он пытается сравнить версию рабочего дерева с индексом и отметить их актуальными.
Этот патч сокращает работу.в системе Windows 10 с очень большим РЕПО (индекс 450MB) и различными уровнями разреженности производительность была улучшена в
{preloadindex=true, fscache=false}
случай 80% и в{preloadindex=true, fscache=true}
случай 20% для различного команды.