2

Gerrit patch set number associated with local branch downloaded using git-review

Consider a change in Gerrit, say change 1234, having the following patch sets

# Gerrit change 1234 (https://mygerrit.somewhere.net/#/c/1234/)
1 (original commit)
2 (some amendments)
3 (some amendments)

And that I checkout patch set 2 of the change using git-review:

$ git review -d 1234,2
Downloading refs/changes/00/1234/2 from gerrit
Switched to branch "review/foo_bar/1234"

Question:

  • While on branch review/foo_bar/1234 (no changes after the review command above), is it somewhat possible to query the Gerrit patch set number associated with the branch? I.e.

    $ ... ?
    2
    

The only approach I've come up with myself is to make use of git ls-remote to identify all patch set numbers (and their associated SHA hashes) for the given change, and thereafter compare the hashes against the hash of the local branch's HEAD (git rev-parse HEAD). Alternatively just matching the hash of local HEAD to the git ls-remote and extract the patch set number from there, but I was hoping for a neater approach.

dfrib
  • 70,367
  • 12
  • 127
  • 192

1 Answers1

3

You can query gerrit using the ssh query interface and the commit id. For example, if my gerrit remote is...

$ git remote -v
gerrit  ssh://lars@review.openstack.org:29418/openstack/tripleo-quickstart.git (fetch)

...then I can make a gerrit query like this:

ssh -p 29418 lars@review.openstack.org gerrit query $(git rev-parse HEAD)

Just for kicks I grabbed patchset 415754, which gets me:

$ git log -1
commit c5852f3f29f0a08236261772e8cd892eba381597 (HEAD -> review/leif_madsen/415754)

If I run the above ssh ... query, I'll get back a chunk of text that will include something like:

  patchSets:
    number: 1
    revision: a8eedf9e6c87f6542ea1802a493d9d5caa7acaa2
    [...]
  patchSets:
    number: 2
    revision: c5852f3f29f0a08236261772e8cd892eba381597
    [...]

Just look for the patch set that matches your current commit ID. In this case, you can see that I have patchset 2.

You can automate that by (a) asking for JSON output with --format json and (b) using a JSON query tool such as jq:

$ ssh -p 29418 lars@review.openstack.org gerrit query \
  $(git rev-parse HEAD) --patch-sets --format json |
  head -1 | jq '.patchSets[] |
  select(.revision=="'"$(git rev-parse HEAD)"'").ref'

Which produces, in this case, the output:

"refs/changes/54/415754/2"
larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thanks! I deliberately constrained my question to not include the trickier case (I myself have no idea how to approach this) where the local `HEAD` has been modified (amended): do you have any thoughts on how to possibly approach the case where the hash of `HEAD` is no longer matching any PS hash (handle: find out which PS `HEAD` was based upon)? Say for a use case with a commit hook that warns a user if the PS the local branch’s `HEAD` was based upon does not match the most current one on gerrit. – dfrib Nov 23 '17 at 19:24
  • That's easy. In that case, your gerrit query would return 0 results; the JSON repsonse would look something like `{"type":"stats","rowCount":0,"runTimeMilliseconds":4,"moreChanges":false}`. You could easily check for that in a script. – larsks Nov 23 '17 at 20:27
  • I was possibly a bit unclear in my last comment, sorry for that: the tricky part in this “hard scenario” is not how to analyze whether a PS (`HEAD`) is already present or not on gerrit, but how to (as I wrote, I don’t even have an idea myself; some local dict. caching of which PS was most recently downloaded for a given change?) see whether a given new yet-to-be-pushed PS were based on the most recent gerrit PS or not. In my example, basing a new PS(/amendment) on `2` would yield a warning/prompt from the hook, whereas a new PS based on `3` would not. – dfrib Nov 23 '17 at 20:32