Git-查找回购中哪些应用已更改

时间:2019-07-12 11:32:19

标签: git deployment continuous-integration continuous-deployment

我有一个非常大的存储库,其中包含许多应用程序/服务。例如,有一些用C#编写的Windows服务,一个JS / HTML Web客户端,节点应用程序和其他应用程序。

当我标记新版本时,我想以编程方式找到基于前一个标记的diff标记哪些需要部署。

对于某些应用程序,它很简单,只需检查存储库子文件夹中的更改即可。例如,Web客户端全部位于src/clients/web中。但是C#服务使用一些共享的C#库,这些库不在这些服务的文件夹中。这些依赖关系会随着时间而变化,因此我只能真正依靠csproj文件中的引用。

是否有针对此问题的一般(或部分)解决方案?

4 个答案:

答案 0 :(得分:1)

对该问题的更一般的解决方法是使用:

  • 每个程序/库/模块一个Git存储库
  • 一个父存储库引用了这些存储库as submodules

这样,当您将新标签放入父存储库时,您可以:

  • 首先执行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/'