4

関連する質問:なぜ Git はオリジン マスターをプッシュするたびにリポジトリ全体を送信するのですか?

短いバージョン: 2 つの Git リポジトリで作業している場合、コミット オブジェクトの 99% が同一であっても、がリポジトリAを指すように設定されているときにコミットをリポジトリBgit pushに送信するために使用すると、すべてのオブジェクト (200MB +) が転送されます。origin

より長いバージョン:継続的インテグレーション サーバーに 2 つ目の Git リポジトリをセットアップしました。コミット オブジェクトをローカルで準備した後、通常のように直接origin/masterプッシュするのではなく、この 2 番目のリポジトリのブランチに変更をプッシュします。CI サーバーは新しいブランチを取得し、それを に自動リベースしmaster、統合テストを実行します。すべて問題なければ、ブランチをorigin/masterマスター リポジトリにプッシュします。

また、誰かが CI プロセスを迂回して直接プッシュした場合に備えて、CI サーバーはマスター リポジトリからgit fetchの最新のコピーを取得するために定期的に呼び出します。origin/master

これは、特にgit fetch; git rebase origin/masterCI リポジトリにプッシュする前に a を実行した場合に、うまく機能します。Git は、まだ にないコミット オブジェクトのみを送信しますorigin/master。プッシュする前にフェッチ/リベースのステップをスキップしても、プロセスは引き続き機能しますが、Git は、すべてではないにしても、大部分のコミット オブジェクトを CI リポジトリに送信しているように見えます。現在、200MB 以上の価値があります。(レポの新しいクローンは 225MB でクロックインします。)

私たちは何か間違ったことをしていますか?Git が CI リポジトリでブランチを形成するために必要なコミット オブジェクトのみを送信するように、この動作を修正する方法はありますか? 明らかに pre-push を実行することで問題を回避git fetch; git rebase origin/masterできますが、特にマスター リポジトリに直接プッシュしても同じ問題が発生しないため、その手順をスキップできるはずです。

私たちのリポジトリは Gitosis 0.2 によって提供されており、クライアントは圧倒的に msysgit 1.7.3.1-preview を実行しています。

4

3 に答える 3

2

この問題の最も簡単な解決策、プッシュの直前にフェッチすることです。

$ git fetch origin master
$ git push user@host:repo.git HEAD:refs/heads/commit128952690069

この場合、特定のブランチをFETCH_HEAD;にフェッチすることが重要です。このようにして、ユーザーのローカルブランチの状態は影響を受けませんが、メインリポジトリから最新のオブジェクトセットを受け取ります。以下git pushは、Gitがオブジェクトのパックを開始するときに、常に祖先コミットが存在するようにします。

私はいくつかのツールを使っていくつかのツールを実行しましたgit pack-objects:コミットを含むパックファイルをビルドする<common_ancestor>..HEADと、必要な量のデータのみがパックされます:

$ echo $(git merge-base master origin/master)..HEAD | git pack-objects --revs --thin --stdout --all-progress-implied > packfile

git pushただし、リポジトリを同じ状態で発行すると、すべてのオブジェクトがパックされて送信されます。

Gitリポジトリに接続すると、リポジトリ内の最新リビジョンのSHAを受信するのではないかと思います。GitにそのSHAによって表されるコミットオブジェクトがローカルにないgit merge-base場合、共通の祖先を判別するために実行することはできません。したがって、すべてのオブジェクトをリモートリポジトリに送信する必要があります。そのコミットオブジェクトが存在する場合、それはgit merge-base成功し、共通の祖先を参照してパックファイルを構築できます。

于 2010-11-12T02:37:07.223 に答える
2

master...それを...に自動リベースします

そこが問題の根本だと思います。CI サーバーがこの自動リベース ステップを実行するたびに、現在のブランチとマスター ブランチの最も近い共通の祖先に関連するまったく新しいコミット セットが作成されます。

次にコードを CI サーバーにプッシュすると、実際にはこれらすべてのオブジェクトがなくなっているため (ライブ ヘッドからは到達できません)、クライアントにすべてのオブジェクトを再度送信するように要求します。

作成しているコミットの SHA1 コミット ID を監視することで、これが起こっていることを確認できるはずです。おそらく、ローカル コミットのコミット ID が、CI サーバー上のリベース ブランチの対応するコミット ID と一致しなくなっていることに気付くでしょう。

于 2010-11-05T00:23:34.027 に答える
0

ローカル リポジトリが CI サーバー リポジトリと同期していないようです。CI サーバーへのプッシュがこれを行うという事実は、ローカル リポジトリに異なるコミット ハッシュのセットがあることを意味します。次のようになります。

gitクローンマスター
(... 仕事する ...)
git push ci ブランチ
(... CIは、プッシュしたすべてのコミットハッシュを変更するリベースを行います..)
(... CI はそのテストを行い、マスターにプッシュします ...)
(... master と CI は一致しますが、プッシュしたすべてのコミットのハッシュは
     ローカルマシン以外には存在しません...)
(... 仕事する ...)
git push ci ブランチ

その最後のプッシュには、最初のプッシュからのコミットのセット全体が含まれます。これは、CI のリベースによってすべてのハッシュが変更され、作成した元のコミットを引き続き処理しているためです。

于 2010-11-05T16:51:23.127 に答える