Получить последнюю ссылку на изменение Gerrit

Как я могу получить последнюю ссылку на изменение геррита с помощью одной команды. Мне нужен вывод как "refs/changes/11/1234/4". Есть ли какая-нибудь команда git для того же

Я знаю, что команды ssh в сочетании с запросом gerrit и небольшим количеством сценариев могут получить это, но я хочу знать, есть ли лучший способ сделать то же самое. Ниже приведена команда ssh, которую я бы использовал для получения refspec.

ssh -p $ REVIEW_SERVER_PORT $ GERRIT_REVIEW_SERVER запрос Gerrit --format=TEXT --current-patch-set $ $CHANGE_SHA | grep ref.

Точно так же, я также хотел бы получить ПОСЛЕДНЮЮ ПОПЕЧАТКУ изменения геррита

2 ответа

Вы должны использовать запрос Gerrit. Данный номер изменения 4665:

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

Какие выводы:

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

где вы можете найти currentPatchSet.ref поле.


Старое, слишком сложное решение:

При условии, что вы хотите получить последний набор изменений 2392:

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

какие выводы refs/changes/92/2392/12 для моего репо.

Или, если вы хотите получить последнее изменение от Геррита:

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

какие выводы refs/changes/54/2554/2 для моего репо.


объяснение

Команда git ls-remote отображает все ссылки в удаленном репозитории, так что в случае с Gerrit - также перечислены все наборы патчей. Это выводит что-то вроде:

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

Таким образом, чтобы выбрать все наборы патчей из определенного изменения, нам нужно получить результаты путем /NUMBER/, который объясняет grep /2392/, После этого и выбрав второй столбец с помощью awk, вы получите:

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

Теперь мы хотим выбрать последний набор патчей. Нам нужна сортировка. Команда сортировки умеет сортировать по номерам с -n и мы можем указать, по какому столбцу выполнять сортировку -kX аргумент. Но это требует, чтобы столбцы были разделены пробелом (AFAIK), поэтому нам нужно заменить наш / разделители с пробелом. Мы используем sed для этого. После первой замены каждый refs/changes/92/2392/X становится refs changes 92 2392 X, Затем сортировка выполняется по пятому столбцу (номер набора патчей). Результат:

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

Последнее, что нужно сделать, - это выбрать последнюю строку с хвостом и заменить пробелы обратно косыми чертами. Вуаля!

Выбор последнего изменения из Gerrit осуществляется таким же образом, но без grep и сортировки по четвертому столбцу (Change-Id).

Вот решение, которое будет работать через HTTP, так как SSH может не работать в некоторых средах CI.

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

Вот решение, которое позволяет избежать перечисления удаленного или использования API REST gerrit.

Каждое изменение в gerrit имеет специальную ссылку, называемую meta:

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

После получения он указывает на цепочку коммитов, которые представляют историю обновлений этого изменения. Сообщение коммита, помимо прочего, имеет трейлерPatch-set который будет содержать номер набора патчей, к которому применяется это изменение:

> 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>

Естественно, верхушка этой ветки будет указывать на последнее обновление и, следовательно, будет содержать номер последнего набора исправлений. Вот как я могу узнать номер последнего патча изменения:

 » 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

Не стесняйтесь использовать это 6 на стандартный вывод, как вам будет угодно;)

Другие вопросы по тегам