Skip to content

Commit

Permalink
Merge branch 'jk/check-repository-format'
Browse files Browse the repository at this point in the history
The repository set-up sequence has been streamlined (the biggest
change is that there is no longer git_config_early()), so that we
do not attempt to look into refs/* when we know we do not have a
Git repository.

* jk/check-repository-format:
  verify_repository_format: mark messages for translation
  setup: drop repository_format_version global
  setup: unify repository version callbacks
  init: use setup.c's repo version verification
  setup: refactor repo format reading and verification
  config: drop git_config_early
  check_repository_format_gently: stop using git_config_early
  lazily load core.sharedrepository
  wrap shared_repository global in get/set accessors
  setup: document check_repository_format()
  • Loading branch information
gitster committed Apr 13, 2016
2 parents 7b0d47b + 274db84 commit 907c416
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 114 deletions.
7 changes: 0 additions & 7 deletions Documentation/technical/api-config.txt
Expand Up @@ -63,13 +63,6 @@ parse for configuration, rather than looking in the usual files. Regular
Specify whether include directives should be followed in parsed files.
Regular `git_config` defaults to `1`.

There is a special version of `git_config` called `git_config_early`.
This version takes an additional parameter to specify the repository
config, instead of having it looked up via `git_path`. This is useful
early in a Git program before the repository has been found. Unless
you're working with early setup code, you probably don't want to use
this.

Reading Specific Files
----------------------

Expand Down
45 changes: 24 additions & 21 deletions builtin/init-db.c
Expand Up @@ -95,6 +95,8 @@ static void copy_templates(const char *template_dir)
struct strbuf path = STRBUF_INIT;
struct strbuf template_path = STRBUF_INIT;
size_t template_len;
struct repository_format template_format;
struct strbuf err = STRBUF_INIT;
DIR *dir;
char *to_free = NULL;

Expand All @@ -121,17 +123,18 @@ static void copy_templates(const char *template_dir)

/* Make sure that template is from the correct vintage */
strbuf_addstr(&template_path, "config");
repository_format_version = 0;
git_config_from_file(check_repository_format_version,
template_path.buf, NULL);
read_repository_format(&template_format, template_path.buf);
strbuf_setlen(&template_path, template_len);

if (repository_format_version &&
repository_format_version != GIT_REPO_VERSION) {
warning(_("not copying templates of "
"a wrong format version %d from '%s'"),
repository_format_version,
template_dir);
/*
* No mention of version at all is OK, but anything else should be
* verified.
*/
if (template_format.version >= 0 &&
verify_repository_format(&template_format, &err) < 0) {
warning(_("not copying templates from '%s': %s"),
template_dir, err.buf);
strbuf_release(&err);
goto close_free_return;
}

Expand Down Expand Up @@ -199,13 +202,13 @@ static int create_default_files(const char *template_path)

/* reading existing config may have overwrote it */
if (init_shared_repository != -1)
shared_repository = init_shared_repository;
set_shared_repository(init_shared_repository);

/*
* We would have created the above under user's umask -- under
* shared-repository settings, we would need to fix them up.
*/
if (shared_repository) {
if (get_shared_repository()) {
adjust_shared_perm(get_git_dir());
adjust_shared_perm(git_path_buf(&buf, "refs"));
adjust_shared_perm(git_path_buf(&buf, "refs/heads"));
Expand Down Expand Up @@ -370,20 +373,20 @@ int init_db(const char *template_dir, unsigned int flags)

create_object_directory();

if (shared_repository) {
if (get_shared_repository()) {
char buf[10];
/* We do not spell "group" and such, so that
* the configuration can be read by older version
* of git. Note, we use octal numbers for new share modes,
* and compatibility values for PERM_GROUP and
* PERM_EVERYBODY.
*/
if (shared_repository < 0)
if (get_shared_repository() < 0)
/* force to the mode value */
xsnprintf(buf, sizeof(buf), "0%o", -shared_repository);
else if (shared_repository == PERM_GROUP)
xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository());
else if (get_shared_repository() == PERM_GROUP)
xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP);
else if (shared_repository == PERM_EVERYBODY)
else if (get_shared_repository() == PERM_EVERYBODY)
xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY);
else
die("BUG: invalid value for shared_repository");
Expand All @@ -399,7 +402,7 @@ int init_db(const char *template_dir, unsigned int flags)
"", and the last '%s%s' is the verbatim directory name. */
printf(_("%s%s Git repository in %s%s\n"),
reinit ? _("Reinitialized existing") : _("Initialized empty"),
shared_repository ? _(" shared") : "",
get_shared_repository() ? _(" shared") : "",
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
}

Expand Down Expand Up @@ -494,8 +497,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
* and we know shared_repository should always be 0;
* but just in case we play safe.
*/
saved = shared_repository;
shared_repository = 0;
saved = get_shared_repository();
set_shared_repository(0);
switch (safe_create_leading_directories_const(argv[0])) {
case SCLD_OK:
case SCLD_PERMS:
Expand All @@ -507,7 +510,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
die_errno(_("cannot mkdir %s"), argv[0]);
break;
}
shared_repository = saved;
set_shared_repository(saved);
if (mkdir(argv[0], 0777) < 0)
die_errno(_("cannot mkdir %s"), argv[0]);
mkdir_tried = 1;
Expand All @@ -525,7 +528,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
}

if (init_shared_repository != -1)
shared_repository = init_shared_repository;
set_shared_repository(init_shared_repository);

/*
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
Expand Down
40 changes: 35 additions & 5 deletions cache.h
Expand Up @@ -651,7 +651,6 @@ extern int prefer_symlink_refs;
extern int log_all_ref_updates;
extern int warn_ambiguous_refs;
extern int warn_on_object_refname_ambiguity;
extern int shared_repository;
extern const char *apply_default_whitespace;
extern const char *apply_default_ignorewhitespace;
extern const char *git_attributes_file;
Expand All @@ -664,6 +663,9 @@ extern size_t delta_base_cache_limit;
extern unsigned long big_file_threshold;
extern unsigned long pack_size_limit_cfg;

void set_shared_repository(int value);
int get_shared_repository(void);

/*
* Do replace refs need to be checked this run? This variable is
* initialized to true unless --no-replace-object is used or
Expand Down Expand Up @@ -745,9 +747,39 @@ extern int grafts_replace_parents;
*/
#define GIT_REPO_VERSION 0
#define GIT_REPO_VERSION_READ 1
extern int repository_format_version;
extern int repository_format_precious_objects;
extern int check_repository_format(void);

struct repository_format {
int version;
int precious_objects;
int is_bare;
char *work_tree;
struct string_list unknown_extensions;
};

/*
* Read the repository format characteristics from the config file "path" into
* "format" struct. Returns the numeric version. On error, -1 is returned,
* format->version is set to -1, and all other fields in the struct are
* undefined.
*/
int read_repository_format(struct repository_format *format, const char *path);

/*
* Verify that the repository described by repository_format is something we
* can read. If it is, return 0. Otherwise, return -1, and "err" will describe
* any errors encountered.
*/
int verify_repository_format(const struct repository_format *format,
struct strbuf *err);

/*
* Check the repository format version in the path found in get_git_dir(),
* and die if it is a version we don't understand. Generally one would
* set_git_dir() before calling this, and use it only for "are we in a valid
* repo?".
*/
extern void check_repository_format(void);

#define MTIME_CHANGED 0x0001
#define CTIME_CHANGED 0x0002
Expand Down Expand Up @@ -1526,7 +1558,6 @@ extern void git_config(config_fn_t fn, void *);
extern int git_config_with_options(config_fn_t fn, void *,
struct git_config_source *config_source,
int respect_includes);
extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
extern int git_parse_ulong(const char *, unsigned long *);
extern int git_parse_maybe_bool(const char *);
extern int git_config_int(const char *, const char *);
Expand All @@ -1550,7 +1581,6 @@ extern void git_config_set_multivar_in_file(const char *, const char *, const ch
extern int git_config_rename_section(const char *, const char *);
extern int git_config_rename_section_in_file(const char *, const char *, const char *);
extern const char *git_etc_gitconfig(void);
extern int check_repository_format_version(const char *var, const char *value, void *cb);
extern int git_env_bool(const char *, int);
extern unsigned long git_env_ulong(const char *, unsigned long);
extern int git_config_system(void);
Expand Down
12 changes: 4 additions & 8 deletions config.c
Expand Up @@ -1188,11 +1188,12 @@ int git_config_system(void)
return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
}

int git_config_early(config_fn_t fn, void *data, const char *repo_config)
static int do_git_config_sequence(config_fn_t fn, void *data)
{
int ret = 0, found = 0;
char *xdg_config = xdg_config_home("config");
char *user_config = expand_user_path("~/.gitconfig");
char *repo_config = git_pathdup("config");

if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0)) {
ret += git_config_from_file(fn, git_etc_gitconfig(),
Expand Down Expand Up @@ -1228,15 +1229,14 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)

free(xdg_config);
free(user_config);
free(repo_config);
return ret == 0 ? found : ret;
}

int git_config_with_options(config_fn_t fn, void *data,
struct git_config_source *config_source,
int respect_includes)
{
char *repo_config = NULL;
int ret;
struct config_include_data inc = CONFIG_INCLUDE_INIT;

if (respect_includes) {
Expand All @@ -1257,11 +1257,7 @@ int git_config_with_options(config_fn_t fn, void *data,
else if (config_source && config_source->blob)
return git_config_from_blob_ref(fn, config_source->blob, data);

repo_config = git_pathdup("config");
ret = git_config_early(fn, data, repo_config);
if (repo_config)
free(repo_config);
return ret;
return do_git_config_sequence(fn, data);
}

static void git_config_raw(config_fn_t fn, void *data)
Expand Down
23 changes: 21 additions & 2 deletions environment.c
Expand Up @@ -25,11 +25,9 @@ int log_all_ref_updates = -1; /* unspecified */
int warn_ambiguous_refs = 1;
int warn_on_object_refname_ambiguity = 1;
int ref_paranoia = -1;
int repository_format_version;
int repository_format_precious_objects;
const char *git_commit_encoding;
const char *git_log_output_encoding;
int shared_repository = PERM_UMASK;
const char *apply_default_whitespace;
const char *apply_default_ignorewhitespace;
const char *git_attributes_file;
Expand Down Expand Up @@ -324,3 +322,24 @@ const char *get_commit_output_encoding(void)
{
return git_commit_encoding ? git_commit_encoding : "UTF-8";
}

static int the_shared_repository = PERM_UMASK;
static int need_shared_repository_from_config = 1;

void set_shared_repository(int value)
{
the_shared_repository = value;
need_shared_repository_from_config = 0;
}

int get_shared_repository(void)
{
if (need_shared_repository_from_config) {
const char *var = "core.sharedrepository";
const char *value;
if (!git_config_get_value(var, &value))
the_shared_repository = git_config_perm(var, value);
need_shared_repository_from_config = 0;
}
return the_shared_repository;
}
10 changes: 5 additions & 5 deletions path.c
Expand Up @@ -702,17 +702,17 @@ static int calc_shared_perm(int mode)
{
int tweak;

if (shared_repository < 0)
tweak = -shared_repository;
if (get_shared_repository() < 0)
tweak = -get_shared_repository();
else
tweak = shared_repository;
tweak = get_shared_repository();

if (!(mode & S_IWUSR))
tweak &= ~0222;
if (mode & S_IXUSR)
/* Copy read bits to execute bits */
tweak |= (tweak & 0444) >> 2;
if (shared_repository < 0)
if (get_shared_repository() < 0)
mode = (mode & ~0777) | tweak;
else
mode |= tweak;
Expand All @@ -725,7 +725,7 @@ int adjust_shared_perm(const char *path)
{
int old_mode, new_mode;

if (!shared_repository)
if (!get_shared_repository())
return 0;
if (get_st_mode_bits(path, &old_mode) < 0)
return -1;
Expand Down

0 comments on commit 907c416

Please sign in to comment.