Skip to content

Instantly share code, notes, and snippets.

@jpigree
Created March 30, 2018 15:00
Show Gist options
  • Save jpigree/74dd9d671098c410dc4adb2c858f3113 to your computer and use it in GitHub Desktop.
Save jpigree/74dd9d671098c410dc4adb2c858f3113 to your computer and use it in GitHub Desktop.
Check Git branches duration in a repository
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import operator
from subprocess import check_output, check_call, STDOUT
from datetime import timedelta
from time import time
FNULL = open(os.devnull, 'w')
MAIN_BRANCHES = ["develop", "master"]
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
DEFAULT = '\033[0m'
class BranchInfos(object):
def __init__(self, name, duration, commits, committer):
self.name = name
self.duration = duration
self.commits = commits
self.committer = committer
def __lt__(self, other):
return self.duration < other.duration
def feature_branches():
branches = check_output(
["git", "ls-remote", "--heads", "origin"],
universal_newlines=True)
for branch in branches.split("\n"):
if branch:
branch = branch.split()[1].strip().replace("refs/heads/", "")
if branch not in MAIN_BRANCHES:
yield branch
def merge_base(base, branch):
return check_output(
["git", "merge-base", branch, base],
universal_newlines=True).strip()
def branch_commits(base, branch):
return check_output(
["git", "rev-list", "{}..{}".format(base, branch)],
universal_newlines=True).strip().split()
def commit_date(commit):
return check_output(
["git", "show", "-s", "--format=%ct", commit],
universal_newlines=True).strip()
def commit_committer(commit):
return check_output(
["git", "show", "-s", "--format=%cn", commit],
universal_newlines=True).strip()
def remote_branch(branch):
return "origin/{}".format(branch)
def branch_infos(base, branch):
r_branch = remote_branch(branch)
r_base_branch = remote_branch(base)
base_commit = merge_base(r_base_branch, r_branch)
commits = branch_commits(base_commit, r_branch)
duration = 0
committer = commit_committer(base_commit)
if commits:
first_commit_date = commit_date(commits[-1])
duration = int(time()) - int(first_commit_date)
committer = commit_committer(commits[0])
return BranchInfos(
name=branch,
duration=duration,
commits=commits,
committer=committer)
def show_branches_duration(base):
infos = dict()
for branch in feature_branches():
infos[branch] = branch_infos(base, branch)
for key, value in sorted(infos.items(), key=operator.itemgetter(1)):
if value == 0:
print("{}{}{}({}{}{}) is fully merged{} inside {}".format(
BLUE,
key,
DEFAULT,
BOLD,
value.committer,
DEFAULT,
GREEN,
base))
else:
delta = timedelta(seconds=value.duration)
print(
"{}{}{}({}{}{}) oldest unmerged commit is {}{} days old{}".format(
BLUE,
key,
DEFAULT,
BOLD,
value.committer,
DEFAULT,
YELLOW,
delta.days,
DEFAULT))
if __name__ == "__main__":
if len(sys.argv) > 1:
REPO_PATH = sys.argv[1]
if os.path.isdir(REPO_PATH):
os.chdir(REPO_PATH)
check_call(["git", "fetch"], stdout=FNULL, stderr=STDOUT)
show_branches_duration("develop")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment