Obtain the latest refspec on a Gerrit Change
Asked Answered
S

3

12

How can I obtain the latest refspec on a gerrit change through a single command. I need the output as "refs/changes/11/1234/4". Is there any git command for the same

I do know that ssh commands combined with gerrit query and a bit of scripting can obtain this, but want to know if there is any better way to do the same. Following is the ssh command I would use to get the refspec.

ssh -p $REVIEW_SERVER_PORT $GERRIT_REVIEW_SERVER gerrit query --format=TEXT --current-patch-set $CHANGE_SHA | grep ref.

Similarly, I would also want to get the LATEST PATCHSET of the gerrit change

Spital answered 8/3, 2014 at 3:13 Comment(1)
Did you ever find your answer? I'm also looking for something like this.Same
A
13

You should use the gerrit query. Given change number 4665:

ssh -p 29418 review.example.com gerrit query --current-patch-set --format=JSON change:4665

Which outputs:

{  
   "project":"xx",
   "branch":"master",
   "topic":"TOPIC",
   "id":"I0b6fc492fd08749e409c359a73d74e7795f50cc9",
   "number":"4665",
   // ...
   "currentPatchSet":{  
      "number":"5",
      "revision":"ae3a5d2684991070041e1c34b5a16b1376dc3ce5",
      "parents":[  
         "5b21793cadd3dc55008ef6c8dc658e127d80c097"
      ],
      "ref":"refs/changes/65/4665/5",
      // ...
   }
}

where you can find the currentPatchSet.ref field.


Old, overcomplicated solution:

Provided that you want to get the latest patchset of change 2392:

git ls-remote | grep /2392/ | awk '{print $2}' | sed 's/\// /g' | sort -n -k5 | tail -n 1 | sed 's/ /\//g'

which outputs refs/changes/92/2392/12 for my repo.

Or, when you want to get the last Change from the Gerrit:

git ls-remote | awk '{print $2}' | sed 's/\// /g' | sort -n -k4 | tail -n 1 | sed 's/ /\//g'

which outputs refs/changes/54/2554/2 for my repo.


Explanation

git ls-remote command displays all references in a remote repository, so in case of Gerrit - every patchset is listed too. It outputs something like:

2ccddbfb34a98e8ba461964fae3766aa41be944d        refs/changes/91/2291/7
d00c21c28d07626caea27594489442696ea39231        refs/changes/91/2291/8
8c05e6551a6a34c33a36669bf7e83c996569e24d        refs/changes/91/2291/9
bc6762ac7b9ac5a74fc2e548df2541cb83977ec5        refs/changes/91/2391/1
3bd96c0d1ba2d561fa484ddfc264fabbf86aa536        refs/changes/91/2391/2

So in order to pick all patchsets from a particular change, we need to grep results out by /NUMBER/, which explains the grep /2392/. After that and by selecting second column with awk, the result is:

refs/changes/92/2392/1
refs/changes/92/2392/10
refs/changes/92/2392/11
refs/changes/92/2392/12
refs/changes/92/2392/2
refs/changes/92/2392/3
refs/changes/92/2392/4
refs/changes/92/2392/5
refs/changes/92/2392/6
refs/changes/92/2392/7
refs/changes/92/2392/8
refs/changes/92/2392/9

Now we want to pick the last patchset. We need sorting. sort command is able to sort by a numbers with -n and we can specify on which column to perform sorting with -kX argument. But it requires columns to be separated with white space (AFAIK), so we need to replace our / delimiters with a space. We use sed for it. After first replacement, each refs/changes/92/2392/X becomes refs changes 92 2392 X. Then sort is performed on fifth column (patchset number). Result:

refs changes 92 2392 1
refs changes 92 2392 2
refs changes 92 2392 3
refs changes 92 2392 4
refs changes 92 2392 5
refs changes 92 2392 6
refs changes 92 2392 7
refs changes 92 2392 8
refs changes 92 2392 9
refs changes 92 2392 10
refs changes 92 2392 11
refs changes 92 2392 12

Last thing to do is to select the last line with tail and replace the spaces back to be slashes. Voilà!

Selecting latest change from Gerrit is done in the same way, but without grep and sorting by fourth column (Change-Id).

Aleris answered 26/9, 2014 at 22:16 Comment(2)
Once can replace sed 's/\// /g' | sort -n -k5 | tail -n 1 | sed 's/ /\//g' with sort -t'/' -k5rn | head -1Cormier
Adding | jq '.currentPatchSet.ref' would make this answer more usable.Doall
T
2

Here is a solution that would work over HTTP as SSH may not work in some CI environments.

find_latest_change () {
  local remote=$1
  local review=$2
  git ls-remote $remote | grep -E "refs/changes/[[:digit:]]+/$2/" | sort -t / -k 5 -g | tail -n1 | awk '{print $2}'
}

remote=https://review.gerrithub.io/org-name/project-name
latest=$(find_latest_change $remote 12345)
git fetch $remote $latest && git cherry-pick FETCH_HEAD
Troytroyer answered 2/12, 2016 at 12:11 Comment(0)
P
1

Here is a solution that avoids listing the remote or using the gerrit REST API.

Every change in gerrit has a special ref called meta:

git fetch origin refs/changes/98/898/meta

Once fetched, it points to a chain of commits that represent the history of updates to this change. The commit message, among other things, has a trailer Patch-set that will contain the patchset number this change applies to:

> git log FETCH_HEAD

Author: Gerrit User 1000026 <1000026@dc17d2f6-4abc-4304-ba32-8b7ca44eda6b>
Date:   Wed Aug 19 06:36:23 2020 +0100

Update patch set 6

Change has been successfully cherry-picked as 68e4bc1612d61110ccfae4ac94bbd4458b2868a9 by Leonid Usov

Patch-set: 6
Subject: Add a new feature
Status: merged
Commit: 68e4bc1612d61110ccfae4ac94bbd4458b2868a9
Tag: autogenerated:gerrit:merged
Groups: bd9a33f7432c39308935056720de59168ff04003
Label: Code-Review=+2
Label: Verified=+1 Gerrit User 1000001 <1000001@dc17d2f6-4abc-4304-ba32-8b7ca44eda6b>
Label: SUBM=+1
Submission-id: 914
Submitted-with: OK
Submitted-with: OK: Code-Review: Gerrit User 1000026 <1000026@dc17d2f6-4abc-4304-ba32-8b7ca44eda6b>
Submitted-with: OK: Verified: Gerrit User 1000001 <1000001@dc17d2f6-4abc-4304-ba32-8b7ca44eda6b>

Naturally, the tip of that branch will point to the latest update, and hence will contain the number of the latest patchset. Here is how I can know the latest patch set number of a change:

 » git fetch origin refs/changes/14/914/meta \
   && git cat-file -p FETCH_HEAD \
    | git interpret-trailers --parse \
    | sed -E "/^Patch-set:/s/([[:alpha:]-]+):[[:space:]]*(.*)/\2/;q"
From ssh://gerrit/repo
 * branch                    refs/changes/14/914/meta -> FETCH_HEAD
6

Feel free to use that 6 on the stdout as you please ;)

Palenque answered 19/8, 2020 at 7:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.