diff options
-rw-r--r-- | src/dir.cpp | 1 | ||||
-rw-r--r-- | src/repo.cpp | 24 | ||||
-rw-r--r-- | src/repo.h | 4 |
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))); } @@ -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; |