25

私は git に 2 つの開発ブランチを持っており、2 つの間で頻繁に変更する必要があります。ただし、本当にイライラするのは、git でブランチを変更するたびに、一部のファイルのファイル システムのタイムスタンプが変更されるため、プロジェクト全体が再構築されることです。

多くの場合、メイクファイルは、プロジェクトを 2 つの異なるビルド ディレクトリにビルドするように構成されています。

これを回避する方法はありますか?コンパイルは非常に長く、時間のかかるプロセスです...

編集:-これは質問のもう少し詳細な説明です...他の多くのファイルに含まれているヘッダーファイルBasic.hがあるとします。Basic.h はブランチ 1 とブランチ 2 で異なります。

ここで、ブランチ 1 を build_branch1 に、ブランチ 2 を build_branch2 にコンパイルしたとします。ブランチ 2 が現在チェックアウトされているとします。次に、ブランチ 1 をチェックアウトし、File1.cpp を変更して再コンパイルします。理想的には、前回コンパイルしてから File1.cpp だけが変更されているため、再コンパイルする必要があるのはこのファイルだけです。

ただし、チェックアウトにより Basic.h のタイムスタンプが変更されているため、Basic.h を含むすべてのファイルが再コンパイルされます。これは避けたい。

4

5 に答える 5

15

Gitは、ブランチ間で更新されるファイルのみを変更します。ただし、単一のファイルが変更された場合でもコンパイラが完全な再構築を行う場合は、いつでも異なるブランチを異なるディレクトリに複製してチェックアウトできます。それは次のようなものです:

/your-repo-name.branch1
/your-repo-name.branch2

これには余分なディスク容量が必要ですが、巨大なリポジトリで分岐ブランチを切り替えるよりもはるかに便利です。

于 2012-04-27T18:52:46.263 に答える
11

別の部分的な答え: コンパイラ キャッシュ。

元のブランチに戻って再構築すると、依存関係には、依存する多数のファイルを再構築するBasic.h必要があることが示されていますが、オブジェクト ファイルはコンパイラ キャッシュから取得できます。

ccache( http://ccache.samba.org/ ) はまだかなり高価な作業 (翻訳単位全体がハッシュ キーを使用するため、前処理された翻訳単位の処理) を行う必要がありますが、コンパイルよりもはるかに安価です。

場合によってccacheは、いくつかの空白の変更など、コンパイルに影響を与えない変更に直面してコンパイルを排除できます。たとえば、依存ファイル (ヘッダーまたはソース) のコメントを変更しても、キャッシュされたオブジェクト ファイルは無効になりません。

git pullそのため、これまでに見たことのない新しい変化を見つけた場合でも役立ちますBasic.h

于 2012-04-27T23:43:51.187 に答える
4

実際にコンパイルが必要なファイルがわかっていて、それらを手動で行う場合、GNU Make(少なくとも他の実装についてはわかりません)にはフラグがあります。-tこれは基本的にMakefileを実行し、コマンドを実行する代わりにタイムスタンプを変更します。

このフラグを使用する前に、更新が必要なファイルを更新する必要があります。そうしないと、正当に古くなっているが更新されているように見えるオブジェクトファイルになってしまいます。詳細については、リンクされたドキュメントを参照してください。

ブランチを切り替えるときの変更の量によっては、この-oオプションも興味深い場合があります。

于 2012-04-27T18:53:20.947 に答える
3

ブランチ間で実際に異なる場合Basic.h、唯一の修正は、より細かい依存関係を持つ小さなファイルに分割することです。これにより、変更時に再構築されるものが少なくなります。

しかし、Basic.h実際にはブランチ間でまったく同じであるがgit、タイムスタンプが変更されているとします。touch Basic.hこれは、タイムスタンプ ベースのビルド システムの制限を明らかにするような、誤ったトリガーです。理想的には、タイムスタンプが変更されたときではなく、コンテンツが変更されたときにビルド システムを再構築する必要があります。タイムスタンプが使用されるのは、コンテンツの変更を検出する安価な代替手段であるためです。優れた方法は、タイムスタンプに関係なく、ビルド システムがすべてのファイルのハッシュを保持し、実際の変更を検出することです。これにより、「クロック スキューが検出されました。ビルドが不完全である可能性があります」などの問題も修正されます。

この種のビルド システムを Make から入手することはできません。ただし、特定のファイルに関しては、その一部を操作できる場合があります。たとえば、オブジェクト ファイルが直接依存するのではなく、スタンプ ファイルである に依存するように Make ルールを記述できBasic.hますBasic.h.sha。さて、何が入っていBasic.h.shaますか?このファイルには、 の SHA256 ハッシュが含まれていますBasic.h

Make を実行するたびに、Makefile のロジックがハッシュを計算し、Basic.hそれを に格納されているハッシュと比較しBasic.h.shaます。異なる場合Basic.h.shaは、新しいハッシュで上書きされます。これにより、そのタイムスタンプがバンプされ、再構築がトリガーされます。

BASIC_H_SHA := $(shell sha256sum Basic.h)
BASIC_H_SHA_OLD := $(shell cat Basic.h.sha)

ifneq ($(BASIC_H_SHA),$(BASIC_H_SHA_OLD))
$(info Basic.h has changed!)
DUMMY := $(shell echo "$(BASIC_H_SHA)" > Basic.h.sha)
endif

これらの行に沿ってロジックを実装し、それぞれの変更に依存するモジュールを作成しましたCFLAGS基本的に、何かの変更を、ビルドされるものを制御するタイムスタンプ ファイルのタッチに変えることができます。

于 2012-04-27T21:55:50.803 に答える
2

タイムスタンプを保持し、ビルド環境で問題が発生しないようにする良い方法はありません。git clone / git checkout branchB を使用して、ブランチ B をビルドして操作するための 2 番目の作業ディレクトリを作成します。Makefile で両方をビルドしないでください。それぞれを独自のビルド ディレクトリにビルドします。

于 2012-04-27T18:54:44.243 に答える