1

I am trying to use the git rev-list command in a repo that I have setup a sparse checkout in. Repo was set up as follows:

mkdir -p /opt/apcu
git -C /opt/apcu/ init
git -C /opt/apcu/ remote add -f origin git@github.com:krakjoe/apcu.git
git -C /opt/apcu/ config core.sparseCheckout true
echo "apc.php" >> /opt/apcu/.git/info/sparse-checkout
git -C /opt/apcu/ config branch.master.remote origin
git -C /opt/apcu/ config branch.master.merge refs/heads/master
git -C /opt/apcu/ pull origin

Now I would like to check for any changes in the repo:

$ git rev-list HEAD...origin
fatal: ambiguous argument 'HEAD...origin': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Any idea why I am getting the above error?

This is the bash script that is failing for me. The idea was to check for any changes to the remote repos and then pull them down. The reason I go through the trouble of checking for commits is because another function in the script runs an installation depending on what is updated.

# Do not fetch or pull "master" this is not always the default branch you have checked out.
# Omitting the branch to fetch or pull will pull the default.
for i in "${repo_array[@]}"; do
    git -C "$i" fetch origin &>/dev/null
    # Get rid of errors because git reports differences in repo as errors.
    commits=$(git -C "$i" rev-list HEAD...origin --count 2>/dev/null)

    if (( commits != 0 )); then
        git -C "$i" pull origin &>/dev/null
        # Run the installer function to install new versions
        installer
    fi
done 
steveH
  • 155
  • 2
  • 9

2 Answers2

1

origin is not a reference, but a remote URL

For instance: origin/master would be a reference to the last fetched remote master HEAD.

git rev-list HEAD...origin/master

In your case, since master is not always the branch you are pulling, you would use:

commits=$(git -C "$i" rev-list HEAD...@{u} --count 2>/dev/null)

With @{u} (or @{upstream}) being the shortcut for the upstream branch associated with the current branch.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • So if I had a different branch than `master` checked out I would need to do: `git rev-list HEAD...origin/v3.3/dev` – steveH Apr 05 '20 at 15:24
  • @steveH After a fetch, yes: https://stackoverflow.com/a/10685691/6309. After a pull, this is trickier: https://stackoverflow.com/a/12631371/6309 – VonC Apr 05 '20 at 15:26
  • I updated my question to help show the code that I am trying to run. Thanks for all the help. – steveH Apr 05 '20 at 15:50
  • @steveH I know: I have already updated the answer accordingly. – VonC Apr 05 '20 at 15:53
0

Note that origin can mean origin/HEAD, which can be a symbolic reference pointing to one of your other origin/* remote-tracking names. If origin/HEAD exists, and you use the name origin by itself the way you are doing,1 See the gitrevisions documentation, and in particular the six-step process for resolving a revision specifier; note that step 6 consists of adding ref/remotes/ to the front, and /HEAD to the end, of whatever name you provided and attempting to look that up.

Having run git remote add origin, you can run git remote set-head origin (with whatever options you like) to set the refs/remotes/origin/HEAD symbolic reference. But unless you really want to query the remote Git to set your refs/remotes/origin/HEAD to match their HEAD, it's almost certainly much better to just use an explicit origin/master, or origin/other-specified-name, here. In fact, in a script, it's wise to use fully-qualified names: refs/remotes/origin/master, for instance.

Using the @{upstream} or @{u} modifier on a branch name is probably your best bet, though; see VonC's answer.


1The specifiers in a compound item like HEAD..origin amount to three tokens: HEAD, .., and origin. By "by itself", I mean that you're using origin as a token in this way, and not as part of a larger token such as origin/master. You can also write, e.g., origin~12 here; the three tokens are origin, ~, and 12. While Git's revision parser is ad-hoc, rather than using a formal grammar with lexemes, it functions like one.

torek
  • 448,244
  • 59
  • 642
  • 775