Created
March 9, 2020 08:08
-
-
Save mnieber/bfa7a225885a59c27e96f8af0c09bd9f to your computer and use it in GitHub Desktop.
Picks a commit and puts it on a new branch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Usage: git pick sha branch-name --base[=origin/master] | |
# | |
# Picks a commit and puts it on a new branch that is based off "base". | |
# The following actions are taken: | |
# | |
# - check if branch-name does not already exist (abort if it does) | |
# - resolve "sha" to an absolute hash | |
# - git fetch | |
# - git checkout of branch-name based on "base" | |
# - git cherry-pick "sha" (using the absolute hash) | |
# - git checkout - (this returns us to the previous branch) | |
# - remove branch-name if any of the previous steps failed | |
# | |
import argparse | |
import subprocess | |
import sys | |
def git(*args, quiet=False): | |
pipes = subprocess.Popen(['git'] + list(args), | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE) | |
std_out, std_err = pipes.communicate() | |
std_out = std_out.decode('utf-8') | |
std_err = std_err.decode('utf-8') | |
if pipes.returncode != 0: | |
if not quiet: | |
print(std_out) | |
print(std_err.strip()) | |
raise Exception(pipes.returncode) | |
return std_out | |
def chop(x): | |
return x[:-1] if x.endswith("\n") else x | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument("sha") | |
parser.add_argument("branch_name") | |
parser.add_argument("--base", default="origin/master") | |
args = parser.parse_args() | |
args.abs_sha = chop(git("rev-parse", args.sha)) | |
try: | |
git("diff-index", "--quiet", "HEAD", "--") | |
except Exception: | |
print("You have uncommitted changes") | |
sys.exit(1) | |
try: | |
git("rev-parse", "--verify", args.branch_name, quiet=True) | |
except Exception: | |
pass | |
else: | |
print("Destination branch already exists") | |
sys.exit(1) | |
try: | |
git("fetch") | |
except Exception: | |
pass | |
git("branch", args.branch_name, args.base) | |
git("checkout", args.branch_name) | |
failed = False | |
try: | |
git("cherry-pick", args.abs_sha) | |
except Exception: | |
failed = True | |
print("Sorry, cherry-pick failed") | |
git("checkout", "-") | |
if failed: | |
git("branch", "-d", args.branch_name) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment