git-mr-merge: initial implementation
authorFrantisek Hrbata <frantisek@hrbata.com>
Wed, 16 Dec 2020 17:30:32 +0000 (18:30 +0100)
committerFrantisek Hrbata <frantisek@hrbata.com>
Wed, 16 Dec 2020 17:30:32 +0000 (18:30 +0100)
Signed-off-by: Frantisek Hrbata <frantisek@hrbata.com>
git-mr-merge [new file with mode: 0755]

diff --git a/git-mr-merge b/git-mr-merge
new file mode 100755 (executable)
index 0000000..04bd451
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+
+# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+
+"""
+Copyright © 2020 Frantisek Hrbata <frantisek@hrbata.com>
+This program is free software. It comes without any warranty, to
+the extent permitted by applicable law. You can redistribute it
+and/or modify it under the terms of the Do What The Fuck You Want
+To Public License, Version 2, as published by Sam Hocevar. See
+http://www.wtfpl.net/ for more details.
+"""
+
+import argparse
+import sys
+import mrlib
+import tempfile
+
+parser = argparse.ArgumentParser(description="Merge MR to current branch.")
+parser.add_argument("mr", metavar="REV",
+        help="MR revision which should be merged.")
+parser.add_argument("-f", "--force", action="store_true",
+        help="Proceed with the merge even if the MR base does not match.")
+parser.add_argument("--ff", action="store_true",
+        help="Allow fast-forward. By default merge commit is created even for fast-forward merges.")
+
+args = parser.parse_args()
+refs = mrlib.load_refs()
+mr = mrlib.verify_mrs([args.mr], refs)[0]
+
+tags = mrlib.load_tags([mr], refs=refs, commits=False)
+mrtags = mrlib.get_commit_tags(tags, mr, mrlib.rev_zero)
+base = mrlib.get_tag_value(mrtags, "B")
+subj = "Merge of " + mrlib.get_tag_value(mrtags, "S")
+desc = mrlib.get_tag_value(mrtags, "D").replace("\\n", "\n")
+
+rv, out, err = mrlib.run(["git", "merge-base", "HEAD", mr])
+mbase = out.strip()
+
+tmpdir = tempfile.TemporaryDirectory()
+msgfn = "{}/msg".format(tmpdir.name)
+
+with open(msgfn, "a+") as f:
+    f.write(subj)
+    f.write("\n\n")
+    f.write(desc)
+
+if not args.force:
+    if base != mbase:
+        sys.exit("MR base '{}' does not match '{}'.".format(base, mbase))
+
+cmd = ["git", "merge", "-F", msgfn]
+if args.ff:
+    cmd += ["--ff"]
+else:
+    cmd += ["--no-ff"]
+
+cmd += [mr]
+rv, out, err = mrlib.run(cmd)
+if out:
+    print(out, end="")
+if err:
+    print(err, file=sys.stderr, end="")