英文:
How to identify paths to files that were modified in the most recent git merge in bash or groovy?
问题
如何在Bash、Groovy或Jenkinsfile中识别最近的Git合并中已修改的文件路径?
在每次合并事件触发的Jenkins作业中,存在一个阶段,仅当最近的合并包含位于以下文件夹中的新文件(例如:new-file.yaml
)时,或者该文件夹中的已存在文件被修改时才会触发该阶段:
foo/env/<name-of-environment>/
英文:
How to identify path/s to file/s that was/were modified in the most recent git merge in Bash or Groovy or maybe there is any other way to do that in Jenkinsfile?
A Jenkins job is triggered on every merge event.
There is a stage that should be only triggered if the most recent merge includes a new file with an arbitrary name for example: new-file.yaml
in folder:
foo/env/<name-of-environment>/
or if an already existing file in that folder was modified.
答案1
得分: 2
以下是您要翻译的内容:
要获取在任意两个提交之间发生更改的文件列表,您可以使用:
git diff <commit1> <commit2> --name-only
对于合并提交,合并提交的ID将是 <commit2>
,其中一个父提交的ID将是 <commit1>
。大多数情况下,它将是合并提交的第一个父提交。例如,如果合并提交是提交 X
,则差异将是:
git diff X~1 X --name-only
要在特定分支上触发新提交时,您可以使用 HEAD
或 @
(在大多数 shell 中,包括 bash),因此一般语法是:
git diff @~1 @ --name-only
然后,您可以解析输出以获取所需的文件:
git diff @~1 @ --name-only | grep foo/env/test/
注意事项:
- 如果分支上可能出现多个提交而没有合并提交,那么此检查将无法完美工作。例如,假设可以将3个新的线性提交与快进合并一起合并;在这种情况下,对
@~1 @
进行差异处理将只显示顶部提交中的更改,而不是所有3个。如果这种情况可能发生,您可能需要保存上次运行检查的最后提交ID,并将其用作 commit1。如果在合并到目标分支时始终使用--no-ff
,它将始终强制生成合并提交,您将不会遇到此问题。 - 上面我说过,“大多数情况下它将是合并提交的第一个父提交。”它可能是第二个父提交的情况是,如果有人将目标分支合并到源分支,然后将源分支快进合并到目标分支。这将翻转合并提交的父级,并且通常是不被赞同的,但我提到它是因为它是一个常见问题。
- 一些工具将默认的拉取请求合并策略设置为始终强制生成合并提交,以避免#1和#2中描述的问题。
英文:
To get a list of files that changed between any two commits, you could use:
git diff <commit1> <commit2> --name-only
For a merge commit, the merge commit's ID would be <commit2>
and one of it's parent's commit ID would be <commit1>
. Most of the time it will be the first parent of the merge commit. So for example, if the merge commit is commit X
, the diff would be:
git diff X~1 X --name-only
For a trigger on a specific branch when new commits appear, you could use HEAD
or @
(in most shells, including bash), so the general syntax is:
git diff @~1 @ --name-only
You could then parse the output for your desired file:
git diff @~1 @ --name-only | grep foo/env/test/
Notes:
- If it's possible for multiple commits to appear on the branch without a merge commit, then this check will not work perfectly. For example, suppose 3 new linear commits could be merged in with a fast-forward merge; in this case diffing
@~1 @
will only show you changes in the top most commit, rather than all 3. If this is a possibility, you may need to save the last commit ID you ran your check on, and use that as commit1. If you always use--no-ff
when merging into the target branch, it will always force a merge commit and you won't have this issue. - Above I said "Most of the time it will be the first parent of the merge commit." The scenario where it could be the second parent would be if someone merged the target branch into the source branch, and then did a fast-forward merge of the source branch back into the target. This would flip the parents of the merge commit and is generally frowned upon, but I mention it since it's a common issue.
- Some tools have the default Pull Request merge strategy set to always force a merge commit, to avoid the issues described in #1 and #2.
答案2
得分: 1
在Jenkins中,您可以使用内置的changeset
条件:默认情况下,它以通配符作为参数。例如:
stage('A conditional stage') {
when { changeset 'foo/env/test/*' }
steps {
echo 'There was a change in that directory'
}
}
英文:
In Jenkins, you can use the built-in changeset
condition: by default, it takes a glob as a parameter. For example:
stage('A conditional stage') {
when { changeset 'foo/env/test/*' }
steps {
echo 'There was a change in that directory'
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论