gitazure-pipelinesazure-pipelines-yamlgit-diff

How to git diff on an Azure DevOps CI pipeline with more than one repository


There are a few helpful [questions and answers][1] online,

[1]: How to git diff on a Azure CI pipeline, but they seem to be working in a single-repository environment. I'm using one git repository for the project source, another for a department-wide YAML code repo that covers several projects.

My current challenge is getting a list of changed files as a result of a PullRequest, IndividualCI, or BatchCI Build.Reason for the product repo. The list is needed for a CI static code analysis.

Using git diff --name-only HEAD^ HEAD (or HEAD~ HEAD or @~ @) all give me fatal: not a git repository (or any of the parent directories): .git

With two repositories, the Build.SourceDirectory gets the name of the repositories appended, but I haven't been able to find for to use that information (e.g. \agent\_work\1\s\foo) in or before the git diff call.

Has anyone come across that problem, or any suggestions for a solution?


Solution

  • Assuming you have defined additional repository resource(s) in your YAML pipeline to be consumed together with the self repo, and according to the document,

    Unless a path is specified in the checkout step, source code is placed in a default directory. This directory is different depending on whether you are checking out a single repository or multiple repositories.

    Multiple repositories: If you have multiple checkout steps in your job, your source code is checked out into directories named after the repositories as a subfolder of s in (Agent.BuildDirectory). If (Agent.BuildDirectory) is C:\agent\_work\1 and your repositories are named tools and code, your code is checked out to C:\agent\_work\1\s\tools and C:\agent\_work\1\s\code,

    Therefore, you may try the sample YAML pipeline below to run git diff in different repo paths on that agent machine.

    resources:
     repositories:
       - repository: RepoA
         name: RepoA
         type: git
    
    variables:
      RepoA.name: $[ resources.repositories.RepoA.name ]
      RepoA.ref: $[ resources.repositories.RepoA.ref ]
      RepoA.version: $[ resources.repositories.RepoA.version ]
    
    steps:
    # Set fetchDepth as 0 to disable the dault shallow fetch 1
    - checkout: self
      fetchDepth: 0
    - checkout: RepoA
      fetchDepth: 0
    - script: |
        echo "================ 1. Show file structure in Pipeline.Workspace ================"
        tree $(Pipeline.Workspace)
        
        echo "================ 2. Show self repo info and run git diff ================"
        cd $(Agent.BuildDirectory)/s/$(Build.Repository.Name)
        echo "self repo name: $(Build.Repository.Name)"
        echo "self repo ref: $(Build.SourceBranch)"
        echo "self repo commit version: $(Build.SourceVersion)"
        git diff --name-only $(Build.SourceVersion)^ $(Build.SourceVersion)
        
        echo "================ 3. Show $(RepoA.name) info and run git diff ================"
        cd $(Agent.BuildDirectory)/s/$(RepoA.name)
        echo "RepoA name: $(RepoA.name)"
        echo "RepoA ref: $(RepoA.ref)"
        echo "RepoA commit version: $(RepoA.version)"
        git diff --name-only $(RepoA.version)^ $(RepoA.version)
      displayName: Run git diff in multiple repo paths
    

    Image