DEV Community

Martin Ratinaud
Martin Ratinaud

Posted on • Edited on

Fetch several branches locally in GitHub actions

Edited

Working on Open Terms Archive, I recently needed to fetch both the main branch and my current branch locally in order to make a programmatic git diff on a file.

Unfortunately, GitHub Actions only allows the local fetch of one branch at a time, and even though such a syntax:

- uses: actions/checkout@v2
  with:
    fetch-depth: 0 # fetch all history for all branches and tags
  fetchLocal: ["main"]
Enter fullscreen mode Exit fullscreen mode

would have been great, it does not exist.

NOTE: fetch-depth: 0 will fetch all the branches and will make them available on remotes/origin/<branch> but my script used the local branch main so I had to map it locally

So here is how fetching 2 branches locally can be done:

Solution

Thanks to Matti

- uses: actions/checkout@v2
  with:
    fetch-depth: 0 # fetch all history for all branches and tags
- run: git branch main remotes/origin/main
Enter fullscreen mode Exit fullscreen mode

Other workaround

I keep it here as it shows how to retrieve the current branch name on both push and pull_request events (which I did not see anywhere).
But you should definitely use the above solution

- name: Get branch name
  run: |
    if [ -z $GITHUB_HEAD_REF ]; then BRANCH=$GITHUB_REF_NAME; else BRANCH=$GITHUB_HEAD_REF; fi
    echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- uses: actions/checkout@v2
  with:
    ref: main
    fetch-depth: 0 # fetch all history for all branches and tags
- run: git checkout --force -B $BRANCH refs/remotes/origin/$BRANCH
Enter fullscreen mode Exit fullscreen mode

Conclusion

This way, both branches are available locally for the diff.

Who am I?

My name is Martin Ratinaud and Iโ€™m a senior software engineer and remote enthusiast, contagiously happy and curious.
I create websites like this one for staking crypto and many more...

Check my LinkedIn and get in touch!

Top comments (4)

Collapse
 
cicirello profile image
Vincent A. Cicirello • Edited

You can actually use the checkout action multiple times in the same workflow. Here are a couple examples. In this workflow the first checkout is for the default branch, but then the second uses checkout for a branch named badges where I store coverage badges. In that one you'll notice the path input to the checkout action allows specifying a directory for the result of the checkout.

In this second example, the first checkout is again the default branch. But the second is for the gh-pages branch so the workflow can deploy documentation to GitHub Pages served from that branch.

In both of those examples I'm nesting the second checkout inside the other. The docs for the checkout action also explain how to do the same thing but with the branches side by side in different directories rather than nested, if you'd prefer that.

Collapse
 
martinratinaud profile image
Martin Ratinaud

Thanks a lot for your answer

I have tested this using

- uses: actions/checkout@v2
   with:
     ref: main
- uses: actions/checkout@v2
Enter fullscreen mode Exit fullscreen mode

Which from what I understand should fetch main and then my current branch but as you can see here, it does not work as main branch is not present in the repo.

Or am I mistaking ?

Collapse
 
cicirello profile image
Vincent A. Cicirello

I reread your post for the reason you are checking out multiple branches, to do a git diff on a file. You might need to use your current approach for that. My prior suggestion works well for a case where your workflow uses contents of one branch to produce contents for another (e.g., running javadoc on sourcecode from main branch but pushing the html generated by javadoc to gh-pages branch instead of back to main).

But I now don't think there is a way to adapt to your use-case. Without using the path input to the checkout action, the second checkout will clobber the first. I believe it will be as if you only did the second one. And checking out each branch to different paths probably won't help you do what you want to do.

Thread Thread
 
martinratinaud profile image
Martin Ratinaud

Indeed

I tweaked a bit my solution as it was not working in all cases but now it does.

Thanks for your reply