--- /dev/null
+#!/usr/bin/env python3
+# check out every commit added by the current branch, blackify them,
+# and generate diffs to reconstruct the original commits, but then
+# blackified
+import logging
+import os
+import sys
+from subprocess import check_output, run, Popen, PIPE
+
+
+def git(*args: str) -> str:
+ return check_output(["git"] + list(args)).decode("utf8").strip()
+
+
+def blackify(base_branch: str, black_command: str, logger: logging.Logger) -> int:
+ current_branch = git("branch", "--show-current")
+
+ if not current_branch or base_branch == current_branch:
+ logger.error("You need to check out a feature brach to work on")
+ return 1
+
+ if not os.path.exists(".git"):
+ logger.error("Run me in the root of your repo")
+ return 1
+
+ merge_base = git("merge-base", "HEAD", base_branch)
+ if not merge_base:
+ logger.error(
+ "Could not find a common commit for current head and %s" % base_branch
+ )
+ return 1
+
+ commits = git(
+ "log", "--reverse", "--pretty=format:%H", "%s~1..HEAD" % merge_base
+ ).split()
+ for commit in commits:
+ git("checkout", commit, "-b%s-black" % commit)
+ check_output(black_command, shell=True)
+ git("commit", "-aqm", "blackify")
+
+ git("checkout", base_branch, "-b%s-black" % current_branch)
+
+ for last_commit, commit in zip(commits, commits[1:]):
+ allow_empty = (
+ b"--allow-empty" in run(["git", "apply", "-h"], stdout=PIPE).stdout
+ )
+ quiet = b"--quiet" in run(["git", "apply", "-h"], stdout=PIPE).stdout
+ git_diff = Popen(
+ [
+ "git",
+ "diff",
+ "--find-copies",
+ "%s-black..%s-black" % (last_commit, commit),
+ ],
+ stdout=PIPE,
+ )
+ git_apply = Popen(
+ [
+ "git",
+ "apply",
+ ]
+ + (["--quiet"] if quiet else [])
+ + [
+ "-3",
+ "--intent-to-add",
+ ]
+ + (["--allow-empty"] if allow_empty else [])
+ + [
+ "-",
+ ],
+ stdin=git_diff.stdout,
+ )
+ if git_diff.stdout is not None:
+ git_diff.stdout.close()
+ git_apply.communicate()
+ git("commit", "--allow-empty", "-aqC", commit)
+
+ for commit in commits:
+ git("branch", "-qD", "%s-black" % commit)
+
+ return 0
+
+
+if __name__ == "__main__":
+ import argparse
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("base_branch")
+ parser.add_argument("--black_command", default="black -q .")
+ parser.add_argument("--logfile", type=argparse.FileType("w"), default=sys.stdout)
+ args = parser.parse_args()
+ logger = logging.getLogger(__name__)
+ logger.addHandler(logging.StreamHandler(args.logfile))
+ logger.setLevel(logging.INFO)
+ sys.exit(blackify(args.base_branch, args.black_command, logger))