aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-06-22 15:49:05 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-06-22 19:31:26 +0300
commitc2404728b623588aa89920ae435b48af0fef011e (patch)
treeba739c37837b71dbc8881cad81204ac2ee6f50e4
parentf95f24412ea85149556b34abb91f06e247d6db6d (diff)
Add branch sub-option for git project vcs in bdep-new
Also fix tests which failed if for the initial branch git-init defaults to the name other than 'master'.
-rw-r--r--bdep/git.cxx23
-rw-r--r--bdep/git.hxx40
-rw-r--r--bdep/git.txx6
-rw-r--r--bdep/new.cli8
-rw-r--r--bdep/new.cxx46
-rw-r--r--tests/ci.testscript6
-rw-r--r--tests/init.testscript1
-rw-r--r--tests/project.testscript5
-rw-r--r--tests/publish.testscript4
-rw-r--r--tests/release.testscript7
10 files changed, 126 insertions, 20 deletions
diff --git a/bdep/git.cxx b/bdep/git.cxx
index cc697b3..f9bdc04 100644
--- a/bdep/git.cxx
+++ b/bdep/git.cxx
@@ -24,10 +24,8 @@ namespace bdep
static optional<semantic_version> bun_git_ver;
#endif
- // Check that git is at least of the specified minimum supported version.
- //
- void
- git_check_version (const semantic_version& min_ver, bool system)
+ bool
+ git_try_check_version (const semantic_version& min_ver, bool system)
{
// Query and cache git version on the first call.
//
@@ -50,9 +48,24 @@ namespace bdep
// Note that we don't expect the min_ver to contain the build component,
// that doesn't matter functionality-wise for git.
//
- if (*gv < min_ver)
+ return *gv >= min_ver;
+ }
+
+ // As above but issue diagnostics and fail if git is older than the
+ // specified minimum supported version.
+ //
+ void
+ git_check_version (const semantic_version& min_ver, bool system)
+ {
+ if (!git_try_check_version (min_ver, system))
+ {
+ optional<semantic_version>& gv (system ? sys_git_ver : bun_git_ver);
+
+ assert (gv); // Must have been cached by git_try_check_version().
+
fail << "unsupported git version " << *gv <<
info << "minimum supported version is " << min_ver << endf;
+ }
}
// Return git process path and the --exec-path option, if it is required for
diff --git a/bdep/git.hxx b/bdep/git.hxx
index b7703ea..30baf69 100644
--- a/bdep/git.hxx
+++ b/bdep/git.hxx
@@ -67,18 +67,50 @@ namespace bdep
// Run git process.
//
+ // Pass NULL as the repository argument if the git command is not
+ // repository-specific (e.g., init).
+ //
template <typename... A>
void
run_git (const semantic_version&,
bool system,
bool progress,
- const dir_path& repo,
+ const dir_path* repo,
A&&... args);
template <typename... A>
inline void
run_git (const semantic_version& min_ver,
bool system,
+ const dir_path* repo,
+ A&&... args)
+ {
+ run_git (min_ver,
+ system,
+ true /* progress */,
+ repo,
+ forward<A> (args)...);
+ }
+
+ template <typename... A>
+ inline void
+ run_git (const semantic_version& min_ver,
+ bool system,
+ bool progress,
+ const dir_path& repo,
+ A&&... args)
+ {
+ run_git (min_ver,
+ system,
+ progress,
+ &repo,
+ forward<A> (args)...);
+ }
+
+ template <typename... A>
+ inline void
+ run_git (const semantic_version& min_ver,
+ bool system,
const dir_path& repo,
A&&... args)
{
@@ -173,6 +205,12 @@ namespace bdep
template <typename... A>
void
git_push (const common_options&, const dir_path& repo, A&&... args);
+
+ // Return true if git is at least of the specified minimum supported
+ // version.
+ //
+ bool
+ git_try_check_version (const semantic_version&, bool system);
}
#include <bdep/git.ixx>
diff --git a/bdep/git.txx b/bdep/git.txx
index ef81bd8..2af8e1f 100644
--- a/bdep/git.txx
+++ b/bdep/git.txx
@@ -8,7 +8,7 @@ namespace bdep
run_git (const semantic_version& min_ver,
bool system,
bool progress,
- const dir_path& repo,
+ const dir_path* repo,
A&&... args)
{
// Unfortunately git doesn't have any kind of a no-progress option but
@@ -30,10 +30,12 @@ namespace bdep
//
process pr (start_git (min_ver,
system,
- repo,
0 /* stdin */,
err /* stdout */,
err /* stderr */,
+ (repo != nullptr
+ ? cstrings ({"-C", repo->string ().c_str ()})
+ : cstrings ()),
forward<A> (args)...));
bool io (false);
diff --git a/bdep/new.cli b/bdep/new.cli
index 8f3b094..c6dc8ee 100644
--- a/bdep/new.cli
+++ b/bdep/new.cli
@@ -501,7 +501,12 @@ namespace bdep
\li|\cb{git}
Initialize a \cb{git(1)} repository inside the project and generate
- \cb{.gitignore} files.||
+ \cb{.gitignore} files. Recognized version control system sub-options:|
+
+ \li|\n\ \ \ \c{\b{branch=}\i{name}}
+
+ Use the specified name for the initial branch in the newly created
+ repository.||
\dl|
@@ -632,6 +637,7 @@ namespace bdep
//
class cmd_new_git_options
{
+ string branch;
};
class cmd_new_none_options
diff --git a/bdep/new.cxx b/bdep/new.cxx
index 2c954fc..a2d2ad4 100644
--- a/bdep/new.cxx
+++ b/bdep/new.cxx
@@ -24,6 +24,13 @@ using namespace butl;
namespace bdep
{
+ // While we don't have any specific requirements for git version here, let's
+ // use the lowest common denominator for other bdep commands. Note that
+ // *_git() functions require the minimum supported git version as an
+ // argument.
+ //
+ static const semantic_version git_ver {2, 1, 0};
+
// License id to full name map.
//
// Used for the license full name search for the auto-detected and
@@ -1235,8 +1242,43 @@ cmd_new (cmd_new_options&& o, cli::group_scanner& args)
{
switch (vc)
{
- case vcs::git: run ("git", "init", "-q", out); break;
- case vcs::none: break;
+ case vcs::git:
+ {
+ const cmd_new_git_options& opt (vc.git_opt);
+
+ // If the branch name is specified, then pass it to git-init using the
+ // --initial-branch option if the git version is at least 2.28.0 (the
+ // one which has introduced this option). Otherwise, run git-init
+ // normally and then change HEAD to refer to the requested name. Note
+ // that the branch will only be created on the first commit.
+ //
+ if (opt.branch_specified ())
+ {
+ if (git_try_check_version (semantic_version {2, 28, 0},
+ true /* system */))
+ {
+ run_git (git_ver, true /* system */, nullptr /* repo */,
+ "init", "-q", "--initial-branch", opt.branch (), out);
+ }
+ else
+ {
+ run_git (git_ver, true /* system */, nullptr /* repo */,
+ "init", "-q", out);
+
+ run_git (git_ver, true /* system */, out,
+ "symbolic-ref",
+ "-q",
+ "HEAD",
+ "refs/heads/" + opt.branch ());
+ }
+ }
+ else
+ run_git (git_ver, true /* system */, nullptr /* repo */,
+ "init", "-q", out);
+
+ break;
+ }
+ case vcs::none: break;
}
}
diff --git a/tests/ci.testscript b/tests/ci.testscript
index cff198b..d604aa7 100644
--- a/tests/ci.testscript
+++ b/tests/ci.testscript
@@ -20,7 +20,7 @@ end
# Create the remote repository.
#
+mkdir --no-cleanup prj.git
-+git -C prj.git init --bare --quiet &prj.git/***
++git -C prj.git -c init.defaultBranch=master init --bare --quiet &prj.git/***
# Adjust the local repository and push it to the remote one.
#
@@ -53,7 +53,7 @@ test.arguments += --yes --repository "$repository" --server "$server" \
config_cxx = [cmdline] cc config.cxx=$quote($recall($cxx.path) $cxx.config.mode, true)
-new += 2>!
+new += --vcs git,branch=master 2>!
init += $config_cxx -d prj 2>! &prj/**/bootstrap/***
windows = ($cxx.target.class == 'windows')
@@ -663,7 +663,7 @@ windows = ($cxx.target.class == 'windows')
# Create the remote repository.
#
+mkdir --no-cleanup prj.git
- +git -C prj.git init --bare --quiet &prj.git/***
+ +git -C prj.git -c init.defaultBranch=master init --bare --quiet &prj.git/***
# Create the local repository and push it to the remote one.
#
diff --git a/tests/init.testscript b/tests/init.testscript
index 2a4f686..2e66721 100644
--- a/tests/init.testscript
+++ b/tests/init.testscript
@@ -8,6 +8,7 @@
config_cxx = [cmdline] cc config.cxx=$quote($recall($cxx.path) $cxx.config.mode, true)
+new += --vcs git,branch=master
status += -d prj
: create-cfg
diff --git a/tests/project.testscript b/tests/project.testscript
index b40f7da..a675081 100644
--- a/tests/project.testscript
+++ b/tests/project.testscript
@@ -9,7 +9,10 @@
# project can not be shared between multiple bdep processes. Also we need to
# make sure that projects are not cloned while being used by bdep.
#
-+$new prj 2>- &prj/*** # By default: -t exe -l c++.
+# Make sure that the initial branch is named as 'master', since tests may rely
+# on that.
+#
++$new --vcs git,branch=master prj 2>! &prj/*** # By default: -t exe -l c++.
# The most commonly used project cloning command that copies it from the
# parent scope working directory.
diff --git a/tests/publish.testscript b/tests/publish.testscript
index 1fd8d38..41b5eed 100644
--- a/tests/publish.testscript
+++ b/tests/publish.testscript
@@ -22,7 +22,7 @@ test.arguments += --repository "$repository" --yes \
config_cxx = [cmdline] cc config.cxx=$quote($recall($cxx.path) $cxx.config.mode, true)
-new += 2>!
+new += --vcs git,branch=master 2>!
init += $config_cxx -d prj 2>! &prj/**/bootstrap/***
windows = ($cxx.target.class == 'windows')
@@ -438,7 +438,7 @@ g = [cmdline] git -C prj >! 2>!
# Create the remote repository.
#
+mkdir --no-cleanup prj.git
- +git -C prj.git init --bare --quiet &prj.git/***
+ +git -C prj.git -c init.defaultBranch=master init --bare --quiet &prj.git/***
+$clone_prj
diff --git a/tests/release.testscript b/tests/release.testscript
index 1140161..2b86964 100644
--- a/tests/release.testscript
+++ b/tests/release.testscript
@@ -16,7 +16,7 @@ g = [cmdline] git 2>! >&2
# Create the remote repository.
#
+mkdir --no-cleanup prj.git
-+$g -C prj.git init --bare &prj.git/***
++$g -C prj.git -c init.defaultBranch=master init --bare &prj.git/***
clone_rep = [cmdline] cp --no-cleanup -pr ../prj.git ./ &prj.git/***
clone_root_rep = [cmdline] cp --no-cleanup -pr $~/prj.git ./ &prj.git/***
@@ -54,6 +54,8 @@ pull2 = [cmdline] $gp2 pull --ff-only
fetch2 = [cmdline] $gp2 fetch
log2 = [cmdline] $gp2 log '--pretty=format:"%d %s"'
+new += --vcs git,branch=master 2>-
+
: single-pkg
:
{
@@ -1103,11 +1105,10 @@ log2 = [cmdline] $gp2 log '--pretty=format:"%d %s"'
# Create the remote repository.
#
+mkdir --no-cleanup prj.git
- +git -C prj.git init --bare --quiet &prj.git/***
+ +git -C prj.git -c init.defaultBranch=master init --bare --quiet &prj.git/***
# Create the local repository.
#
- new += 2>-
+$new -t empty prj &prj/***
+$new -t exe --package prj -d prj
+$new -t lib --package libprj -d prj