summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dir.cpp1
-rw-r--r--src/repo.cpp24
-rw-r--r--src/repo.h4
3 files changed, 23 insertions, 6 deletions
diff --git a/src/dir.cpp b/src/dir.cpp
index 012baa5..f59dd92 100644
--- a/src/dir.cpp
+++ b/src/dir.cpp
@@ -14,6 +14,7 @@ GitFS::Directory::Directory(Repo * const r, const std::string & p) :
GitFS::Git::TreePtr
GitFS::Directory::getSubtree() const
{
+ repo->update();
if (!git_oid_equal(&subTreeCacheRootId, git_tree_id(repo->tree.get()))) {
if (path == "/") {
subTreeCache = repo->tree;
diff --git a/src/repo.cpp b/src/repo.cpp
index 0da7e4a..634fe07 100644
--- a/src/repo.cpp
+++ b/src/repo.cpp
@@ -12,21 +12,29 @@ std::string operator/(const std::string & a, const std::string & b)
GitFS::Repo::Repo(const PropertyReader & properties) :
repo(Git::RepositoryOpenBare(properties("gitdir"))),
commitish(properties("commitish") / "master"),
+ isBranch(false),
+ resolvedAt(0),
gid(properties("gid") / "root"),
uid(properties("uid") / "root")
{
- git_oid commitId;
if (commitish.length() == GIT_OID_HEXSZ) {
- commitId = Git::OidParse(commitish);
+ commit = Git::CommitLookup(repo, Git::OidParse(commitish));
}
else {
- auto ref = Git::Commitish(repo, commitish);
+ ref = Git::Commitish(repo, commitish);
isBranch = git_reference_is_branch(ref.get());
- ref = Git::Resolve(ref);
- commitId = *git_reference_target(ref.get());
}
+ update();
+}
- commit = Git::CommitLookup(repo, commitId);
+void
+GitFS::Repo::update()
+{
+ if (!commit || (isBranch && ref && resolvedAt < std::time(nullptr) - 30)) {
+ commit = Git::CommitLookup(repo,
+ *git_reference_target(Git::Resolve(ref).get()));
+ resolvedAt = std::time(nullptr);
+ }
tree = Git::TreeLookup(repo, *git_commit_tree_id(commit.get()));
}
@@ -64,6 +72,7 @@ GitFS::Repo::access(ReqEnv, ::std::string path, int mode, const ::Ice::Current&)
if (path == "/") return 0;
try {
+ update();
auto e = Git::TreeEntryByPath(tree, path);
const auto emode = git_tree_entry_filemode(e.get());
@@ -90,6 +99,7 @@ GitFS::Repo::getattr(ReqEnv, ::std::string path, const ::Ice::Current&)
a.mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
else {
+ update();
auto entry = Git::TreeEntryByPath(tree, path);
a << *entry;
if (S_ISREG(git_tree_entry_filemode(entry.get()))) {
@@ -109,6 +119,7 @@ GitFS::Repo::readlink(ReqEnv, ::std::string path, const ::Ice::Current&)
{
if (path.empty() || path == "/") throw NetFS::SystemError(EINVAL);
+ update();
auto e = Git::TreeEntryByPath(tree, path);
if (!S_ISLNK(git_tree_entry_filemode(e.get()))) throw NetFS::SystemError(EINVAL);
auto blob = Git::BlobLookup(repo, *git_tree_entry_id(e.get()));
@@ -123,6 +134,7 @@ GitFS::Repo::open(ReqEnv, ::std::string path, int, const ::Ice::Current& ice)
if (path.empty()) throw NetFS::SystemError(EINVAL);
if (path == "/") throw NetFS::SystemError(EISDIR);
+ update();
return Ice::uncheckedCast<NetFS::FilePrx>(ice.adapter->addWithUUID(
std::make_shared<Blob>(this, path)));
}
diff --git a/src/repo.h b/src/repo.h
index adeac94..b5b183c 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -33,11 +33,15 @@ namespace GitFS {
void utimens(ReqEnv env, ::std::string path, long long int atime, long long int atimens, long long int mtime, long long int mtimens, const ::Ice::Current& current) override;
private:
+ void update();
+
friend class Directory;
friend class Blob;
const Git::RepositoryPtr repo;
const std::string commitish;
+ Git::RefPtr ref;
bool isBranch;
+ std::time_t resolvedAt;
Git::CommitPtr commit;
Git::TreePtr tree;
const std::string gid, uid;