リポジトリ内のすべてのオブジェクトの未加工のSHA1リストを取得するより良い方法はありますかls .git/objects/??/\*
およびcat .git/objects/pack/*.idx | git show-index
?
git rev-list --all
しかし、それは.git/refsによって参照されるコミットオブジェクトのみを一覧表示し、私はeverythingを探しています。git-hash-object、git-mktreeなどによって作成される参照されていないオブジェクトを含みます。
編集:アリストテレス 掲載 さらに良い回答 、これは正しいとマークされるべきです。
編集:スクリプトに構文エラーがあり、grep -v
行の最後にバックスラッシュがありません
いくつかの修正を行った後、Markの答えはうまくいきました。
--git-dir
の代わりに--show-cdup
を使用して、裸のリポジトリをサポートしましたPerl
は-r
をサポートしていないため、sed
を使用しました#!/bin/sh
set -e
cd "$(git rev-parse --git-dir)"
# Find all the objects that are in packs:
find objects/pack -name 'pack-*.idx' | while read p ; do
git show-index < $p | cut -f 2 -d ' '
done
# And now find all loose objects:
find objects/ \
| egrep '[0-9a-f]{38}' \
| grep -v /pack/ \
| Perl -pe 's:^.*([0-9a-f][0-9a-f])/([0-9a-f]{38}):\1\2:' \
;
試して
git rev-list --objects --all
編集ジョシュは良い点を指摘しました:
git rev-list --objects -g --no-walk --all
ref-logsから到達可能なオブジェクトをリストします。
到達不能なコミット内のすべてのオブジェクトも表示するには:
git rev-list --objects --no-walk \
$(git fsck --unreachable |
grep '^unreachable commit' |
cut -d' ' -f3)
すべてをまとめて、reallyにすべてのオブジェクトをrev-list --objects
の出力形式で取得するには、次のようなものが必要です。
{
git rev-list --objects --all
git rev-list --objects -g --no-walk --all
git rev-list --objects --no-walk \
$(git fsck --unreachable |
grep '^unreachable commit' |
cut -d' ' -f3)
} | sort | uniq
出力をやや便利な方法でソートするには(ツリー/ブロブのパス、最初にコミット)、追加の| sort -k2
を使用します。これは、同一パスのすべての異なるブロブ(リビジョン)をグループ化します。
このオプションがいつ存在するかはわかりませんが、できます
git cat-file --batch-check --batch-all-objects
これにより、manページによると、
すべてのオブジェクトリポジトリおよび代替オブジェクトストア(到達可能なオブジェクトだけでなく)
(強調鉱山)。
デフォルトでは、これによりオブジェクトタイプとサイズが各ハッシュとともに生成されますが、この情報は簡単に削除できます。と
git cat-file --batch-check --batch-all-objects | cut -d' ' -f1
または、--batch-check
にカスタム形式を指定します。
これは、答え マークによる および ウィルキルによる からのスクリプトのより正確で、より単純で、より速い表現です。
それは使用しています rev-parse --git-path
は、より複雑なGitリポジトリの設定(たとえば、マルチワークツリーの状況など)でもobjects
ディレクトリを見つけます。
find
、grep
、Perl
、sed
の不要な使用をすべて回避します。
ゆるいオブジェクトやパックがなくても(または、新しいリポジトリでこれを実行する場合はどちらでも)正常に動作します。
ただし、このミレニアムのBashが必要ですか???? (2.02以降、特にextglob
ビット用)。
共有してお楽しみください。
#!/bin/bash
set -e
shopt -s nullglob extglob
cd "`git rev-parse --git-path objects`"
# packed objects
for p in pack/pack-*([0-9a-f]).idx ; do
git show-index < $p | cut -f 2 -d ' '
done
# loose objects
for o in [0-9a-f][0-9a-f]/*([0-9a-f]) ; do
echo ${o/\/}
done
すべてのルーズオブジェクトファイルとすべてのパックファイルのインデックスを確認するよりも、明らかに優れた方法を知りません。 gitリポジトリの形式は非常に安定しており、この方法を使用すると、git fsck
、これは磁器に分類されます。この方法も高速だと思います。次のスクリプトは、リポジトリ内のすべてのオブジェクトを示しています。
#!/bin/sh
set -e
cd "$(git rev-parse --show-cdup)"
# Find all the objects that are in packs:
for p in .git/objects/pack/pack-*.idx
do
git show-index < $p | cut -f 2 -d ' '
done
# And now find all loose objects:
find .git/objects/ | egrep '[0-9a-f]{38}' | \
sed -r 's,^.*([0-9a-f][0-9a-f])/([0-9a-f]{38}),\1\2,'
(このスクリプトの元のバージョンは パックファイル内の最大のオブジェクトを見つけるためのこの便利なスクリプト に基づいていましたが、git show-index
、あなたの質問で提案されたとおり。)
このスクリプトを GitHub Gist にしました。
Erki Der Loony の answer で提案されているgit cat-file --batch-check --batch-all-objects
コマンドは、で作成できます。新しいGit 2.19(2018年第3四半期)オプション--unordered
を使用した場合の高速化.
学習したすべてのオブジェクトを反復処理するAPIオプションでオブジェクトをpackfilesに表示される順序でリストします。これにより、呼び出し元がこれらのオブジェクトにアクセスする場合、オブジェクトが列挙されるため。
commit 0889aae 、 commit 79ed0a5 、 commit 54d2f0d を参照/、 commit ced9fff (2018年8月14日)、および commit 0750bb5 、 commit b1adb38 、 commit aa2f5ef 、 commit 736eb88 、 commit 8b36155 、 commit a7ff6f5 、 commit 202e7f1 (2018年8月10日) ジェフ・キング(peff
) 。 ( Junio C Hamano-gitster
- in commit 0c54cda 、8月20日で合併2018)
cat-file
:--batch-all-objects
の「unordered
」出力をサポートパックファイル内のすべてのオブジェクトのコンテンツにアクセスする場合、一般的にハッシュ順ではなくパック順でアクセスする方がはるかに効率的です。これにより、パックファイル内のアクセスの局所性が向上します。これは、パックファイルが関連するデルタを隣り合わせに配置するため、デルタベースキャッシュにとってより使いやすくなります。対照的に、sha1はコンテンツと識別可能な関係がないため、ハッシュ順序は事実上ランダムです。
このパッチは、
--unordered
オプションをcat-file
に導入します。これは、内部のパック順でパックを反復処理します。すべてのファイルコンテンツをダンプすると、結果を確認できます。$ time ./git cat-file --batch-all-objects --buffer --batch | wc -c 6883195596 real 0m44.491s user 0m42.902s sys 0m5.230s $ time ./git cat-file --unordered \ --batch-all-objects --buffer --batch | wc -c 6883195596 real 0m6.075s user 0m4.774s sys 0m3.548s
同じ出力、異なる順序、はるかに高速。次のような異なるプロセスでオブジェクトコンテンツにアクセスする場合でも、同じスピードアップが適用されます。
git cat-file --batch-all-objects --buffer --batch-check | grep blob | git cat-file --batch='%(objectname) %(rest)' | wc -c
最初のコマンドに「
--unordered
」を追加すると、git.git
のランタイムが24秒から3.5秒にドロップされます。サイドノート:実際にすべてのインプロセスを実行するために、実際にはさらに高速化が利用可能です。実際のパックの反復中にオブジェクトのコンテンツを出力しているため、オブジェクトの場所を知っており、
oid_object_info()
によって行われる追加のルックアップをスキップできます。このパッチは、基になるAPIがこれらの種類の直接リクエストを行う準備ができていないため、その最適化の手前で停止します。
--unordered
の方がはるかに優れている場合、デフォルトにしないのはなぜですか? 2つの理由:
--batch-all-objects
はハッシュ順に出力することをドキュメントで約束しました。cat-file
は配管であるため、人々はそのデフォルトに依存している可能性があり、変更することはできません。実際には slower です。パック順で歩くには、パックのrevindexを計算する必要があります。そして、重複排除の手順では、ソートと重複ではなく、oidsetを使用します。
たとえば、各オブジェクトのタイプとサイズにアクセスするだけの場合、次のようになります。
git cat-file --batch-all-objects --buffer --batch-check
--unordered
を使用すると、ベスト5のウォームキャッシュタイミングは900ミリ秒から1100ミリ秒になります。コールドキャッシュまたはメモリのプレッシャーの中で、パックファイル内のローカリティが向上するため、より良い結果を得ることができます。最後の質問:なぜ「
--unordered
」ではなく「--pack-order
」なのですか?答えは再び2つあります。
「パック順序」は、オブジェクトのセット全体で明確に定義されたものではありません。複数のパックのオブジェクトと同様に、ゆるいオブジェクトをヒットしています。そして、約束している唯一の順序は within 単一のパックです。残りは明らかにランダムです。
ここでのポイントは最適化です。そのため、特定の順序を約束するのではなく、オブジェクトのコンテンツにアクセスするのに効率的な順序を選択するというだけです。これにより、別の互換性オプションを追加することなく、将来のさらなる変更に対応できます。
Git 2.20(2018年第4四半期)ではさらに高速です:
commit 8c84ae6 、 commit 8b2f8cb 、 commit 9249ca2 を参照/、 commit 22a1646 、 commit bf73282 (2018年10月4日)by ルネ・シャーフ(rscharfe
) 。
( Junio C Hamano-gitster
- in commit 82d0a8c 、10月19日で合併2018)
oidset
:khash
を使用メモリフットプリントを削減し、高速化するために、
khash.h
を使用してoidset
を再実装します。
master
およびClang 6.0.1で、oidsetを使用して主に重複オブジェクトをチェックするコマンドのパフォーマンス:$ cmd="./git-cat-file --batch-all-objects --unordered --buffer --batch-check='%(objectname)'" $ /usr/bin/time $cmd >/dev/null 0.22user 0.03system 0:00.25elapsed 99%CPU (0avgtext+0avgdata 48484maxresident)k 0inputs+0outputs (0major+11204minor)pagefaults 0swaps $ hyperfine "$cmd" Benchmark #1: ./git-cat-file --batch-all-objects --unordered --buffer --batch-check='%(objectname)' Time (mean ± σ): 250.0 ms ± 6.0 ms [User: 225.9 ms, System: 23.6 ms] Range (min … max): 242.0 ms … 261.1 ms
そして、このパッチで:
$ /usr/bin/time $cmd >/dev/null 0.14user 0.00system 0:00.15elapsed 100%CPU (0avgtext+0avgdata 41396maxresident)k 0inputs+0outputs (0major+8318minor)pagefaults 0swaps $ hyperfine "$cmd" Benchmark #1: ./git-cat-file --batch-all-objects --unordered --buffer --batch-check='%(objectname)' Time (mean ± σ): 151.9 ms ± 4.9 ms [User: 130.5 ms, System: 21.2 ms] Range (min … max): 148.2 ms … 170.4 ms
Git 2.21(2019年第1四半期)では、パック内の順序でオブジェクトを訪問する通常のパターンに従って、コードパスをさらに最適化してコミットグラフを書き出します。
commit d7574c9 (2019年1月19日)by ÆvarArnfjörðBjarmason(avar
) を参照してください。
( ジュニオC浜野-gitster
- in commit 04d67b6 、2月5日2019)
for_each_object_in_pack()
とともにFOR_EACH_OBJECT_PACK_ORDER
を使用して、「commit-graph write」ステップを少し最適化します。
Derrick Stoleeは、Windowsで 彼自身のテストを行いました 高い精度で2%の改善を示しました。
Git 2.23(Q3 2019)は、「 git rev-list --objects
」を改善し、「--no-object-names
」オプションで学習して、パックオブジェクトのグループ化ヒントとして使用されるオブジェクトへのパスをスケルチします。
commit 42357b4 (2019年6月19日)by Emily Shaffer(nasamuffin
) を参照してください。
( Junio C Hamano-gitster
- in commit f4f7e75 、09 Jul 2019)
rev-list
:パイピングを有効にするために--no-object-names
を教えるRev-listに、追加情報なしで非コミットオブジェクトのOIDのみ)を出力するオプションを与えることにより、
cat-file
による簡単な解析を許可します。
これは短期的なシムです。後で、rev-list
は、検出したオブジェクトのタイプをcat-file
のような形式で印刷する方法を教える必要があります。このコミットの前に、次のように、
rev-list
からの出力をcatファイルにパイプする前にマッサージする必要がありました。git rev-list --objects HEAD | cut -f 1 -d ' ' | git cat-file --batch-check
OIDの最後に不可視の空白が存在するため、ルートツリーを処理する場合、これは特に予想外でした。
git rev-list --objects --filter=tree:1 --max-count=1 HEAD | xargs -I% echo "AA%AA"
これで、追加されたテストケースのように、直接パイプすることができます。
git rev-list --objects --no-object-names HEAD | git cat-file --batch-check
それが次の違いです。
vonc@vonvb:~/gits/src/git$ git rev-list --objects HEAD~1..
9d418600f4d10dcbbfb0b5fdbc71d509e03ba719
590f2375e0f944e3b76a055acd2cb036823d4b44
55d368920b2bba16689cb6d4aef2a09e8cfac8ef Documentation
9903384d43ab88f5a124bc667f8d6d3a8bce7dff Documentation/RelNotes
a63204ffe8a040479654c3e44db6c170feca2a58 Documentation/RelNotes/2.23.0.txt
そして、--no-object-name
で:
vonc@vonvb:~/gits/src/git$ git rev-list --objects --no-object-names HEAD~1..
9d418600f4d10dcbbfb0b5fdbc71d509e03ba719
590f2375e0f944e3b76a055acd2cb036823d4b44
55d368920b2bba16689cb6d4aef2a09e8cfac8ef
9903384d43ab88f5a124bc667f8d6d3a8bce7dff
a63204ffe8a040479654c3e44db6c170feca2a58
別の便利なオプションは、git verify-pack -v <packfile>
verify-pack -v
は、データベース内のすべてのオブジェクトとそのオブジェクトタイプをリストします。