2016-05-09 5 views
0

私はgit addと同じ配管コマンドが使えますか?

git add $DIRECTORY 

git add $FILE 

どのようにそれが動作しないを入力するときに、実際に何が起こるかを学ぶことで、より良いを理解したいのですが?

progit's git internals sectionを読むことで大まかなアイデアを得ることができます。 $DIRECTORYもし

  • は再帰的に$DIRECTORY内のすべてのファイルを追加するディレクトリ、find $DIRECTORY -type f -exec git add {} \;のようなもの、すなわち、です。次に、ファイルごとにgit add $FILENAMEが適用されます。
  • cleanフィルタを実行している.gitignoreに対するチェック(およびその "上司")
  • .gitattributesに対するチェックは、該当
  • git hash-object -w場合clean編の内容

そしてそして、インデックスが取得します何らかの形で更新され、git mktreeが含まれます。しかし、そこには何が起こりますか?ディレクトリのツリーには、追加されたファイルまたは以前にコミットされたすべてのファイルだけが含まれていますか?そして次に何が起こるでしょうか?

+0

Gitはdiffを実行するたびにすべてを再帰的に検索しますか?または 'add'など? – Geremia

答えて

2

git addには、同等の配管コマンドはありませんが、最も近いものはおそらくgit update-indexです。 ProGitの説明は正しいです。

  1. 各ディレクトリをディレクトリの内容のリストに置き換えてください。結果はaddで指定されたファイルのリストであり、ディレクトリ内のではなくではないことが判明しているファイルや、特殊インデックス状態のファイル(--assume-unchanged--skip-worktree)の特殊な扱いがあります。つまり、このステップでは現在のインデックスも参照します。

  2. unstaged-たが、無視(.gitignore経由)ファイルをチェックし、-f/--forceを与えない限り、(警告付き)のリストからそれらを捨てます。

    (これはサブディレクトリではこれをテストしていないため、再帰スキャンで選択されたサブディレクトリエントリには適用されませんが、コマンドラインで実際に指定された名前にのみ適用される可能性があります。場合は、手順2を手順1と組み合わせて、-fでも無視する場合は名前を追加しないようにする必要があります。

  3. 属性がある場合はそれを適用し、必要に応じてファイルを一時的に消去します。

  4. git update-index --add --remove --replaceを使用して、モード更新を含むインデックスエントリが更新されたリポジトリに書き込まれた変更ファイルを取得します。 (手順3でクリーニングされたファイルの場合は、提案したように別のgit hash-object -wを使用し、--add --remove --replaceの代わりに--index-infoを使用する必要があります。--index-versionを参照)、インデックス自体が難文書フォーマットを使用して、単にフラットファイル(またはより正確には、いくつかのフォーマットの一つとして)

git mktree

コマンドは、まったくこのプロセスに入りません。

インデックスには、ステージと呼ばれるファイル名ごとに最大4つのエントリがあります。ステージ0は通常のキャッシュエントリであり、ステージ1〜3は競合するマージです。ファイルを削除するための特別なビットがいくつかあります:--assume-unchanged--skip-worktree--intent-to-add、およびいくつかの特別な内部使用フラグ。Gitはディレクトリを格納していませんが、Gitはctime Gitはこれを維持するためにOSを信頼することができるならば、変更されていないディレクトリをすばやくスキップすることができます)。

git mktreeコマンドは、インデックスを一連のツリーオブジェクトに変換するときのみ有効です。 Gitは、インデックス内の各サブディレクトリに対して1つのツリーと、全体インデックスを表す1つのトップレベルツリーを作成する必要があります。 (サブプロジェクトがあれば、すでに存在していれば "gitlink"エントリーとしてインデックスに入っています)。

+0

Gitは 'diff'や' add'などを行うたびに、ファイルシステム内のすべてを再帰的に検索しますか? – Geremia

+0

@Geremia:詳細はかなり異なりますが、かなりです。インデックスには特別な "スピードアップ"ロールがあり、問題のディレクトリのタイムスタンプがインデックス自体に格納されているものと一致する場合、Gitは何かを再帰的に読み飛ばすことができます。ワイドおよび/またはディープツリーの場合、これは大きな違いを生む可能性があります。そのため、追跡されていないディレクトリであっても、バックグラウンドでキャッシュに格納されます(オプションで2番目の「分割インデックスキャッシュ」にあります)。 – torek

関連する問題