Setting an environment variable with `git diff master` fails

I have an environment variable set up like this in .travis.yml:

env:
  global:
    - DIFF=`./bench/scripts/diff.sh | paste -s -d, -`

and ./bench/scripts/diff.sh looks like this:

#!/usr/bin/env bash

CHANGED_FILES=`git diff --name-only master src/`

for CHANGED_FILE in $CHANGED_FILES; do
  echo ../$CHANGED_FILE
done

Ordinarily, this works fine but for some branches, Travis doesn’t recognize master and fails with this:

fatal: ambiguous argument ‘master’: unknown revision or path not in the working tree.
Use ‘–’ to separate paths from revisions, like this:
‘git […] – […]’

Is master (the target branch) not guaranteed to exist? Is a repository not necessarily cloned by the time items under env are set?

Is master (the target branch) not guaranteed to exist?

Exactly. Travis CI doesn’t clone the whole repository, but only a shallow clone of a branch to be built.

Is there a configuration step to ensure a clone that contains the target branch to diff against is performed?

Is there a configuration step to ensure a clone that contains the target branch to diff against is performed?

Not that I’m aware of, but of course you can run any commands in
.travis.yml or in your script, including a git fetch to
(preferably shallow) fetch the master branch.

Have you tried reproducing this issue with a fresh clone locally?

Hi @tristen

Following page might be helpful for you.

Disabling git --depth option

Have you tried reproducing this issue with a fresh clone locally?

I have and have not been able to recreate this error locally. master exists and git diff --name-only master src/ in my feature branch correct report the file-paths that have changed.

Thanks for the suggestion. I am still running into the same ambiguous argument 'master' with this change in .travis.yml:

before_script:
  - git remote set-branches --add origin master
  - git fetch
  - npm run build

I wanted to try and not rely on an environment variable so npm run build runs a node script that executes this (which continues to throw the error)

const { execSync } = require('child_process');

const diffCommand = `
  CHANGED_FILES=\`git diff --name-only master src/\`

  for CHANGED_FILE in $CHANGED_FILES; do
    echo $(basename $CHANGED_FILE .js)
  done
`;

console.log(execSync(diffCommand).toString().trim().split('\n')); // Throws error

Thanks for the suggestion. I am still running into the same ambiguous argument 'master' with this change in .travis.yml:

before_script:
  - git remote set-branches --add origin master
  - git fetch

The output of the above command should be visible in the job’s log,
and should look like this:

git fetch
From https://github.com/....
 * [new branch]        master     -> origin/master

So while it does fetch the remote’s master branch, it does not
create a master branch in the local repository, but stores it under
refs/remotes/origin/master, because that’s what the previous git remote ... command told it to do.

You could either:

  • Leave your before_script as is, and update your other script to
    diff against origin/master instead.

  • Update your before_script to run git fetch --depth=50 origin refs/heads/master:refs/heads/master.

1 Like

This is also a possible solution for others who might want to try something else:

Imprint