Git: 编译 master,然后合并到 dev 而无需重新编译所有内容
Git: compile master, then merge into dev without recompiling everything
我正在开发一个大型开源项目,开发速度很快,编译时间很长。我的问题是关于如何在从 master 获取最新更改后最小化重新编译。
说我有
/--MyDev1
/
A (=master)
\
\--MyDev2
MyDev1 和 MyDev2 只涉及几个文件,所以如果我有 A、MyDev1 或 MyDev2 的编译版本,对其他任何一个进行检查并且 运行ning make 非常快。
几个星期过去了,master进步了很多,upstream了。几百
文件已更改:我检查 master,提取最新的更改,运行 制作,然后喝几十杯咖啡。
之后,我想进行合并,使世界看起来像
/--MyDev1--------MyDev1'
/ /
A----....---------B
\ \
\--MyDev2--------MyDev2'
但是,如果我只是这样做:
git 签出 MyDev1
git 合并大师
制作
然后make 会重新编译一切,因为A 和B 之间的所有文件都被触及了。喝那么多咖啡会生病的。
我想要的是合并来自 B,其中git只涉及A和MyDev1之间更改的文件(之后MyDev2也一样,可能会重新编译MyDev1 和 MyDev2 之间的所有内容)。
我不知道使用纯 git 的解决方案。 (可能 git 的设计甚至 none。)
但我有另一个解决方案,我经常使用:我在每次构建之前将代码同步到其他地方(我们称之为构建区域)。诀窍是,我让 rsync 根据校验和而不是时间戳(标志:-rlpgoDv --checksum --ignore-times
)确定要同步的文件。那我就只在构建区编译了。
一般来说,这不会加快速度,但至少对你的
git checkout MyDev1 && git merge master make
例子。在这种情况下,rsync 只会触及您的几个 MyDev1 文件。重新编译应该很快。
当 MyDev2 尚未合并而 MyDev1 已合并时,事情变得缓慢。在这种情况下,我建议每个分支一个构建区域(但这基本上需要每个分支一个主编译)。根据您的实际情况,至少有一个建议应该会有所帮助。
更新: 我一直在想:真正改变时间戳的是 git checkout MyDev1
,而不是合并(假设没有冲突)。如果你可以在另一个方向合并,你可以这样做(假设你在 master
并且刚刚喝了很多咖啡也就是编译):
git checkout master
git checkout -b tmp_merging_branch master
git merge MyDev1
git branch -d MyDev1
git branch -m MyDev1
这会保留时间戳,只要合并实际上不更改文件即可。没关系,因为无论如何都应该重建这些文件。好消息是,您可以为 MyDev2 重复该操作:初始 git checkout master
然后会保留 master
和 MyDev1
中相等的文件的时间戳。但它只有在可以接受类似
的情况下才有效
/ --- MyDev1 --- MyDev1' ------ MyDev1''
/ \ \
A --- .... ---------- B --- ... ----- C
\ / /
\ --- MyDev2 --- MyDev2' ------ MyDev2''
我正在开发一个大型开源项目,开发速度很快,编译时间很长。我的问题是关于如何在从 master 获取最新更改后最小化重新编译。
说我有
/--MyDev1
/
A (=master)
\
\--MyDev2
MyDev1 和 MyDev2 只涉及几个文件,所以如果我有 A、MyDev1 或 MyDev2 的编译版本,对其他任何一个进行检查并且 运行ning make 非常快。
几个星期过去了,master进步了很多,upstream了。几百 文件已更改:我检查 master,提取最新的更改,运行 制作,然后喝几十杯咖啡。
之后,我想进行合并,使世界看起来像
/--MyDev1--------MyDev1'
/ /
A----....---------B
\ \
\--MyDev2--------MyDev2'
但是,如果我只是这样做:
git 签出 MyDev1 git 合并大师 制作
然后make 会重新编译一切,因为A 和B 之间的所有文件都被触及了。喝那么多咖啡会生病的。
我想要的是合并来自 B,其中git只涉及A和MyDev1之间更改的文件(之后MyDev2也一样,可能会重新编译MyDev1 和 MyDev2 之间的所有内容)。
我不知道使用纯 git 的解决方案。 (可能 git 的设计甚至 none。)
但我有另一个解决方案,我经常使用:我在每次构建之前将代码同步到其他地方(我们称之为构建区域)。诀窍是,我让 rsync 根据校验和而不是时间戳(标志:-rlpgoDv --checksum --ignore-times
)确定要同步的文件。那我就只在构建区编译了。
一般来说,这不会加快速度,但至少对你的
git checkout MyDev1 && git merge master make
例子。在这种情况下,rsync 只会触及您的几个 MyDev1 文件。重新编译应该很快。
当 MyDev2 尚未合并而 MyDev1 已合并时,事情变得缓慢。在这种情况下,我建议每个分支一个构建区域(但这基本上需要每个分支一个主编译)。根据您的实际情况,至少有一个建议应该会有所帮助。
更新: 我一直在想:真正改变时间戳的是 git checkout MyDev1
,而不是合并(假设没有冲突)。如果你可以在另一个方向合并,你可以这样做(假设你在 master
并且刚刚喝了很多咖啡也就是编译):
git checkout master
git checkout -b tmp_merging_branch master
git merge MyDev1
git branch -d MyDev1
git branch -m MyDev1
这会保留时间戳,只要合并实际上不更改文件即可。没关系,因为无论如何都应该重建这些文件。好消息是,您可以为 MyDev2 重复该操作:初始 git checkout master
然后会保留 master
和 MyDev1
中相等的文件的时间戳。但它只有在可以接受类似
/ --- MyDev1 --- MyDev1' ------ MyDev1''
/ \ \
A --- .... ---------- B --- ... ----- C
\ / /
\ --- MyDev2 --- MyDev2' ------ MyDev2''