TLDR
It is not working because due to the way Travis clones repositories, the
branches don't exist locally. You need to pull them first.
In my travis build script, I call this function that allows me to pull all the
branches. Adapt it according to your need.
function create_all_branches()
{
# Keep track of where Travis put us.
# We are on a detached head, and we need to be able to go back to it.
local build_head=$(git rev-parse HEAD)
# Fetch all the remote branches. Travis clones with `--depth`, which
# implies `--single-branch`, so we need to overwrite remote.origin.fetch to
# do that.
git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch
# optionally, we can also fetch the tags
git fetch --tags
# create the tacking branches
for branch in $(git branch -r|grep -v HEAD) ; do
git checkout -qf ${branch#origin/}
done
# finally, go back to where we were at the beginning
git checkout ${build_head}
}
Explanation
How Travis clones repositories
We can see in Travis logs which commands are run when it clones the repositories. It is slightly different for regular branches and for pull requests.
For a Pull Request:
# Clone the repository (note the --depth option) in ./user/repo
git clone --depth=50 https://github.com/user/repo.git user/repo
# Go the repository
cd user/repo
# Fetch the reference to the pull request
git fetch origin +refs/pull/22/merge:
# Checkout the HEAD of the reference we just fetched. In other words,
# checkout the last commit of the PR. For details about FETCH_HEAD see
# https://stackoverflow.com/a/9237511/1836144
git checkout -qf FETCH_HEAD
For a regular branch (called mybranch
in this example):
# Clone the repository (note the --depth option) in ./user/repo
# This time, we also have the --branch option
git clone --depth=50 branch=mybranch https://github.com/user/repo.git user/repo
# Go the repository
cd user/repo
# Checkout the HEAD of the branch we just fetched
git checkout -qf 7f15290cc343249217a9b3669975705a3dc5bd44
In both case the --depth
option is used when the repository is cloned, which implies --single-branch
. Here is what git
says about --single-branch
:
Clone only the history leading to the tip of a single branch, either specified by the --branch option or the primary branch remote’s HEAD points at. Further fetches into the resulting repository will only update the remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when --single-branch clone was made, no remote-tracking branch is created.
In other words, only one remote branch was fetched. Worse, git fetch
won't
even fetch the other branches.
How to pull all the remote branches
This answer explains how to make git fetch
work again:
git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
Now, git fetch
should fetch all the remote branches, but we are still not done: we want remote-tracking branches to be created. For this, we can do git checkout
for each branch we just fetched:
for branch in $(git branch -r|grep -v HEAD) ; do
git checkout ${branch#origin/}
done