10

任意のコマンドを覚える代わりに、構成ファイル (.gitignore や .git/config など) を直接変更するのが好きですが、Git が "git update-index --assume-unchanged file "。

ご存知の方、教えてください!

4

2 に答える 2

4

コマンドのどこにあるかを示します--gitupdate -index

したがって、インデックスはテキストファイルではないため、実際にインデックスを編集することはできません。

git update-index --assume-unchangedまた、コマンドで保存される内容の詳細についてはUsing “assume unchanged” bit 、マニュアルのセクションを参照してください。

于 2011-08-18T22:47:10.537 に答える
3

他の人が言ったように、それはにあるインデックスに保存され.git/indexます。

いくつかの調査作業の後、それが次の場所にあることがわかりました。各インデックス エントリの有効なビットを想定します。

したがって、以下の内容を理解する前に、他の回答で説明されているように、まずインデックスのグローバル形式を理解する必要があります。

次に、「有効であると仮定する」ビットが原因であることをどのように確認したかを説明します。

  • 経験的に
  • ソースを読むことで

経験的

それまでの時間hd

設定:

git init
echo a > b
git add b

それで:

hd .git/index

与えます:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 e9 b6 f3  |DIRC........T...|
00000010  2d 4f e1 2f 54 e9 b6 f3  2d 4f e1 2f 00 00 08 05  |-O./T...-O./....|
00000020  00 de 32 ff 00 00 81 a4  00 00 03 e8 00 00 03 e8  |..2.............|
00000030  00 00 00 00 e6 9d e2 9b  b2 d1 d6 43 4b 8b 29 ae  |...........CK.).|
00000040  77 5a d8 c2 e4 8c 53 91  00 01 62 00 c9 a2 4b c1  |wZ....S...b...K.|
00000050  23 00 1e 32 53 3c 51 5d  d5 cb 1a b4 43 18 ad 8c  |#..2S<Q]....C...|
00000060

今:

git update-index --assume-unchanged b
hd .git/index

与えます:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 e9 b6 f3  |DIRC........T...|
00000010  2d 4f e1 2f 54 e9 b6 f3  2d 4f e1 2f 00 00 08 05  |-O./T...-O./....|
00000020  00 de 32 ff 00 00 81 a4  00 00 03 e8 00 00 03 e8  |..2.............|
00000030  00 00 00 00 e6 9d e2 9b  b2 d1 d6 43 4b 8b 29 ae  |...........CK.).|
00000040  77 5a d8 c2 e4 8c 53 91  80 01 62 00 17 08 a8 58  |wZ....S...b....X|
00000050  f7 c5 b3 e1 7d 47 ac a2  88 d9 66 c7 5c 2f 74 d7  |....}G....f.\/t.|
00000060

2 つのインデックスを比較し、インデックスのグローバル構造を調べると、違いは次のとおりであることがわかります。

  • バイト番号0x48(行の 9 番目40) が から00に変更されました80これがフラグであり、キャッシュ エントリ フラグの最初のビットです。
  • 0x4Cからまでの 20 バイト0x5F。これは、インデックス全体に対する SHA-1 であるため、予想されます。

これは、インデックス エントリの SHA-1 の SHA-1 が から までのバイト単位で0x34フラグ0x47を考慮していないことにも気付きました。これは、両方のインデックス間で変更されていないためです。これがおそらく、フラグが SHA の後に配置されている理由であり、SHA はその前にあるもののみを考慮します。

ソースコード

それが Git 2.3 のソース コードと一貫しているかどうかを見てみましょう。

最初にupdate-index、 grepのソースを見てくださいassume-unchanged

これは次の行につながります。

{OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
  N_("mark files as \"not changing\""),
  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
  N_("clear assumed-unchanged bit"),
  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},

そのため、値は に保存されmark_valid_onlyます。それを grep し、それが1 つの場所でのみ使用されていることを確認します。

if (mark_valid_only) {
  if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))
    die("Unable to mark file %s", path);
  return;
}

CEキャッシュエントリを意味します。

mark_ce_flagsをすばやく調べると、次のことがわかります。

if (mark)
  active_cache[pos]->ce_flags |= flag;
else
  active_cache[pos]->ce_flags &= ~flag;

したがって、関数は基本的に、トライステートであるCE_VALIDに応じてビットを設定または設定解除します。mark_valid_only

  • マーク:--assume-unchanged
  • マークを外す:--no-assume-unchanged
  • 何もしない: で0設定されたオプションのデフォルト値{OPTION_SET_INT, 0

次に、 の下builtin/で grep すると、他の場所で の値が設定されていないことがわかりますCE_VALID。したがって、それ--assume-unchangedを設定する唯一のコマンドである必要があります。

ただし、フラグはソース コードの多くの場所で使用されます。これには多くの副作用があるため、予期されるはずであり、次のように毎回使用されます。

ce->ce_flags & CE_VALID

ce_flagsしたがって、それは の体の一部であると結論付けstruct cache_entryます。

インデックスが at に指定されてcache.hいるのは、その機能の 1 つがコミットをより速く作成するためのキャッシュになるためです。

下線と周囲線の定義を見ると、CE_VALID次のようになります。cache.h

#define CE_STAGEMASK (0x3000)
#define CE_EXTENDED (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12

0x8000したがって、これは整数 ( ) の最初のビットであり、 のすぐ隣にあると結論付けます。これは、以前の実験CE_EXTENDEDと一致しています。

于 2015-02-22T11:05:08.573 に答える