Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you merge into another branch using travis with git commands?

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!

like image 896
ipalibowhyte Avatar asked Dec 21 '15 22:12

ipalibowhyte


1 Answers

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
like image 153
little-dude Avatar answered Sep 21 '22 13:09

little-dude