I am trying to add a feature to my devstack to add auto deploy when a travis test passes on a branch called travis. After this test passes, I want to merge this travis branch into master branch and push to the master branch.
So far, when I push to travis branch, travis runs the test and everything succeeds but I am having problems with my git commands in after_success
in my travis.yml file.
travis.yml
- "npm i -g jasmine-node"
-after_success:
- "git fetch"
- "git checkout master"
- "git merge travis"
- "git push origin master"
branches:
only:
- travis
This is the output on travis console:
error: pathspec 'master' did not match any file(s) known to git.
fatal: 'travis' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Thank you so much!
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}
}
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With