--- /dev/null
+#!/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="")