forked from tkrajina/git-plus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-relation
executable file
·108 lines (87 loc) · 4.03 KB
/
git-relation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2013 Tomo Krajina
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys as mod_sys
import argparse as mod_argparse
import gitutils as mod_gitutils
mod_gitutils.assert_in_git_repository()
parser = mod_argparse.ArgumentParser(
description='Show a relation between two git commits/tags/branches')
parser.add_argument('branch_1', metavar='branch_1', type=str,
help='the one commit/tag/branch')
parser.add_argument('branch_2', metavar='branch_2', type=str, nargs='?', default='HEAD',
help='the other commit/tag/branch (default HEAD)')
parser.add_argument('-b', '--brief', action='store_true',
default=False, help='brief output')
args = parser.parse_args()
branch_1 = args.branch_1
branch_2 = args.branch_2
def get_git_sha1(branch_name):
success, sha1 = mod_gitutils.execute_git('log -1 %s --format=%%H' % branch_name,
output=False)
if not success:
print 'Invalid branch %s' % branch_name
mod_sys.exit(1)
return sha1.strip()
def print_log(commit_1, commit_2):
success, log = mod_gitutils.execute_git(
'log %s..%s --format=%%x20%%x20%%x20%%h%%x20%%Cgreen%%an%%Creset%%x20\"%%Cred%%s%%Creset\",%%x20%%ar' % (commit_1, commit_2),
output=False)
if not success:
print 'Error retrieving log %s..%s' % (commit_1, commit_2)
mod_sys.exit(1)
result = log.rstrip()
lines = result.split('\n')
print
print '%s commits from \033[1;34m%s\033[0m to \033[1;34m%s\033[0m:' % (len(lines), commit_1, commit_2)
if len(lines) < 30:
print result
return
first = lines[:10]
last = lines[-10:]
lines = first + [' ...%s more commits...' % (len(lines) - len(first) - len(last))] + last
print '\n'.join(lines)
def distance_to_commit(commit_1, commit_2):
success, log = mod_gitutils.execute_git(
'rev-list %s..%s --count' % (commit_1, commit_2),
output=False)
if not success:
print 'Error calculating distance between %s..%s' % (commit_1, commit_2)
mod_sys.exit(1)
return int(log)
branch_1_sha1 = get_git_sha1(branch_1)
branch_2_sha1 = get_git_sha1(branch_2)
success, merge_base = mod_gitutils.execute_git('merge-base %s %s' % (branch_1, branch_2),
output=False)
merge_base = merge_base.strip()
if not success:
print 'Can\'t find merge base for %s and %s' % (branch_1, branch_2)
mod_sys.exit(1)
elif merge_base == branch_1_sha1 and merge_base == branch_2_sha1:
print '\033[1;34m%s\033[0m \033[1;31mEQUALS\033[0m \033[1;34m%s\033[0m' % (branch_1, branch_2)
elif merge_base == branch_1_sha1:
print '\033[1;34m%s\033[0m is \033[1;31mBEHIND\033[0m \033[1;34m%s\033[0m by %d commits' % (branch_1, branch_2, distance_to_commit(branch_1, branch_2))
if not args.brief:
print_log(branch_1, branch_2)
elif merge_base == branch_2_sha1:
print '\033[1;34m%s\033[0m is \033[1;31mAHEAD\033[0m of \033[1;34m%s\033[0m by %d commits' % (branch_1, branch_2, distance_to_commit(branch_2, branch_1))
if not args.brief:
print_log(branch_2, branch_1)
else:
print '\033[1;34m%s\033[0m and \033[1;34m%s\033[0m \033[1;31mDIVERGED\033[0m by respectively %d and %d commits' % (branch_1, branch_2, distance_to_commit(merge_base, branch_1), distance_to_commit(merge_base, branch_2))
if not args.brief:
print 'common point is \033[1;34m%s\033[0m'%(merge_base)
print_log(merge_base, branch_1)
print_log(merge_base, branch_2)