aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bdep/git.cxx30
-rw-r--r--bdep/git.hxx32
-rw-r--r--bdep/git.ixx40
-rw-r--r--bdep/git.txx50
-rw-r--r--bdep/project-email.cxx2
-rw-r--r--bdep/publish.cxx14
6 files changed, 115 insertions, 53 deletions
diff --git a/bdep/git.cxx b/bdep/git.cxx
index c26d257..c0b48fc 100644
--- a/bdep/git.cxx
+++ b/bdep/git.cxx
@@ -4,7 +4,8 @@
#include <bdep/git.hxx>
-#include <libbutl/filesystem.mxx>
+#include <libbutl/git.mxx>
+#include <libbutl/standard-version.mxx>
#include <bdep/diagnostics.hxx>
@@ -12,14 +13,27 @@ using namespace butl;
namespace bdep
{
- bool
- git (const dir_path& d)
+ static optional<standard_version> git_ver;
+
+ void
+ git_check_version ()
{
- // .git can be either a directory or a file in case of a submodule.
- //
- return entry_exists (d / ".git",
- true /* follow_symlinks */,
- true /* ignore_errors */);
+ if (!git_ver)
+ {
+ // Make sure that the getline() function call doesn't end up with an
+ // infinite recursion.
+ //
+ git_ver = standard_version ();
+
+ optional<string> s (git_line (false /* ignore_error */, "--version"));
+
+ if (!s || !(git_ver = git_version (*s)))
+ fail << "unable to obtain git version";
+
+ if (git_ver->version < 20120000000)
+ fail << "unsupported git version " << *git_ver <<
+ info << "minimum supported version is 2.12.0" << endf;
+ }
}
optional<string>
diff --git a/bdep/git.hxx b/bdep/git.hxx
index 1552670..ca49622 100644
--- a/bdep/git.hxx
+++ b/bdep/git.hxx
@@ -5,39 +5,49 @@
#ifndef BDEP_GIT_HXX
#define BDEP_GIT_HXX
+#include <libbutl/git.mxx>
+
#include <bdep/types.hxx>
#include <bdep/utility.hxx>
namespace bdep
{
- // Return true if the specified directory is a git repository root (contains
- // the .git filesystem entry).
- //
- bool
- git (const dir_path&);
+ using butl::git_repository;
- template <typename... A>
- inline void
- run_git (const dir_path& repo, A&&... args);
+ template <typename I, typename O, typename E, typename... A>
+ process
+ start_git (I&& in, O&& out, E&& err, A&&... args);
template <typename I, typename O, typename E, typename... A>
- inline process
- start_git (I&& in, O&& out, E&& err, const dir_path& repo, A&&... args);
+ process
+ start_git (const dir_path& repo, I&& in, O&& out, E&& err, A&&... args);
+
+ void
+ finish_git (process& pr, bool io_read = false);
+
+ template <typename... A>
+ void
+ run_git (const dir_path& repo, A&&... args);
// Return the first line of the git output. If ignore_error is true, then
// suppress stderr, ignore (normal) error exit status, and return nullopt.
//
template <typename... A>
optional<string>
+ git_line (bool ignore_error, A&&... args);
+
+ template <typename... A>
+ optional<string>
git_line (const dir_path& repo, bool ignore_error, A&&... args);
// Similar to the above but takes the already started git process with a
// redirected output pipe.
//
optional<string>
- git_line (process&& pr, fdpipe&& pipe, bool ignore_error = false);
+ git_line (process&& pr, fdpipe&& pipe, bool ignore_error);
}
#include <bdep/git.ixx>
+#include <bdep/git.txx>
#endif // BDEP_GIT_HXX
diff --git a/bdep/git.ixx b/bdep/git.ixx
index e71375a..9369564 100644
--- a/bdep/git.ixx
+++ b/bdep/git.ixx
@@ -2,43 +2,31 @@
// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-using namespace butl;
-
namespace bdep
{
- template <typename... A>
- inline void
- run_git (const dir_path& repo, A&&... args)
+ template <typename I, typename O, typename E, typename... A>
+ inline process
+ start_git (const dir_path& repo, I&& in, O&& out, E&& err, A&&... args)
{
- return run ("git", "-C", repo, forward<A> (args)...);
+ return start_git (forward<I> (in),
+ forward<O> (out),
+ forward<E> (err),
+ "-C", repo,
+ forward<A> (args)...);
}
- template <typename I, typename O, typename E, typename... A>
- inline process
- start_git (I&& in, O&& out, E&& err, const dir_path& repo, A&&... args)
+ inline void
+ finish_git (process& pr, bool io_read)
{
- return start (forward<I> (in),
- forward<O> (out),
- forward<E> (err),
- "git",
- "-C", repo,
- forward<A> (args)...);
+ finish ("git", pr, io_read);
}
template <typename... A>
inline optional<string>
git_line (const dir_path& repo, bool ie, A&&... args)
{
- fdpipe pipe (fdopen_pipe ());
- auto_fd null (ie ? fdnull () : auto_fd ());
-
- process pr (start (0 /* stdin */,
- pipe /* stdout */,
- ie ? null.get () : 2 /* stderr */,
- "git",
- "-C", repo,
- forward<A> (args)...));
-
- return git_line (move (pr), move (pipe), ie);
+ return git_line (ie,
+ "-C", repo,
+ forward<A> (args)...);
}
}
diff --git a/bdep/git.txx b/bdep/git.txx
new file mode 100644
index 0000000..aef5f3d
--- /dev/null
+++ b/bdep/git.txx
@@ -0,0 +1,50 @@
+// file : bdep/git.txx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+namespace bdep
+{
+ template <typename... A>
+ void
+ run_git (const dir_path& repo, A&&... args)
+ {
+ process pr (start_git (repo,
+ 0 /* stdin */,
+ 1 /* stdout */,
+ 2 /* stderr */,
+ forward<A> (args)...));
+
+ finish_git (pr);
+ }
+
+ void
+ git_check_version ();
+
+ template <typename I, typename O, typename E, typename... A>
+ process
+ start_git (I&& in, O&& out, E&& err, A&&... args)
+ {
+ git_check_version ();
+
+ return start (forward<I> (in),
+ forward<O> (out),
+ forward<E> (err),
+ "git",
+ forward<A> (args)...);
+ }
+
+ template <typename... A>
+ optional<string>
+ git_line (bool ie, A&&... args)
+ {
+ fdpipe pipe (fdopen_pipe ());
+ auto_fd null (ie ? fdnull () : auto_fd ());
+
+ process pr (start_git (0 /* stdin */,
+ pipe /* stdout */,
+ ie ? null.get () : 2 /* stderr */,
+ forward<A> (args)...));
+
+ return git_line (move (pr), move (pipe), ie);
+ }
+}
diff --git a/bdep/project-email.cxx b/bdep/project-email.cxx
index 2b836f2..6216d28 100644
--- a/bdep/project-email.cxx
+++ b/bdep/project-email.cxx
@@ -27,7 +27,7 @@ namespace bdep
// See if this is a VCS repository we recognize.
//
- if (git (prj))
+ if (git_repository (prj))
{
// In git the author email can be specified with the GIT_AUTHOR_EMAIL
// environment variable after which things fall back to the committer
diff --git a/bdep/publish.cxx b/bdep/publish.cxx
index 3650381..40a1724 100644
--- a/bdep/publish.cxx
+++ b/bdep/publish.cxx
@@ -44,7 +44,7 @@ namespace bdep
static url
control_url (const dir_path& prj)
{
- if (git (prj))
+ if (git_repository (prj))
{
// First try remote.origin.build2ControlUrl which can be used to specify
// a custom URL (e.g., if a correct one cannot be automatically derived
@@ -890,7 +890,7 @@ namespace bdep
//
// See if this is a VCS repository we recognize.
//
- if (ctrl && git (prj))
+ if (ctrl && git_repository (prj))
{
// Checkout the build2-control branch into a separate working tree not
// to interfere with the user's stuff.
@@ -919,10 +919,10 @@ namespace bdep
bool q (verb < 2);
auto_fd null (q ? fdnull () : auto_fd ());
- process pr (start_git (0 /* stdin */,
+ process pr (start_git (prj,
+ 0 /* stdin */,
q ? null.get () : 1 /* stdout */,
q ? null.get () : 2 /* stderr */,
- prj,
"worktree",
"add",
wd,
@@ -1003,15 +1003,15 @@ namespace bdep
auto_fd null (fdnull ());
fdpipe pipe (fdopen_pipe ());
- process pr (start_git (null.get () /* stdin */,
+ process pr (start_git (prj,
+ null.get () /* stdin */,
pipe /* stdout */,
2 /* stderr */,
- prj,
"hash-object",
"-wt", "tree",
"--stdin"));
- optional<string> tree (git_line (move (pr), move (pipe)));
+ optional<string> tree (git_line (move (pr), move (pipe), false));
if (!tree)
fail << "unable to create git tree object for build2-control";