summaryrefslogtreecommitdiff
path: root/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c160
1 files changed, 78 insertions, 82 deletions
diff --git a/setup.c b/setup.c
index 860507e1fd..b24c811c1c 100644
--- a/setup.c
+++ b/setup.c
@@ -3,6 +3,7 @@
#include "config.h"
#include "dir.h"
#include "string-list.h"
+#include "chdir-notify.h"
static int inside_git_dir = -1;
static int inside_work_tree = -1;
@@ -119,7 +120,7 @@ char *prefix_path(const char *prefix, int len, const char *path)
{
char *r = prefix_path_gently(prefix, len, NULL, path);
if (!r)
- die("'%s' is outside repository", path);
+ die(_("'%s' is outside repository"), path);
return r;
}
@@ -160,7 +161,7 @@ int check_filename(const char *prefix, const char *arg)
free(to_free);
return 0; /* file does not exist */
}
- die_errno("failed to stat '%s'", arg);
+ die_errno(_("failed to stat '%s'"), arg);
}
static void NORETURN die_verify_filename(const char *prefix,
@@ -230,7 +231,7 @@ void verify_filename(const char *prefix,
int diagnose_misspelt_rev)
{
if (*arg == '-')
- die("bad flag '%s' used after filename", arg);
+ die(_("option '%s' must come before non-option arguments"), arg);
if (looks_like_pathspec(arg) || check_filename(prefix, arg))
return;
die_verify_filename(prefix, arg, diagnose_misspelt_rev);
@@ -312,7 +313,9 @@ int is_git_directory(const char *suspect)
size_t len;
/* Check worktree-related signatures */
- strbuf_addf(&path, "%s/HEAD", suspect);
+ strbuf_addstr(&path, suspect);
+ strbuf_complete(&path, '/');
+ strbuf_addstr(&path, "HEAD");
if (validate_headref(path.buf))
goto done;
@@ -376,21 +379,18 @@ int is_inside_work_tree(void)
void setup_work_tree(void)
{
- const char *work_tree, *git_dir;
+ const char *work_tree;
static int initialized = 0;
if (initialized)
return;
if (work_tree_config_is_bogus)
- die("unable to set up work tree using invalid config");
+ die(_("unable to set up work tree using invalid config"));
work_tree = get_git_work_tree();
- git_dir = get_git_dir();
- if (!is_absolute_path(git_dir))
- git_dir = real_path(get_git_dir());
- if (!work_tree || chdir(work_tree))
- die("This operation must be run in a work tree");
+ if (!work_tree || chdir_notify(work_tree))
+ die(_("this operation must be run in a work tree"));
/*
* Make sure subsequent git processes find correct worktree
@@ -399,12 +399,6 @@ void setup_work_tree(void)
if (getenv(GIT_WORK_TREE_ENVIRONMENT))
setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
- /*
- * NEEDSWORK: this call can essentially be set_git_dir(get_git_dir())
- * which can cause some problems when trying to free the old value of
- * gitdir.
- */
- set_git_dir(remove_leading_path(git_dir, work_tree));
initialized = 1;
}
@@ -425,7 +419,11 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
;
else if (!strcmp(ext, "preciousobjects"))
data->precious_objects = git_config_bool(var, value);
- else
+ else if (!strcmp(ext, "partialclone")) {
+ if (!value)
+ return config_error_nonbool(var);
+ data->partial_clone = xstrdup(value);
+ } else
string_list_append(&data->unknown_extensions, ext);
} else if (strcmp(var, "core.bare") == 0) {
data->is_bare = git_config_bool(var, value);
@@ -437,16 +435,15 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
return 0;
}
-static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
+static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)
{
struct strbuf sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
- struct repository_format candidate;
int has_common;
has_common = get_common_dir(&sb, gitdir);
strbuf_addstr(&sb, "/config");
- read_repository_format(&candidate, sb.buf);
+ read_repository_format(candidate, sb.buf);
strbuf_release(&sb);
/*
@@ -454,10 +451,10 @@ static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
* we treat a missing config as a silent "ok", even when nongit_ok
* is unset.
*/
- if (candidate.version < 0)
+ if (candidate->version < 0)
return 0;
- if (verify_repository_format(&candidate, &err) < 0) {
+ if (verify_repository_format(candidate, &err) < 0) {
if (nongit_ok) {
warning("%s", err.buf);
strbuf_release(&err);
@@ -467,21 +464,22 @@ static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
die("%s", err.buf);
}
- repository_format_precious_objects = candidate.precious_objects;
- string_list_clear(&candidate.unknown_extensions, 0);
+ repository_format_precious_objects = candidate->precious_objects;
+ repository_format_partial_clone = candidate->partial_clone;
+ string_list_clear(&candidate->unknown_extensions, 0);
if (!has_common) {
- if (candidate.is_bare != -1) {
- is_bare_repository_cfg = candidate.is_bare;
+ if (candidate->is_bare != -1) {
+ is_bare_repository_cfg = candidate->is_bare;
if (is_bare_repository_cfg == 1)
inside_work_tree = -1;
}
- if (candidate.work_tree) {
+ if (candidate->work_tree) {
free(git_work_tree_cfg);
- git_work_tree_cfg = candidate.work_tree;
+ git_work_tree_cfg = candidate->work_tree;
inside_work_tree = -1;
}
} else {
- free(candidate.work_tree);
+ free(candidate->work_tree);
}
return 0;
@@ -492,6 +490,7 @@ int read_repository_format(struct repository_format *format, const char *path)
memset(format, 0, sizeof(*format));
format->version = -1;
format->is_bare = -1;
+ format->hash_algo = GIT_HASH_SHA1;
string_list_init(&format->unknown_extensions, 1);
git_config_from_file(check_repo_format, path, format);
return format->version;
@@ -528,25 +527,26 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir)
/* non-fatal; follow return path */
break;
case READ_GITFILE_ERR_OPEN_FAILED:
- die_errno("Error opening '%s'", path);
+ die_errno(_("error opening '%s'"), path);
case READ_GITFILE_ERR_TOO_LARGE:
- die("Too large to be a .git file: '%s'", path);
+ die(_("too large to be a .git file: '%s'"), path);
case READ_GITFILE_ERR_READ_FAILED:
- die("Error reading %s", path);
+ die(_("error reading %s"), path);
case READ_GITFILE_ERR_INVALID_FORMAT:
- die("Invalid gitfile format: %s", path);
+ die(_("invalid gitfile format: %s"), path);
case READ_GITFILE_ERR_NO_PATH:
- die("No path in gitfile: %s", path);
+ die(_("no path in gitfile: %s"), path);
case READ_GITFILE_ERR_NOT_A_REPO:
- die("Not a git repository: %s", dir);
+ die(_("not a git repository: %s"), dir);
default:
- die("BUG: unknown error code");
+ BUG("unknown error code");
}
}
/*
* Try to read the location of the git directory from the .git file,
- * return path to git directory if found.
+ * return path to git directory if found. The return value comes from
+ * a shared buffer.
*
* On failure, if return_error_code is not NULL, return_error_code
* will be set to an error code and NULL will be returned. If
@@ -627,6 +627,7 @@ cleanup_return:
static const char *setup_explicit_git_dir(const char *gitdirenv,
struct strbuf *cwd,
+ struct repository_format *repo_fmt,
int *nongit_ok)
{
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
@@ -635,7 +636,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
int offset;
if (PATH_MAX - 40 < strlen(gitdirenv))
- die("'$%s' too big", GIT_DIR_ENVIRONMENT);
+ die(_("'$%s' too big"), GIT_DIR_ENVIRONMENT);
gitfile = (char*)read_gitfile(gitdirenv);
if (gitfile) {
@@ -649,10 +650,10 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
free(gitfile);
return NULL;
}
- die("Not a git repository: '%s'", gitdirenv);
+ die(_("not a git repository: '%s'"), gitdirenv);
}
- if (check_repository_format_gently(gitdirenv, nongit_ok)) {
+ if (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {
free(gitfile);
return NULL;
}
@@ -678,12 +679,12 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
else {
char *core_worktree;
if (chdir(gitdirenv))
- die_errno("Could not chdir to '%s'", gitdirenv);
+ die_errno(_("cannot chdir to '%s'"), gitdirenv);
if (chdir(git_work_tree_cfg))
- die_errno("Could not chdir to '%s'", git_work_tree_cfg);
+ die_errno(_("cannot chdir to '%s'"), git_work_tree_cfg);
core_worktree = xgetcwd();
if (chdir(cwd->buf))
- die_errno("Could not come back to cwd");
+ die_errno(_("cannot come back to cwd"));
set_git_work_tree(core_worktree);
free(core_worktree);
}
@@ -711,7 +712,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
if (offset >= 0) { /* cwd inside worktree? */
set_git_dir(real_path(gitdirenv));
if (chdir(worktree))
- die_errno("Could not chdir to '%s'", worktree);
+ die_errno(_("cannot chdir to '%s'"), worktree);
strbuf_addch(cwd, '/');
free(gitfile);
return cwd->buf + offset;
@@ -725,9 +726,10 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
static const char *setup_discovered_git_dir(const char *gitdir,
struct strbuf *cwd, int offset,
+ struct repository_format *repo_fmt,
int *nongit_ok)
{
- if (check_repository_format_gently(gitdir, nongit_ok))
+ if (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))
return NULL;
/* --work-tree is set without --git-dir; use discovered one */
@@ -738,8 +740,8 @@ static const char *setup_discovered_git_dir(const char *gitdir,
if (offset != cwd->len && !is_absolute_path(gitdir))
gitdir = to_free = real_pathdup(gitdir, 1);
if (chdir(cwd->buf))
- die_errno("Could not come back to cwd");
- ret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);
+ die_errno(_("cannot come back to cwd"));
+ ret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
free(to_free);
return ret;
}
@@ -748,7 +750,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
if (is_bare_repository_cfg > 0) {
set_git_dir(offset == cwd->len ? gitdir : real_path(gitdir));
if (chdir(cwd->buf))
- die_errno("Could not come back to cwd");
+ die_errno(_("cannot come back to cwd"));
return NULL;
}
@@ -771,11 +773,12 @@ static const char *setup_discovered_git_dir(const char *gitdir,
/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
+ struct repository_format *repo_fmt,
int *nongit_ok)
{
int root_len;
- if (check_repository_format_gently(".", nongit_ok))
+ if (check_repository_format_gently(".", repo_fmt, nongit_ok))
return NULL;
setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
@@ -786,15 +789,15 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset);
if (chdir(cwd->buf))
- die_errno("Could not come back to cwd");
- return setup_explicit_git_dir(gitdir, cwd, nongit_ok);
+ die_errno(_("cannot come back to cwd"));
+ return setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
}
inside_git_dir = 1;
inside_work_tree = 0;
if (offset != cwd->len) {
if (chdir(cwd->buf))
- die_errno("Cannot come back to cwd");
+ die_errno(_("cannot come back to cwd"));
root_len = offset_1st_component(cwd->buf);
strbuf_setlen(cwd, offset > root_len ? offset : root_len);
set_git_dir(cwd->buf);
@@ -807,9 +810,9 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
static const char *setup_nongit(const char *cwd, int *nongit_ok)
{
if (!nongit_ok)
- die(_("Not a git repository (or any of the parent directories): %s"), DEFAULT_GIT_DIR_ENVIRONMENT);
+ die(_("not a git repository (or any of the parent directories): %s"), DEFAULT_GIT_DIR_ENVIRONMENT);
if (chdir(cwd))
- die_errno(_("Cannot come back to cwd"));
+ die_errno(_("cannot come back to cwd"));
*nongit_ok = 1;
return NULL;
}
@@ -818,7 +821,7 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_
{
struct stat buf;
if (stat(path, &buf)) {
- die_errno("failed to stat '%*s%s%s'",
+ die_errno(_("failed to stat '%*s%s%s'"),
prefix_len,
prefix ? prefix : "",
prefix ? "/" : "", path);
@@ -925,7 +928,7 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
* - ../.git
* - ../.git/
* - ../ (bare)
- * - ../../.git/
+ * - ../../.git
* etc.
*/
one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
@@ -1027,7 +1030,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
{
static struct strbuf cwd = STRBUF_INIT;
struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT;
- const char *prefix, *env_prefix;
+ const char *prefix;
+ struct repository_format repo_fmt;
/*
* We may have read an incomplete configuration before
@@ -1055,18 +1059,18 @@ const char *setup_git_directory_gently(int *nongit_ok)
prefix = NULL;
break;
case GIT_DIR_EXPLICIT:
- prefix = setup_explicit_git_dir(gitdir.buf, &cwd, nongit_ok);
+ prefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);
break;
case GIT_DIR_DISCOVERED:
if (dir.len < cwd.len && chdir(dir.buf))
- die(_("Cannot change to '%s'"), dir.buf);
+ die(_("cannot change to '%s'"), dir.buf);
prefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,
- nongit_ok);
+ &repo_fmt, nongit_ok);
break;
case GIT_DIR_BARE:
if (dir.len < cwd.len && chdir(dir.buf))
- die(_("Cannot change to '%s'"), dir.buf);
- prefix = setup_bare_git_dir(&cwd, dir.len, nongit_ok);
+ die(_("cannot change to '%s'"), dir.buf);
+ prefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);
break;
case GIT_DIR_HIT_CEILING:
prefix = setup_nongit(cwd.buf, nongit_ok);
@@ -1078,23 +1082,13 @@ const char *setup_git_directory_gently(int *nongit_ok)
strbuf_release(&dir);
return NULL;
}
- die(_("Not a git repository (or any parent up to mount point %s)\n"
+ die(_("not a git repository (or any parent up to mount point %s)\n"
"Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."),
dir.buf);
default:
- die("BUG: unhandled setup_git_directory_1() result");
+ BUG("unhandled setup_git_directory_1() result");
}
- /*
- * NEEDSWORK: This was a hack in order to get ls-files and grep to have
- * properly formated output when recursing submodules. Once ls-files
- * and grep have been changed to perform this recursing in-process this
- * needs to be removed.
- */
- env_prefix = getenv(GIT_TOPLEVEL_PREFIX_ENVIRONMENT);
- if (env_prefix)
- prefix = env_prefix;
-
if (prefix)
setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
else
@@ -1119,9 +1113,10 @@ const char *setup_git_directory_gently(int *nongit_ok)
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
if (!gitdir)
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
- repo_set_gitdir(the_repository, gitdir);
- setup_git_env();
+ setup_git_env(gitdir);
}
+ if (startup_info->have_repository)
+ repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
}
strbuf_release(&dir);
@@ -1170,7 +1165,7 @@ int git_config_perm(const char *var, const char *value)
/* A filemode value was given: 0xxx */
if ((i & 0600) != 0600)
- die(_("Problem with core.sharedRepository filemode value "
+ die(_("problem with core.sharedRepository filemode value "
"(0%.3o).\nThe owner of files must always have "
"read and write permissions."), i);
@@ -1183,7 +1178,8 @@ int git_config_perm(const char *var, const char *value)
void check_repository_format(void)
{
- check_repository_format_gently(get_git_dir(), NULL);
+ struct repository_format repo_fmt;
+ check_repository_format_gently(get_git_dir(), &repo_fmt, NULL);
startup_info->have_repository = 1;
}
@@ -1212,7 +1208,7 @@ void sanitize_stdfds(void)
while (fd != -1 && fd < 2)
fd = dup(fd);
if (fd == -1)
- die_errno("open /dev/null or dup failed");
+ die_errno(_("open /dev/null or dup failed"));
if (fd > 2)
close(fd);
}
@@ -1227,12 +1223,12 @@ int daemonize(void)
case 0:
break;
case -1:
- die_errno("fork failed");
+ die_errno(_("fork failed"));
default:
exit(0);
}
if (setsid() == -1)
- die_errno("setsid failed");
+ die_errno(_("setsid failed"));
close(0);
close(1);
close(2);