-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcommit.py
More file actions
140 lines (114 loc) · 4.51 KB
/
commit.py
File metadata and controls
140 lines (114 loc) · 4.51 KB
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
140
import os
import hashlib
import datetime
from blob import Blob
from tree import Tree
# Class definition begins
class Commit(staticmethod):
'''
Commit structure:
Line1..........."commmit"
Line2...........<hash of main dir tree>
Line3...........<hash of parent commit>
Line4...........<timestamp>
Line5...........<comment>
'''
'''
In this version of the system, there isn't any add
implementation. Commit includes all files
present in the main directory in the commit.
'''
def create_commit(comment: str):
main_dir = os.getcwd()
commit_content = "commit"
# Adding hash of main dir tree
tree_hash = Tree.create_index_tree(main_dir)
commit_content += "\n" + tree_hash
# Adding hash of parent commit
# Reading hash stored in .oak\head
os.chdir(".oak")
if not os.path.exists("HEAD"):
# No previous HEAD exists
commit_content += "\n" + "NULL"
else:
with open("HEAD", 'r') as file:
head_hash = file.readline()
assert len(head_hash)==40
commit_content += "\n" + head_hash
# Adding date and time info
commit_content += "\n" + Commit.get_curr_timestamp()
# Adding commit comment
commit_content += "\n" + comment
# Commit content completed
# Hashing the binary encoded content
hash_object = hashlib.sha1(commit_content.encode('utf-8'))
hash_str = hash_object.hexdigest()
hash_prefix = hash_str[:2]
hash_suffix = hash_str[2:]
# Creating commit object folder and file in .git/objects
# We are currently in ".oak"
os.chdir("objects")
if not os.path.exists(hash_prefix):
os.mkdir(hash_prefix)
os.chdir(hash_prefix)
if not os.path.exists(hash_suffix):
with open(hash_suffix, 'w') as file:
file.write(commit_content)
# Updating
os.chdir(os.path.join(main_dir, ".oak"))
with open("HEAD", 'w') as file:
file.write(hash_str)
with open("index", 'r') as index:
index_content = index.readlines()
with open('prev_index', 'w') as prev_index:
new_content = ''
for line in index_content:
new_content += line
# Writing new_content into prev_index
prev_index.write(new_content)
os.chdir(main_dir)
return hash_str
def get_tree_hash(hash_str: str, main_dir: str):
initial_dir = os.getcwd()
os.chdir(os.path.join(main_dir, ".oak", "objects", hash_str[:2]))
with open(hash_str[2:], 'r') as file:
# Read first line, NULL char at the end is excluded
tree_hash = file.readlines()[1][:-1]
assert len(tree_hash)==40
os.chdir(initial_dir)
return tree_hash
def get_parent_hash(hash_str: str, main_dir: str):
initial_dir = os.getcwd()
os.chdir(os.path.join(main_dir, ".oak", "objects", hash_str[:2]))
with open(hash_str[2:], 'r') as file:
# Read second line, NULL char at the end is excluded
parent_hash = file.readlines()[2][:-1]
assert (len(parent_hash)==40 or parent_hash=="NULL")
os.chdir(initial_dir)
return parent_hash
def get_date(hash_str: str, main_dir: str):
initial_dir = os.getcwd()
os.chdir(os.path.join(main_dir, ".oak", "objects", hash_str[:2]))
with open(hash_str[2:], 'r') as file:
# Read third line, NULL char at the end is excluded
date = file.readlines()[3][:-1]
os.chdir(initial_dir)
return date
def get_comment(hash_str: str, main_dir: str):
initial_dir = os.getcwd()
os.chdir(os.path.join(main_dir, ".oak", "objects", hash_str[:2]))
with open(hash_str[2:], 'r') as file:
# Read fourth line fully
comment = file.readlines()[4]
os.chdir(initial_dir)
return comment
def get_curr_timestamp():
now = datetime.datetime.now()
day_of_week = now.strftime("%a")
month_name = now.strftime("%b")
date = now.strftime("%d")
time = now.strftime("%H:%M:%S")
year = now.strftime("%Y")
timestamp = f"{day_of_week} {month_name} {date} {time} {year}"
return timestamp
# Class definition ends