Skip to content

Instantly share code, notes, and snippets.

@meeuw
Last active November 16, 2015 20:10
Show Gist options
  • Save meeuw/4a7c81e3518d47fea70d to your computer and use it in GitHub Desktop.
Save meeuw/4a7c81e3518d47fea70d to your computer and use it in GitHub Desktop.
Python script which reads commands from stdin to automatically merge (remote) branches, shows which branches are merged and shows which branches are available
#!/usr/bin/python2.7
import subprocess
import os
import json
import sys
import pygit2
FNULL = open(os.devnull, 'w')
#FNULL = sys.stdout
def status():
merged = []
nomerged = []
for branch in repo.listall_branches(pygit2.GIT_BRANCH_REMOTE):
b = repo.lookup_branch(branch, pygit2.GIT_BRANCH_REMOTE)
tgt = b.resolve().target
if repo.merge_base(repo.lookup_branch('master').target, tgt) == tgt:
pass
elif repo.merge_base(repo.lookup_branch('dev').target, tgt) == tgt:
merged.append(branch)
else:
nomerged.append(branch)
return {'merged':merged, 'nomerged':nomerged}
def merge(remotes):
subprocess.check_call(["git", "reset", "--hard"], stdout=FNULL, stderr=FNULL)
subprocess.check_call(["git", "clean", "-df"], stdout=FNULL, stderr=FNULL)
subprocess.check_call(["git", "checkout", "master"], stdout=FNULL, stderr=FNULL)
subprocess.call(["git", "branch", "-D", "dev"], stdout=FNULL, stderr=FNULL)
subprocess.check_call(["git", "checkout", "-t", "-b", "dev", "remotes/origin/master"], stdout=FNULL, stderr=FNULL)
ret = []
if len(remotes) < 1: return ret
unfinished = True
while unfinished:
try:
subprocess.check_call(["git", "merge"] + remotes + ["--no-ff", "-m", "automerge"], stdout=FNULL, stderr=FNULL)
unfinished = False
except subprocess.CalledProcessError:
subprocess.call(["git", "merge", "--abort"], stdout=FNULL, stderr=FNULL)
if len(remotes) == 0: unfinished = False
else: ret.append(remotes.pop())
return ret
def mergemaster(author):
branches = merged()
if len(branches) == 0: return
subprocess.check_call(["git", "checkout", "master"], stdout=FNULL, stderr=FNULL)
subprocess.check_call(["git", "merge"] + branches + ["--no-ff", "--no-commit"], stdout=FNULL, stderr=FNULL)
subprocess.call(["git", "commit", "-m", "automerge", "--author", author['author']], stdout=FNULL, stderr=FNULL)
subprocess.check_call(["git", "push", "origin"], stdout=FNULL, stderr=FNULL)
merge([])
return []
def nomerged():
return set(status()['nomerged'])
def merged():
return status()['merged']
def fetch(remotes):
subprocess.check_call(["git", "fetch"] + remotes + ["--prune"], stdout=FNULL, stderr=FNULL)
return []
if len(sys.argv) < 2:
print 'no parameters'
sys.exit()
os.chdir(sys.argv[1])
repo = pygit2.repository.Repository('.')
while 1:
inp = sys.stdin.readline()
if (inp.startswith('nomerged')): ret = list(nomerged())
elif (inp.startswith('merged')): ret = list(merged())
elif (inp.startswith('mergemaster')): ret = mergemaster(json.loads(inp[11:]))
elif (inp.startswith('merge')): ret = merge(json.loads(inp[5:]))
elif (inp.startswith('fetchall')): ret = fetch(['--all'])
elif (inp.startswith('fetch')): ret = fetch(json.loads(inp[5:]))
elif (inp.startswith('status')): ret = status()
else: break
out = json.dumps(ret)
print out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment