29

On the install step, Travis CI clones the repo, which looks similar to this:

git clone --depth=50 --branch=master https://github.com/user/repo.git user/repo

How can I customize / override this?


Background: I am using tag based deploys. The way Travis checks out tagged builds (--branch=<tagname>), the git repository is in a detached state without access to branches. However, for deployment I need to know on which branch I am. My solution is to do a "normal" clone and then switch to the tagged commit.

ericteubert
  • 4,531
  • 3
  • 31
  • 35

8 Answers8

17

You can clone the repository again in the install step. That way you clone the repository twice, but it seems to work.

# .travis.yml
install:
  - git clone https://github.com/$TRAVIS_REPO_SLUG.git $TRAVIS_REPO_SLUG
  - cd $TRAVIS_REPO_SLUG
  - git checkout -qf $TRAVIS_COMMIT
ericteubert
  • 4,531
  • 3
  • 31
  • 35
  • 2
    Use `git clone git@github.com:${TRAVIS_REPO_SLUG}.git` if you're re-cloning a private repo with ssh,. – Derek Soike Sep 27 '17 at 18:59
  • This is probably a bad idea because Travis config (`.travis.yml`) will be read from the previously checked out commit, as it's read before the install step, so before we checkout a different commit where the config file may have been changed. – Oliver Joseph Ash Mar 19 '20 at 20:13
12

Per the Travis docs you can add the following to your .travis.yml to remove the --depth flag:

git:
  depth: false

As --depth implies --single-branch, removing this flag means that all branches will be checked out, which isn't the default behaviour.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
3

I found that in order to get access to your whole repo you need the following:

install:
  - git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
  - git fetch --unshallow --tags

This way you'll have access to remote branches and tags (e.g. can do checkout).

If you're on a tag but no longer want to be in a detached HEAD state you can create a new branch that points to the tag (according to this discussion):

install:
  - git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
  - git fetch --unshallow --tags
  - git symbolic-ref --short HEAD || git checkout -b ${TRAVIS_BRANCH}-test $TRAVIS_BRANCH

Note: git symbolic-ref --short HEAD will fail if you're in a detached HEAD state.

thisismydesign
  • 21,553
  • 9
  • 123
  • 126
2

The problem is not really that you are in a detached branch. It is that git does not allow you to fetch the tags: git fetch --tags will only fetch the branch spcified by --branch in the git clone command you gave.

I explain this in more details this answer.

To solve you issue (checking out a specific tag) you can call a script that looks like this, after the repo is cloned:

    # Keep track of where Travis put us.
    # We are on a detached head, and we need to be able to go back to it.
    build_head=$(git rev-parse HEAD)

    # fetch the tags
    git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
    git fetch --tags

    # checkout the tagged commit
    git checkout -qf <your tag>

    # now do your stuff

    # go back to where we were at the beginning
    git checkout ${build_head}
Community
  • 1
  • 1
little-dude
  • 1,544
  • 2
  • 17
  • 33
1

Run this during your build to have access to origin tags / branches

git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" 1>/dev/null
git fetch origin -q

After that you can run this command to find branches containing your commit

BRANCHES=`git branch -a --contains "$TRAVIS_TAG"`

I've created a script a loooong time ago to fetch the 'environment' branch where the tag was created for continuous deployment purpose.

It may inspire you: https://gist.github.com/rolebi/a0eb1f783b7f3a5f21a631c8da1582dc

Use it like that:

TARGET_ENV="`test $TRAVIS_TAG && bash scripts/get_branch_for_git_reference.sh $TRAVIS_TAG`"
rolebi
  • 1,181
  • 9
  • 13
1

Disable git clone and then clone the repository again in the install step. The repository will be cloned only once in this way. In this "normal" clone you will able to do what ever you want.

git:
  clone: false
install:
  - git clone https://github.com/$TRAVIS_REPO_SLUG.git $TRAVIS_REPO_SLUG
  - cd $TRAVIS_REPO_SLUG
Arafat Hasan
  • 2,811
  • 3
  • 21
  • 38
0

Or you could just query the remote. Add the following to .travis.yml:

env:
    global:
        # get all the branches referencing this commit
        - REAL_BRANCH=$(git ls-remote origin | sed -n "\|$TRAVIS_COMMIT\s\+refs/heads/|{s///p}")

        # or check if we are on a particular branch:
        - IS_RELEASE=$(git ls-remote origin | grep "$TRAVIS_COMMIT\s\+refs/heads/release$"

(I am surprised that the git gurus hadn’t come up with this one already)

Aryeh Leib Taurog
  • 5,370
  • 1
  • 42
  • 49
  • But it only works, if the tag is on the latest commit on the branch you check. When the master branch is already ahead some commits, this gives you only `refs/tags/your-tag`. – Ethan Leroy Jan 03 '19 at 13:13
-1

You can convert the already existing shallow clone to a full clone. To do so execute git fetch --unshallow (available since git version 1.8.3) during the install step.

# .travis.yml
install:
  - git fetch --unshallow --tags

The --tags flag forces to fetch all tags even if they don't belong to the checked out branch. This is needed if your build also depends on tags from other branches.

Florian Dreier
  • 419
  • 6
  • 9
  • 6
    that does not work because Travis clones the repositories with `--depth`, which implies `--single-branch`. `git fetch` will only fetch the branch that was cloned. – little-dude May 18 '17 at 00:08