-
Notifications
You must be signed in to change notification settings - Fork 1
/
branches.py
139 lines (121 loc) · 5.53 KB
/
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""Implement git's branches and merging."""
from os import listdir, rmdir, unlink
from os.path import dirname, exists
from functions import (format_mtime, get_current_branch, make_directory,
read_file, write_file)
def execute_lgit_branch(args, lgit_path):
"""List or create branches."""
def _create_branch(name):
"""Create a new branch."""
# If branch name exists:
if exists(lgit_path + '/.lgit/refs/heads/' + name):
exit("fatal: A branch named '%s' already exists." % name)
# Create new branch:
snapshots = listdir(lgit_path + '/.lgit/snapshots')
with open(lgit_path + '/.lgit/refs/heads/%s' % name, 'w') as branch:
if snapshots:
branch.write(max(snapshots))
def _list_branches():
"""List all existing branches."""
branch = get_current_branch(lgit_path + '/.lgit/HEAD')
for file in sorted(listdir(lgit_path + '/.lgit/refs/heads')):
if file == branch:
print('*', file)
else:
print(' ', file)
if args.branch_name:
# If call branch command without ever have commit yet:
if not listdir(lgit_path + '/.lgit/refs/heads'):
exit("fatal: Not a valid object name: 'master'.")
_create_branch(args.branch_name)
else:
_list_branches()
def execute_lgit_checkout(args, lgit_path):
"""Switch branches or restore working tree files."""
def _report_error(list_file):
"""Print error with the files would be overwitten."""
print('''error: Your local changes to the following files would be
overwritten by checkout:''')
for file_name in list_file:
print('\t' + file_name)
print('''Please, commit your changes or stash them before you can
switch branches.''')
print('Aborting')
def _remove_files_in_index():
"""Remove all files in lgit's index."""
for index in content_index:
file_name = index[138:]
unlink(file_name)
# If there's any empty directory in directory 'file_name':
try:
while '/' in file_name:
file_name = dirname(file_name)
rmdir(file_name)
rmdir(file_name)
except OSError:
pass
def _create_working_files(file_path, content):
"""Create tree of working files."""
# Create tree directory that the file in it:
if '/' in file_path:
parent_paths = file_path.split('/')[:-1]
for i in range(len(parent_paths) - 1):
make_directory('/'.join(parent_paths[:i + 1]))
# Create new file:
write_file(file_path, content)
def _setup_for_new_branch(commit):
"""Create working files and rewrite index for the current branch."""
new_content_index = ''
content_snap = read_file(lgit_path +
'/.lgit/snapshots/%s' % commit).split('\n')
for line_snap in content_snap:
content = read_file(lgit_path + '/.lgit/objects/%s/%s' %
(line_snap[:2], line_snap[2:40]))
file_name = content_snap[41:]
_create_working_files(file_name, content)
timestamp = format_mtime(file_name)
new_content_index += (timestamp + (' ' + line_snap[:40]) * 3 + ' '
+ file_name + '\n')
write_file(lgit_path + '/.lgit/index', new_content_index)
def _update_head_file(branch_name):
"""Update the HEAD file with the branch_name"""
content = 'ref: refs/head/%s' % branch_name
write_file(lgit_path + '/.lgit/HEAD', content)
list_branches = listdir(lgit_path + '/.lgit/refs/heads')
if list_branches:
if args.branch_name not in list_branches:
print("error: pathspec '%s' did not match any file(s) known to git"
% args.branch_name)
else:
branch = get_current_branch(lgit_path + '/.lgit/HEAD')
if args.branch_name == branch:
if branch != 'master':
print("Already on '%s'" % branch)
else:
last_commit = read_file(lgit_path + '/.lgit/refs/heads/%s' %
args.branch_name).split('\n')[0]
current_stage = read_file(
lgit_path + '/.lgit/refs/heads/%s' % branch).split('\n')[0]
if last_commit != current_stage:
content_index = read_file(lgit_path +
'/.lgit/index').split('\n')
# List files has change without 'commit' command:
error_files = []
for line in content_index:
file = line[138:]
if line[15:55] != line[97:137]:
error_files.append(file)
if error_files:
_report_error(error_files)
exit()
else:
_remove_files_in_index()
_setup_for_new_branch(last_commit)
_update_head_file(args.branch_name)
print("Switch to branch '%s'" % args.branch_name)
else:
print('fatal: You are on a branch yet to be born')
def execute_lgit_merge(args, lgit_path):
"""Merge one branch onto another."""
def execute_lgit_stash(args, lgit_path):
"""Stash the changes in a dirty working directory away."""