私は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
ファイルがいつ再表示されるか正確にはわかりません。さまざまなブランチ (リモート追跡とローカルの両方) に何度も切り替えており、非常に忙しいレポであるため、頻繁にプルする新しい変更があります。
gitの比較的初心者として、作業ツリーを「リセット」してそれらのファイルを再度削除する方法がわかりません。
実験として、sparseCheckout を無効にしてプルしてみました。後で 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と同じファイルを無視しました!
sparse-checkout
$ 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 リポジトリは少し大きく (2GB 以上)、「失敗」の間隔 (1 ~ 2 週間程度) が長すぎて、人々が問題を正確に再現しようとすることは期待できません。とで同じパスを使用することは試していません。競合が発生する可能性があることは、今日だけに思い浮かびました。sparse-checkout
exclude
数週間前に #git on 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
たとえば、上記の例に示されているファイルは新しいファイルではないか、最近名前が変更されたものではないため、名前が変更されたときに常に問題が発生するとは限りません。