-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrepository.h
106 lines (83 loc) · 3.81 KB
/
repository.h
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
#ifndef TOG_REPOSITORY_H
#define TOG_REPOSITORY_H
#include <exception>
#include <filesystem>
#include <memory>
#include <string>
#include "blob.h"
#include "commit.h"
#include "handle.h"
#include "tree.h"
namespace tog {
class TogException : public std::exception {
public:
TogException(const std::string& message) : message(message) {}
const char* what() const noexcept override {
return message.c_str();
}
private:
const std::string message;
};
class Repository {
public:
Repository(const std::filesystem::path& togdir_path);
// commits the current worktree contents with the given commit message and
// returns the commit object's hash
std::string commit(const std::string& message);
// restores the worktree to the state captured by the given commit
void checkout(const std::string& hash);
// returns the current branch's last n commit hashes in
// reverse-chronological order (newest first).
std::vector<std::string> history(int n);
// Initialized a new repository in the given directory.
static void init(const std::filesystem::path& path);
std::optional<std::string> head() const {
return _head ? std::optional<std::string>{_head->hash()} : std::nullopt;
}
std::optional<std::string> main() const {
return _main ? std::optional<std::string>{_main->hash()} : std::nullopt;
}
private:
// add_<object> loads an object from the given path, creates an object
// from it and adds it to the repository.
// TODO: Unify these methods once I have better understanding of templates
Handle<Blob>& add_file(const std::filesystem::path& file_path);
Handle<Tree>& add_directory(const std::filesystem::path& directory_path);
// register_object will move the given object into the repository's object
// store and return a (resolved) handle to it. Note that this handle may not
// refer to the same (as in "identical") object as the one passed in.
// TODO: Unify these methods once I have better understanding of templates
Handle<Blob>& register_object(std::unique_ptr<Blob> blob);
Handle<Tree>& register_object(std::unique_ptr<Tree> tree);
Handle<Commit>& register_object(std::unique_ptr<Commit> commit);
// Resolves the given handle. If the hash is not found in the repository,
// an exception is thrown. Note that the returned handle may not be the
// same as the one passed in.
void resolve(Handle<Blob>& blob);
void resolve(Handle<Tree>& tree);
void resolve(Handle<Commit>& commit);
// recursively restores the contents of the given tree at the given path.
void restoreTree(Handle<Tree>& tree, const std::filesystem::path& path);
void restoreBlob(Handle<Blob>& blob, const std::filesystem::path& path);
// load/store refs from .tog/refs
std::optional<Handle<Commit>> load_ref(const std::filesystem::path& path);
void persist_ref(const std::filesystem::path& path,
const std::optional<Handle<Commit>>& commit);
// togdir_path is the path to the .tog, _worktree_path is the path to the
// directory tracked by this repository. Currently, the worktree is always
// togdir/..
std::filesystem::path _togdir_path;
std::filesystem::path _worktree_path;
// lazily stores handles to objects in the repository
// TODO: Unify to single object store once I have better understanding of
// templates
std::unordered_map<std::string, Handle<Blob>> _blobs;
std::unordered_map<std::string, Handle<Tree>> _trees;
std::unordered_map<std::string, Handle<Commit>> _commits;
// stores the currently checked-out commit (if any)
std::optional<Handle<Commit>> _head;
// stores the latest commit on the main branch (currently the only branch)
std::optional<Handle<Commit>> _main;
};
} // namespace tog
#endif // TOG_REPOSITORY_H