我有一个非常大的存储库,其中包含许多应用程序/服务。例如,有一些用C#编写的Windows服务,一个JS / HTML Web客户端,节点应用程序和其他应用程序。
当我标记新版本时,我想以编程方式找到基于前一个标记的diff标记哪些需要部署。
对于某些应用程序,它很简单,只需检查存储库子文件夹中的更改即可。例如,Web客户端全部位于src/clients/web
中。但是C#服务使用一些共享的C#库,这些库不在这些服务的文件夹中。这些依赖关系会随着时间而变化,因此我只能真正依靠csproj
文件中的引用。
是否有针对此问题的一般(或部分)解决方案?
答案 0 :(得分:1)
对该问题的更一般的解决方法是使用:
这样,当您将新标签放入父存储库时,您可以:
git submodule update -remote
以确保您拥有所有子模块的最后一个(主)git diff
,以立即查看哪个子存储库已更改。 答案 1 :(得分:0)
有一个蛮力解决方案,该解决方案将生成两次,以查找更改的文件时间戳:
git checkout <old tag>
msbuild ...
record_all_final_outputs_timestamps > old_timestamps.txt
git checkout <new tag>
msbuild ...
record_all_final_outputs_timestamps > new_timestamps.txt
diff old_timestamps.txt new_timestamps.txt
差异将显示增量构建后实际更改的所有库。 C#具有相对较快的构建,这可能会使此方法可以接受。
答案 2 :(得分:0)
只要git跟踪所有可能表明需要重新部署的文件,这实际上就很容易。正如Yazeed Sabri在评论中已经提到的那样,您可以通过执行以下命令来获取已修改,已添加或已删除文件的完整列表:
git diff --name-only <oldtag> <newtag>
添加-z
以NUL字节代替默认换行符来分隔文件名;这也可以防止git在路径名中引用任何“不寻常的”字符。
您可以通过提供一个或多个路径来进一步优化文件列表:
git diff --name-only <oldtag> <newtag> -- <path_1> <path_2> <path_n>
这只会返回您提供的<path>
之一以下的那些文件。请注意,命令行上的<path>
是相对于当前工作目录的,但是git diff
输出的路径是相对于git存储库的根的。
如果您只对某些变化感兴趣,而对变化不完全感兴趣,则可以使git diff
保持沉默,并使用其退出状态,如下所示(shell):
if ! git diff --quiet "$oldtag" "$newtag" -- src/app_1 app_1.csproj
then
redeploy app_1
fi
请注意此处的!
;如果提供的路径在给定标记之间未更改,则git diff --quiet
以0退出(表示shell逻辑成功),但是我们希望在路径重新配置后重新部署。 (此行为与标准Linux diff
命令一致。)
答案 3 :(得分:0)
我会使用@VonC的建议布局,但是有了您的存储库,核心命令就是您想要的,git diff-tree
不会自动为您递归,因此它只会列出哪些顶级条目已更改:
git diff-tree @ @~
如果不需要检查哪些条目是目录,可以使用--name-only
。要在存储库中还拥有要忽略的顶级文件的
git diff-tree @ @~ | awk '$1":"$2 ~ /:04/'