Search code examples
bashgitjenkinsgroovycontinuous-integration

How to identify paths to files that were modified in the most recent git merge in bash or groovy?


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.


Solution

  • 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:

    1. 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.
    2. 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.
    3. 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.