-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommit.cpp
More file actions
210 lines (168 loc) · 5.61 KB
/
Commit.cpp
File metadata and controls
210 lines (168 loc) · 5.61 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include "Commit.h"
#include "Repository.h"
#include "Utils.h"
/* Constructors */
Commit::Commit()
: m_timestamp(),
m_message(),
m_parent_ref(),
m_second_parent_ref(),
m_commit_ref(),
m_map()
{ }
Commit::Commit(const std::string& message, std::time_t time)
: m_timestamp(time),
m_message(message),
m_parent_ref(),
m_second_parent_ref(),
m_commit_ref(),
m_map()
{
m_commit_ref = sha1({m_message,
m_timestamp.toString(),
toString(m_map)});
}
Commit Commit::getRoot() const {
Commit root = *this;
while (root.m_parent_ref != "") {
root = getFirstParent();
}
return root;
}
Commit Commit::getFirstParent() const {
if (m_parent_ref == "") return Commit();
Commit first_parent;
first_parent.setCommitRef(m_parent_ref);
first_parent.readFromFile();
return first_parent;
}
Commit Commit::getSecondParent() const {
if (m_second_parent_ref == "") return Commit();
Commit second_parent;
second_parent.setCommitRef(m_second_parent_ref);
second_parent.readFromFile();
return second_parent;
}
bool Commit::equalTo(const Commit& commit) const {
return m_commit_ref == commit.m_commit_ref;
}
void Commit::setLogMessage(const std::string& log_message) {
m_message = log_message;
}
void Commit::setSecondParentRef(const std::string& second_parent_ref) {
m_second_parent_ref = second_parent_ref;
}
void Commit::setBlobRef(const std::string& filename, const std::string& commit_ref) {
if (m_map.find(filename) != m_map.end()) {
m_map.erase(filename);
}
m_map.emplace(filename, commit_ref);
}
const std::unordered_map<std::string, std::string>& Commit::getFilesMap() const {
return m_map;
}
bool Commit::isMergedCommit() const {
return m_second_parent_ref != "";
}
void Commit::updateRef() {
m_commit_ref = sha1({ m_message, m_parent_ref, m_second_parent_ref, toString(m_map) });
}
const std::string& Commit::getMessage() const {
return m_message;
}
std::string Commit::getDate() const {
return m_timestamp.toString();
}
bool Commit::containFile(const std::string& filename) const {
return m_map.find(filename) != m_map.end();
}
bool Commit::containFile(const std::string& filename, const std::string& blob_ref) const {
return m_map.find(filename) != m_map.end() && m_map.at(filename) == blob_ref;
}
void Commit::setCommitRef(const std::string& commit_ref) {
m_commit_ref = commit_ref;
}
std::string Commit::getBlobRef(const std::string& filename) const {
if (m_map.find(filename) == m_map.end()) return "";
return m_map.at(filename);
}
void Commit::updateDate() {
m_timestamp = Date();
}
void Commit::updateMessage(const std::string& message) {
m_message = message;
}
void Commit::addFileReference(const std::string& filename, const std::string& commit_ref) {
if (m_map.find(filename) != m_map.end()) {
m_map.erase(filename);
}
m_map.emplace(filename, commit_ref);
}
void Commit::removeFileReference(const std::string& filename, const std::string& commit_ref) {
if (m_map.find(filename) != m_map.end() && m_map[filename] == commit_ref) {
m_map.erase(filename);
}
}
const std::string& Commit::getSecondParentRef() const {
return m_second_parent_ref;
}
const std::string& Commit::getParentRef() const {
return m_parent_ref;
}
void Commit::setParentRef(const std::string& parent_ref) {
m_parent_ref = parent_ref;
}
const std::string& Commit::getCommitRef() const {
return m_commit_ref;
}
bool Commit::containsBlob(const Blob& blob) const {
const std::string& filename = blob.getFilename();
const std::string& blob_ref = blob.getFileRef();
return m_map.find(filename) != m_map.end() && m_map.at(filename) == blob_ref;
}
/*
- CWD
- .gitlet/ -- local repo
- commits/ -- directory of all commit files
- [subdir]/ -- directory of commit files, named with first 2 characters of commit reference
[commit1] -- commit file, named with last 38 characters of commit reference
....
[commitN]
PS: commit reference is a SHA-1 string of size 40
*/
bool Commit::readFromFile() {
// check the existence of parent directory of commit file
fs::path commit_parent_dir = Repository::COMMIT_DIR / m_commit_ref.substr(0,2);
if (fs::exists(commit_parent_dir) == false) {
return false;
}
// in case the commit reference is a short ref
std::string commit_file_short = m_commit_ref.substr(2);
std::set<std::string> regular_files = plainFilenamesIn(commit_parent_dir);
for (const auto& it : regular_files) {
// if get the target file, quit the loop
if (commit_file_short == it.substr(0, commit_file_short.size())) {
commit_file_short = it;
break;
}
}
// check the eixistence of commit file
fs::path commit_file = commit_parent_dir / commit_file_short;
if (fs::exists(commit_file) == false) {
return false;
}
readObject(commit_file, *this);
return true;
}
void Commit::writeToFile() {
fs::path commit_parent_dir = Repository::COMMIT_DIR / m_commit_ref.substr(0, 2);
fs::create_directory(commit_parent_dir);
fs::path commit_file = commit_parent_dir / m_commit_ref.substr(2);
writeObject(commit_file, *this);
}
// todo
void Commit::readFromRemoteRepo(const fs::path& remote_repo) {
}
// todo
void Commit::writeToRemoteRepo(const fs::path& remote_repo) {
}