-
Notifications
You must be signed in to change notification settings - Fork 0
/
git_map_branches.py
executable file
·103 lines (82 loc) · 2.84 KB
/
git_map_branches.py
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
#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Provides a short mapping of all the branches in your local repo, organized by
their upstream ('tracking branch') layout. Example:
origin/master
cool_feature
dependent_feature
other_dependent_feature
other_feature
Branches are colorized as follows:
* Red - a remote branch (usually the root of all local branches)
* Cyan - a local branch which is the same as HEAD
* Note that multiple branches may be Cyan, if they are all on the same
commit, and you have that commit checked out.
* Green - a local branch
* Magenta - a tag
* Magenta '{NO UPSTREAM}' - If you have local branches which do not track any
upstream, then you will see this.
"""
import collections
import sys
from third_party import colorama
from third_party.colorama import Fore, Style
from git_common import current_branch, branches, upstream, hash_one, hash_multi
from git_common import tags
NO_UPSTREAM = '{NO UPSTREAM}'
def color_for_branch(branch, branch_hash, cur_hash, tag_set):
if branch.startswith('origin'):
color = Fore.RED
elif branch == NO_UPSTREAM or branch in tag_set:
color = Fore.MAGENTA
elif branch_hash == cur_hash:
color = Fore.CYAN
else:
color = Fore.GREEN
if branch_hash == cur_hash:
color += Style.BRIGHT
else:
color += Style.NORMAL
return color
def print_branch(cur, cur_hash, branch, branch_hashes, par_map, branch_map,
tag_set, depth=0):
branch_hash = branch_hashes[branch]
color = color_for_branch(branch, branch_hash, cur_hash, tag_set)
suffix = ''
if cur == 'HEAD':
if branch_hash == cur_hash:
suffix = ' *'
elif branch == cur:
suffix = ' *'
print color + " "*depth + branch + suffix
for child in par_map.pop(branch, ()):
print_branch(cur, cur_hash, child, branch_hashes, par_map, branch_map,
tag_set, depth=depth+1)
def main(argv):
colorama.init()
assert len(argv) == 1, "No arguments expected"
branch_map = {}
par_map = collections.defaultdict(list)
for branch in branches():
par = upstream(branch) or NO_UPSTREAM
branch_map[branch] = par
par_map[par].append(branch)
current = current_branch()
hashes = hash_multi(current, *branch_map.keys())
current_hash = hashes[0]
par_hashes = {k: hashes[i+1] for i, k in enumerate(branch_map.iterkeys())}
par_hashes[NO_UPSTREAM] = 0
tag_set = tags()
while par_map:
for parent in par_map:
if parent not in branch_map:
if parent not in par_hashes:
par_hashes[parent] = hash_one(parent)
print_branch(current, current_hash, parent, par_hashes, par_map,
branch_map, tag_set)
break
if __name__ == '__main__':
sys.exit(main(sys.argv))