-
Notifications
You must be signed in to change notification settings - Fork 0
/
linhist.py
94 lines (79 loc) · 2.84 KB
/
linhist.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
#!/usr/bin/env python3
import sys
import argparse
import logging
from git import Repo, InvalidGitRepositoryError, GitCommandError
def main():
logging.basicConfig(
level=logging.INFO, format="%(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger("linhist")
parser = argparse.ArgumentParser(
prog="linhist",
description="A tool to check and maintain a linear Git history",
epilog="For more help on Linhist check https://github.com/wiltonloch/linhist",
)
subparsers = parser.add_subparsers()
check_merge_parser = subparsers.add_parser(
"check-merge", help="Checks if a merge operation would result in linear history"
)
check_merge_parser.add_argument(
"--repository",
type=str,
help="Path to the repository where to perform the check",
default=".",
required=False,
)
check_merge_parser.add_argument(
"--source", type=str, help="Source branch for the merge check", required=True
)
check_merge_parser.add_argument(
"--target", type=str, help="Target branch for the merge check", required=True
)
args = parser.parse_args()
# Checks if no arguments where passed and if so prints help information
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
repository_path = args.repository
source = args.source
target = args.target
try:
repository = Repo(repository_path)
except InvalidGitRepositoryError:
logger.error(
'The argument passed to "--repository" is not a valid Git repository'
)
sys.exit(1)
if source not in repository.branches:
try:
repository.git.switch(source)
except GitCommandError:
logger.error(
'The argument passed to "--source" is not an existing branch in the Git repository'
)
sys.exit(1)
if target not in repository.branches:
try:
repository.git.switch(target)
except GitCommandError:
logger.error(
'The argument passed to "--target" is not an existing branch in the Git repository'
)
sys.exit(1)
common_ancestor = repository.merge_base(source, target)[0]
target_tip = repository.rev_parse(target)
if target_tip == common_ancestor:
logger.info("CHECK PASSED: Merging will result in linear Git history")
sys.exit(0)
else:
logger.info("CHECK FAILED: Merging will result in non-linear Git history.")
logger.info(
"If both branches have some common ancestor, try rebasing the source on the target."
)
logger.info(
"Remember that child branches should be rebased on their parents, not the opposite."
)
sys.exit(1)
if __name__ == "__main__":
main()