[Libreoffice-commits] dev-tools.git: scripts/git-cherry-gerrit.py
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jan 11 09:30:24 UTC 2021
scripts/git-cherry-gerrit.py | 94 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
New commits:
commit 64b7a54156a3864effbd311992d42586d46c6989
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Jan 11 09:12:26 2021 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Jan 11 10:30:06 2021 +0100
git-cherry-gerrit.py: add a python version of the bash script
A functional change from the bash version is that we stop after the
first Change-Id when reading a commit message. This should not cause too
much problems (only happens when directly pushing multiple commits to
e.g. help.git and gerrit generating a submodule update for core.git),
and simplifies the code.
The benefit is that it's easy to use 'git cat-file --batch' from Python,
which gives a performance boost:
28,140 vs 6,105 seconds when comparing e.g. distro/collabora/cp-6.4 and
master of core.git (roughly 5 times faster).
Change-Id: I9ec91ed28bfdbc843f53a9e9f1a7ddd853e63082
Reviewed-on: https://gerrit.libreoffice.org/c/dev-tools/+/109077
Tested-by: Miklos Vajna <vmiklos at collabora.com>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/scripts/git-cherry-gerrit.py b/scripts/git-cherry-gerrit.py
new file mode 100755
index 0000000..6a0cf9e
--- /dev/null
+++ b/scripts/git-cherry-gerrit.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+#
+
+"""
+A version of 'git cherry' that works with change-ids, so it can pair patches
+even if their patch id changed.
+"""
+
+from typing import List
+import subprocess
+import sys
+
+
+def from_pipe(argv: List[str]) -> str:
+ """Executes argv as a command and returns its stdout."""
+ result = subprocess.check_output(argv)
+ return result.strip().decode("utf-8")
+
+
+def get_change_id(git_cat_file: subprocess.Popen, hash_string: str) -> str:
+ """Looks up the change-id for a git hash."""
+ git_cat_file.stdin.write((hash_string + "\n").encode("utf-8"))
+ git_cat_file.stdin.flush()
+ first_line = git_cat_file.stdout.readline().decode("utf-8")
+ size = first_line.strip().split(" ")[2]
+ commit_msg = git_cat_file.stdout.read(int(size)).decode("utf-8")
+ git_cat_file.stdout.readline()
+ for line in commit_msg.split("\n"):
+ if "Change-Id:" in line:
+ return line
+ return ""
+
+
+def main() -> None:
+ """Commandline interface."""
+ cherry_from = ""
+ if len(sys.argv) >= 2:
+ cherry_from = sys.argv[1]
+ cherry_to = ""
+ if len(sys.argv) >= 3:
+ cherry_to = sys.argv[2]
+
+ branch_point = ""
+ if len(sys.argv) >= 4:
+ branch_point = sys.argv[3]
+
+ whitelist_file = ""
+ if len(sys.argv) >= 5:
+ whitelist_file = sys.argv[4]
+
+ if not cherry_from:
+ print("Usage: git-cherry-gerrit.py cherry_from cherry_to [branch_point_from] [whitelist_file]")
+ sys.exit(1)
+
+ merge_base = from_pipe(["git", "merge-base", cherry_from, cherry_to])
+
+ if not branch_point:
+ branch_point = merge_base
+
+ to_change_ids = []
+ to_hashes = from_pipe(["git", "rev-list", merge_base + ".." + cherry_to]).split("\n")
+ git_cat_file = subprocess.Popen(['git', 'cat-file', '--batch'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ for to_hash in to_hashes:
+ to_change_ids.append(get_change_id(git_cat_file, to_hash))
+
+ from_hashes = from_pipe(["git", "rev-list", branch_point + ".." + cherry_from]).split("\n")
+ whitelist: List[str] = []
+ if whitelist_file:
+ with open(whitelist_file, "r") as stream:
+ whitelist = stream.read().strip().split("\n")
+ for from_hash in from_hashes:
+ changeid = get_change_id(git_cat_file, from_hash)
+ pretty = from_pipe(["git", "--no-pager", "log", "-1", "--format=format:%h%x09%an%x09%s%x0a", from_hash])
+ if not changeid:
+ if not whitelist_file or not [entry for entry in whitelist if pretty in entry]:
+ print("WARNING: commit '" + pretty + "' has no Change-Id, assuming it has to be cherry-picked.")
+ continue
+
+ if changeid not in to_change_ids:
+ if not whitelist_file or not [entry for entry in whitelist if pretty in entry]:
+ print(pretty)
+
+ git_cat_file.stdin.close()
+ git_cat_file.terminate()
+
+
+if __name__ == '__main__':
+ main()
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
More information about the Libreoffice-commits
mailing list