aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/version
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-08-13 08:09:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-08-13 08:09:04 +0200
commit61ac67105ef31e1ea31014e50e5b6deb74674594 (patch)
treee45e5be577d82b3c43a4cf94a833d17adb795a9e /libbuild2/version
parentb01aaa16e5adaa0cc064490535f8756b2ef8d421 (diff)
Cache git status results in version module
Diffstat (limited to 'libbuild2/version')
-rw-r--r--libbuild2/version/snapshot-git.cxx46
-rw-r--r--libbuild2/version/snapshot.cxx4
2 files changed, 30 insertions, 20 deletions
diff --git a/libbuild2/version/snapshot-git.cxx b/libbuild2/version/snapshot-git.cxx
index 28d96ac..e766bc9 100644
--- a/libbuild2/version/snapshot-git.cxx
+++ b/libbuild2/version/snapshot-git.cxx
@@ -14,11 +14,20 @@ namespace build2
{
namespace version
{
+ // We have to run git twice to extract the information we need and doing
+ // it repetitively is quite expensive, especially for larger repositories.
+ // So we cache it, which helps multi-package repositories.
+ //
+ static global_cache<snapshot, dir_path> cache;
+
snapshot
- extract_snapshot_git (const dir_path& src_root)
+ extract_snapshot_git (dir_path rep_root)
{
+ if (const snapshot* r = cache.find (rep_root))
+ return *r;
+
snapshot r;
- const char* d (src_root.string ().c_str ());
+ const char* d (rep_root.string ().c_str ());
// On startup git prepends the PATH environment variable value with the
// computed directory path where its sub-programs are supposedly located
@@ -192,30 +201,31 @@ namespace build2
// that.
}
- if (!run_finish_code (args, pr, l))
+ if (run_finish_code (args, pr, l))
+ {
+ if (r.sn == 0)
+ fail << "unable to extract git commit id/date for " << rep_root;
+
+ if (r.committed)
+ {
+ sha1 cs;
+ cs.append ("commit " + to_string (data.size ())); // Includes '\0'.
+ cs.append (data.c_str (), data.size ());
+ r.id.assign (cs.string (), 12); // 12-char abbreviated commit id.
+ }
+ else
+ r.sn++; // Add a second.
+ }
+ else
{
// Presumably new repository without HEAD. Return uncommitted snapshot
// with UNIX epoch as timestamp.
//
r.sn = 19700101000000ULL;
r.committed = false;
- return r;
- }
-
- if (r.sn == 0)
- fail << "unable to extract git commit id/date for " << src_root;
-
- if (r.committed)
- {
- sha1 cs;
- cs.append ("commit " + to_string (data.size ())); // Includes '\0'.
- cs.append (data.c_str (), data.size ());
- r.id.assign (cs.string (), 12); // 12-characters abbreviated commit id.
}
- else
- r.sn++; // Add a second.
- return r;
+ return cache.insert (move (rep_root), move (r));
}
}
}
diff --git a/libbuild2/version/snapshot.cxx b/libbuild2/version/snapshot.cxx
index 3a885b5..d20e633 100644
--- a/libbuild2/version/snapshot.cxx
+++ b/libbuild2/version/snapshot.cxx
@@ -12,7 +12,7 @@ namespace build2
namespace version
{
snapshot
- extract_snapshot_git (const dir_path&);
+ extract_snapshot_git (dir_path);
static const path git (".git");
@@ -46,7 +46,7 @@ namespace build2
if (butl::entry_exists (d / git,
true /* follow_symlinks */,
true /* ignore_errors */))
- return extract_snapshot_git (d);
+ return extract_snapshot_git (move (d));
}
return snapshot ();