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"]
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
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
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)
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 thepath
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.
Thanks a lot for your answer
I have tested this using
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 ?
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.Indeed
I tweaked a bit my solution as it was not working in all cases but now it does.
Thanks for your reply