environment: guard reliance on `the_repository`
cover environment: guard reliance on `the_repository`
Hi,
this patch series is the next part in the epic to get rid of the_repository. This time around I focussed on the environment subsystem, which relies on the_repository both implicitly and explicitly.
The series is structured as follows:
- Patches 1 to 6 moves functions that belong to the repository subsystem.
- Patches 7 and 8 adapt the config subsystem to stop depending on the the_repository again, which had to be added by the preceding patches.
- Patches 9 to 11 move various functionality that is misplaced and that depends on the_repository.
- Patches 12 and 13 guard functionality that relies on global state in the environment subsystem via USE_THE_REPOSITORY_VARIBABLE.
- Patches 14 to 21 demonstrate how to get rid of global config variables part of the environment subsystem for a subset of them. Overall, I think that our reliance on global variables is broken because those variables may or may not point to the actual config of a specific repository we currently hold. They may not even hold state of the_repository, but might've been changed by subsequent logic where we parse another repository's config.
I'm a bit unhappy that I wasn't able to adapt is_bare_repository() to take a struct repository yet, and as a consequence a bunch of code needs to declare USE_THE_REPOSITORY_VARIBABLE again. But it depends on another global variable is_bare_repository_cfg which is being modified quite heavily in multiple subsystems, and the resulting semantics are... confusing. I guess we'll need another biggish patch series to clean up this mess by making the setup subsystem not rely on such global state anymore.
The series is built on top of 17d4b10aea (The tenth batch, 2024-08-28). It merges with next rather cleanish, except for a single merge conflict with headers.
Thanks!
Patrick
Patrick Steinhardt (21):
environment: make get_git_dir() accept a repository
environment: make get_git_common_dir() accept a repository
environment: make get_object_directory() accept a repository
environment: make get_index_file() accept a repository
environment: make get_graft_file() accept a repository
environment: make get_git_work_tree() accept a repository
config: document read_early_config() and read_very_early_config()
config: make dependency on repo in read_early_config() explicit
environment: move odb_mkstemp() into object layer
environment: make get_git_namespace() self-contained
environment: move set_git_dir() and related into setup layer
environment: reorder header to split out the_repository-free section
environment: guard state depending on a repository
repo-settings: split out declarations into a standalone header
branch: stop modifying log_all_ref_updates variable
refs: stop modifying global log_all_ref_updates variable
repo-settings: track defaults close to struct repo_settings
environment: stop storing "core.logAllRefUpdates" globally
environment: stop storing "core.preferSymlinkRefs" globally
environment: stop storing "core.warnAmbiguousRefs" globally
environment: stop storing "core.notesRef" globally
alias.c | 6 +- apply.c | 2 +- branch.c | 5 +- builtin/am.c | 13 +- builtin/blame.c | 2 +- builtin/checkout.c | 4 +- builtin/commit-graph.c | 4 +- builtin/commit.c | 12 +- builtin/config.c | 4 +- builtin/count-objects.c | 2 +- builtin/difftool.c | 8 +- builtin/fsmonitor--daemon.c | 6 +- builtin/gc.c | 2 +- builtin/init-db.c | 4 +- builtin/merge.c | 17 +-- builtin/multi-pack-index.c | 2 +- builtin/notes.c | 22 ++-- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 +- builtin/repack.c | 7 +- builtin/replace.c | 2 +- builtin/reset.c | 4 +- builtin/rev-parse.c | 9 +- builtin/stash.c | 16 +-- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 4 +- builtin/worktree.c | 4 +- builtin/write-tree.c | 3 +- bulk-checkin.c | 4 +- bundle-uri.c | 1 + cache-tree.c | 3 +- commit.c | 4 +- config.c | 42 +------ config.h | 13 +- dir.c | 2 +- environment.c | 237 +++++------------------------------- environment.h | 142 ++++++++++----------- fetch-pack.c | 2 +- fsmonitor.c | 2 +- help.c | 2 +- http-backend.c | 2 +- name-hash.c | 3 + notes.c | 21 ++-- notes.h | 3 +- object-file.c | 37 +++++- object-name.c | 4 +- object-store-ll.h | 15 +++ pack-write.c | 2 +- packfile.c | 2 +- pager.c | 7 +- path.c | 2 + pathspec.c | 4 +- preload-index.c | 3 + prompt.c | 2 + prune-packed.c | 4 +- read-cache.c | 5 +- ref-filter.c | 2 +- refs.c | 7 +- refs.h | 4 +- refs/files-backend.c | 31 +++-- refs/reftable-backend.c | 22 ++-- repo-settings.c | 35 +++++- repo-settings.h | 75 ++++++++++++ repository.c | 40 ++++++ repository.h | 58 ++------- server-info.c | 3 +- setup.c | 152 +++++++++++++++++++---- setup.h | 5 +- sparse-index.c | 2 + statinfo.c | 2 + submodule.c | 2 +- t/helper/test-config.c | 3 +- t/helper/test-path-utils.c | 2 + tmp-objdir.c | 7 +- trace.c | 8 +- trace2/tr2_cfg.c | 4 +- transport-helper.c | 2 +- tree-diff.c | 3 + userdiff.c | 2 + worktree.c | 12 +- wt-status.c | 2 +- 81 files changed, 677 insertions(+), 554 deletions(-) create mode 100644 repo-settings.h
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 1/21 environment: make `get_git_dir()` accept a repository
The get_git_dir() function retrieves the path to the Git directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- apply.c | 2 +- builtin/am.c | 5 +++-- builtin/commit.c | 6 +++--- builtin/config.c | 2 +- builtin/difftool.c | 4 ++-- builtin/fsmonitor--daemon.c | 3 ++- builtin/merge.c | 3 ++- builtin/stash.c | 2 +- cache-tree.c | 3 ++- config.c | 4 +++- environment.c | 10 ++-------- environment.h | 1 - pathspec.c | 2 +- read-cache.c | 5 +++-- repository.c | 7 +++++++ repository.h | 2 ++ setup.c | 12 ++++++------ setup.h | 2 +- trace.c | 4 +++- transport-helper.c | 2 +- worktree.c | 4 ++-- 21 files changed, 48 insertions(+), 37 deletions(-)
apply.c +1 -1
@@ -4111,7 +4111,7 @@ static int read_apply_cache(struct apply_state *state) {if (state->index_file)return read_index_from (state->repo->index, state->index_file, -get_git_dir ()); +repo_get_git_dir (the_repository));else return repo_read_index (state->repo); }
builtin/am.c +3 -2
@@ -1544,7 +1544,8 @@ static int run_apply(const struct am_state *state, const char *index_file)if (index_file) {/* Reload index as apply_all_patches() will have modified it. */ discard_index (the_repository->index); -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository)); }return 0 ;
@@ -1587,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pareturn error ("could not build fake ancestor" );discard_index (the_repository->index); -read_index_from (the_repository->index, index_path,get_git_dir ()); +read_index_from (the_repository->index, index_path,repo_get_git_dir (the_repository));if (write_index_as_tree (&bases[0 ], the_repository->index, index_path,0 ,NULL ))return error (_ ("Repository lacks necessary blobs to fall back on 3-way merge." ));
builtin/commit.c +3 -3
@@ -407,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index);read_index_from (the_repository->index,get_lock_file_path (&index_lock), -get_git_dir ()); +repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,WRITE_TREE_SILENT ) ==0 ) {if (reopen_lock_file (&index_lock) <0 )die (_ ("unable to write index file" ));
@@ -534,7 +534,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index); ret =get_lock_file_path (&false_lock); -read_index_from (the_repository->index, ret,get_git_dir ()); +read_index_from (the_repository->index, ret,repo_get_git_dir (the_repository)); out:string_list_clear (&partial,0 );clear_pathspec (&pathspec);
@@ -1072,7 +1072,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,*/ discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file,repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,0 )) {error (_ ("Error building trees" ));
builtin/config.c +1 -1
@@ -808,7 +808,7 @@ static void location_options_init(struct config_location_options *opts, opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { opts->options.commondir =get_git_common_dir (); - opts->options.git_dir =get_git_dir (); + opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/difftool.c +2 -2
@@ -214,7 +214,7 @@ static void changed_files(struct hashmap *result, const char *index_path,struct child_process update_index =CHILD_PROCESS_INIT ;struct child_process diff_files =CHILD_PROCESS_INIT ;struct strbuf buf =STRBUF_INIT ; -const char *git_dir =absolute_path (get_git_dir ()); +const char *git_dir =absolute_path (repo_get_git_dir (the_repository));FILE *fp; strvec_pushl(&update_index.args,
@@ -737,7 +737,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree (); -setenv (GIT_DIR_ENVIRONMENT ,absolute_path (get_git_dir ()),1 ); +setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 );setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -1
@@ -1311,7 +1311,8 @@ static int fsmonitor_run_daemon(void)strbuf_addstr (&state.path_gitdir_watch,"/.git" );if (!is_directory (state.path_gitdir_watch.buf)) {strbuf_reset (&state.path_gitdir_watch); -strbuf_addstr (&state.path_gitdir_watch,absolute_path (get_git_dir ())); +strbuf_addstr (&state.path_gitdir_watch, +absolute_path (repo_get_git_dir (the_repository))); state.nr_paths_watching =2 ; }
builtin/merge.c +2 -1
@@ -855,7 +855,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)if (invoked_hook)discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository));strbuf_addbuf (&msg, &merge_msg);if (squash)BUG ("the control must not reach here under --squash" );
builtin/stash.c +1 -1
@@ -642,7 +642,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" ,absolute_path (get_git_work_tree ()));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" , -absolute_path (get_git_dir ())); +absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );run_command (&cp); }
cache-tree.c +2 -1
@@ -725,7 +725,8 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,hold_lock_file_for_update (&lock_file, index_path,LOCK_DIE_ON_ERROR ); - entries =read_index_from (index_state, index_path,get_git_dir ()); + entries =read_index_from (index_state, index_path, +repo_get_git_dir (the_repository));if (entries <0 ) { ret =WRITE_TREE_UNREADABLE_INDEX ; goto out;
config.c +3 -1
@@ -6,6 +6,8 @@* */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2212,7 +2214,7 @@ void read_early_config(config_fn_t cb, void *data)if (have_git_dir ()) { opts.commondir =get_git_common_dir (); - opts.git_dir =get_git_dir (); + opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
environment.c +2 -8
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_dir (void ) -{ -if (!the_repository->gitdir) -BUG ("git environment hasn't been setup" ); -return the_repository->gitdir; -} -const char *get_git_common_dir (void ) {if (!the_repository->commondir)
@@ -352,7 +345,8 @@ static void update_relative_gitdir(const char *name UNUSED,const char *new_cwd, void *data UNUSED) { - char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); + char *path = reparent_relative_path(old_cwd, new_cwd, +repo_get_git_dir (the_repository));struct tmp_objdir *tmp_objdir =tmp_objdir_unapply_primary_odb (); trace_printf_key(&trace_setup_key,
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_dir (void );const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );
pathspec.c +1 -1
@@ -497,7 +497,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, copyfrom); hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("%s: '%s' is outside repository at '%s'" ), elt, copyfrom,absolute_path (hint_path)); }
read-cache.c +3 -2
@@ -3238,10 +3238,11 @@ static int should_delete_shared_index(const char *shared_index_path)static int clean_shared_index_files (const char *current_hex) {struct dirent *de; -DIR *dir =opendir (get_git_dir ()); +DIR *dir =opendir (repo_get_git_dir (the_repository));if (!dir) -return error_errno (_ ("unable to open git dir: %s" ),get_git_dir ()); +return error_errno (_ ("unable to open git dir: %s" ), +repo_get_git_dir (the_repository));while ((de =readdir (dir)) !=NULL ) {const char *sha1_hex;
repository.c +7 -0
@@ -91,6 +91,13 @@ static void expand_base_dir(char **out, const char *in, *out =xstrfmt ("%s/%s" , base_dir, def_in); } +const char *repo_get_git_dir (struct repository *repo) +{ +if (!repo->gitdir) +BUG ("git environment hasn't been setup" ); +return repo->gitdir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +2 -0
@@ -206,6 +206,8 @@ struct repository {extern struct repository *the_repository;#endif +const char *repo_get_git_dir (struct repository *repo); +/* * Define a custom repository layout. Any field can be NULL, which * will default back to the path according to the default layout.
setup.c +6 -6
@@ -149,7 +149,7 @@ char *prefix_path(const char *prefix, int len, const char *path)if (!r) {const char *hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("'%s' is outside repository at '%s'" ), path,absolute_path (hint_path)); }
@@ -468,7 +468,7 @@ int is_nonbare_repository_dir(struct strbuf *path)int is_inside_git_dir (void ) {if (inside_git_dir <0 ) - inside_git_dir =is_inside_dir (get_git_dir ()); + inside_git_dir =is_inside_dir (repo_get_git_dir (the_repository));return inside_git_dir; }
@@ -1836,7 +1836,7 @@ void check_repository_format(struct repository_format *fmt)struct repository_format repo_fmt =REPOSITORY_FORMAT_INIT ;if (!fmt) fmt = &repo_fmt; -check_repository_format_gently (get_git_dir (), fmt,NULL ); +check_repository_format_gently (repo_get_git_dir (the_repository), fmt,NULL ); startup_info->have_repository =1 ;repo_set_hash_algo (the_repository, fmt->hash_algo);repo_set_compat_hash_algo (the_repository, fmt->compat_hash_algo);
@@ -2224,7 +2224,7 @@ static int create_default_files(const char *template_path,* shared-repository settings, we would need to fix them up. */ if (get_shared_repository ()) { -adjust_shared_perm (get_git_dir ()); +adjust_shared_perm (repo_get_git_dir (the_repository)); }initialize_repository_version (fmt->hash_algo, fmt->ref_storage_format,0 );
@@ -2434,12 +2434,12 @@ int init_db(const char *git_dir, const char *real_git_dir,die (_ ("%s already exists" ), real_git_dir);set_git_dir (real_git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository);separate_git_dir (git_dir, original_git_dir); }else {set_git_dir (git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository); } startup_info->have_repository =1 ;
setup.h +1 -1
@@ -176,7 +176,7 @@ 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(), +* Check the repository format version in the path found in repo_get_git_dir(the_repository), * 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?".
trace.c +3 -1
@@ -21,6 +21,8 @@* along with this program; if not, see <https://www.gnu.org/licenses/>. */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "environment.h"
@@ -311,7 +313,7 @@ void trace_repo_setup(void)if (!startup_info->prefix) prefix ="(null)" ; -trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (get_git_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ()));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));
transport-helper.c +1 -1
@@ -143,7 +143,7 @@ static struct child_process *get_helper(struct transport *transport)if (have_git_dir ())strvec_pushf (&helper->env,"%s=%s" , -GIT_DIR_ENVIRONMENT ,get_git_dir ()); +GIT_DIR_ENVIRONMENT ,repo_get_git_dir (the_repository)); helper->trace2_child_class = helper->args.v[0 ];/* "remote-<name>" */
worktree.c +2 -2
@@ -57,7 +57,7 @@ static void add_head_info(struct worktree *wt)static int is_current_worktree (struct worktree *wt) { -char *git_dir =absolute_pathdup (get_git_dir ()); +char *git_dir =absolute_pathdup (repo_get_git_dir (the_repository));const char *wt_git_dir =get_worktree_git_dir (wt);int is_current = !fspathcmp (git_dir,absolute_path (wt_git_dir));free (git_dir);
@@ -171,7 +171,7 @@ struct worktree **get_worktrees(void)const char *get_worktree_git_dir (const struct worktree *wt) {if (!wt) -return get_git_dir (); +return repo_get_git_dir (the_repository);else if (!wt->id)return get_git_common_dir ();else
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 2/21 environment: make `get_git_common_dir()` accept a repository
In reply to Patrick SteinhardtThe get_git_common_dir() function retrieves the path to the common directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/config.c | 2 +- builtin/gc.c | 2 +- builtin/rev-parse.c | 2 +- builtin/worktree.c | 4 ++-- config.c | 2 +- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + setup.c | 2 +- submodule.c | 2 +- trace.c | 2 +- worktree.c | 8 ++++---- 13 files changed, 21 insertions(+), 21 deletions(-)
builtin/config.c +1 -1
@@ -807,7 +807,7 @@ static void location_options_init(struct config_location_options *opts,else opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { - opts->options.commondir =get_git_common_dir (); + opts->options.commondir =repo_get_common_dir (the_repository); opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/gc.c +1 -1
@@ -2132,7 +2132,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priorityget_schedule_cmd (&cmd,NULL );strbuf_addf (&tfilename,"%s/schedule_%s_XXXXXX" , -get_git_common_dir (), frequency); +repo_get_common_dir (the_repository), frequency); tfile =xmks_tempfile (tfilename.buf);strbuf_release (&tfilename);
builtin/rev-parse.c +1 -1
@@ -1042,7 +1042,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--git-common-dir" )) { -print_path (get_git_common_dir (), prefix, format,DEFAULT_RELATIVE_IF_SHARED ); +print_path (repo_get_common_dir (the_repository), prefix, format,DEFAULT_RELATIVE_IF_SHARED );continue ; }if (!strcmp (arg,"--is-inside-git-dir" )) {
builtin/worktree.c +2 -2
@@ -219,7 +219,7 @@ static void prune_worktrees(void) }closedir (dir); -strbuf_add_absolute_path (&main_path,get_git_common_dir ()); +strbuf_add_absolute_path (&main_path,repo_get_common_dir (the_repository));/* massage main worktree absolute path to match 'gitdir' content */ strbuf_strip_suffix (&main_path,"/." );string_list_append_nodup (&kept,strbuf_detach (&main_path,NULL ));
@@ -492,7 +492,7 @@ static int add_worktree(const char *path, const char *refname,strbuf_addf (&sb,"%s/gitdir" , sb_repo.buf);strbuf_realpath (&realpath, sb_git.buf,1 );write_file (sb.buf,"%s" , realpath.buf); -strbuf_realpath (&realpath,get_git_common_dir (),1 ); +strbuf_realpath (&realpath,repo_get_common_dir (the_repository),1 );write_file (sb_git.buf,"gitdir: %s/worktrees/%s" , realpath.buf, name);strbuf_reset (&sb);
config.c +1 -1
@@ -2213,7 +2213,7 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ;if (have_git_dir ()) { - opts.commondir =get_git_common_dir (); + opts.commondir =repo_get_common_dir (the_repository); opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the
environment.c +0 -7
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_common_dir (void ) -{ -if (!the_repository->commondir) -BUG ("git environment hasn't been setup" ); -return the_repository->commondir; -} -const char *get_git_namespace (void ) {if (!git_namespace)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);
repository.c +7 -0
@@ -98,6 +98,13 @@ const char *repo_get_git_dir(struct repository *repo)return repo->gitdir; } +const char *repo_get_common_dir (struct repository *repo) +{ +if (!repo->commondir) +BUG ("git environment hasn't been setup" ); +return repo->commondir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -207,6 +207,7 @@ extern struct repository *the_repository;#endif const char *repo_get_git_dir (struct repository *repo); +const char *repo_get_common_dir (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +1 -1
@@ -2068,7 +2068,7 @@ static void copy_templates(const char *option_template) goto close_free_return; } -strbuf_addstr (&path,get_git_common_dir ()); +strbuf_addstr (&path,repo_get_common_dir (the_repository));strbuf_complete (&path,'/' );copy_templates_1 (&path, &template_path, dir); close_free_return:
submodule.c +1 -1
@@ -2462,7 +2462,7 @@ void absorb_git_dir_into_superproject(const char *path, }else {/* Is it already absorbed into the superprojects git dir? */ char *real_sub_git_dir =real_pathdup (sub_git_dir,1 ); -char *real_common_git_dir =real_pathdup (get_git_common_dir (),1 ); +char *real_common_git_dir =real_pathdup (repo_get_common_dir (the_repository),1 );if (!starts_with (real_sub_git_dir, real_common_git_dir))relocate_single_git_dir_into_superproject (path, super_prefix);
trace.c +1 -1
@@ -314,7 +314,7 @@ void trace_repo_setup(void) prefix ="(null)" ;trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository))); -trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (repo_get_common_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));trace_printf_key (&trace_setup_key,"setup: prefix: %s\n" ,quote_crnl (prefix));
worktree.c +4 -4
@@ -72,7 +72,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)struct worktree *worktree =NULL ;struct strbuf worktree_path =STRBUF_INIT ; -strbuf_add_real_path (&worktree_path,get_git_common_dir ()); +strbuf_add_real_path (&worktree_path,repo_get_common_dir (the_repository));strbuf_strip_suffix (&worktree_path,"/.git" );CALLOC_ARRAY (worktree,1 );
@@ -143,7 +143,7 @@ static struct worktree **get_worktrees_internal(int skip_reading_head) list[counter++] =get_main_worktree (skip_reading_head); -strbuf_addf (&path,"%s/worktrees" ,get_git_common_dir ()); +strbuf_addf (&path,"%s/worktrees" ,repo_get_common_dir (the_repository)); dir =opendir (path.buf);strbuf_release (&path);if (dir) {
@@ -173,7 +173,7 @@ const char *get_worktree_git_dir(const struct worktree *wt)if (!wt)return repo_get_git_dir (the_repository);else if (!wt->id) -return get_git_common_dir (); +return repo_get_common_dir (the_repository);else return git_common_path ("worktrees/%s" , wt->id); }
@@ -626,7 +626,7 @@ static int is_main_worktree_path(const char *path)strbuf_add_real_path (&target, path);strbuf_strip_suffix (&target,"/.git" ); -strbuf_add_real_path (&maindir,get_git_common_dir ()); +strbuf_add_real_path (&maindir,repo_get_common_dir (the_repository));strbuf_strip_suffix (&maindir,"/.git" ); cmp =fspathcmp (maindir.buf, target.buf);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 3/21 environment: make `get_object_directory()` accept a repository
In reply to Patrick SteinhardtThe get_object_directory() function retrieves the path to the object directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/commit-graph.c | 4 ++-- builtin/count-objects.c | 2 +- builtin/multi-pack-index.c | 2 +- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 ++++---- builtin/repack.c | 7 ++++--- bulk-checkin.c | 4 ++-- environment.c | 7 ------- environment.h | 1 - fetch-pack.c | 2 +- http-backend.c | 2 +- object-file.c | 4 ++-- pack-write.c | 2 +- packfile.c | 2 +- prune-packed.c | 4 +++- repository.c | 7 +++++++ repository.h | 1 + server-info.c | 3 ++- setup.c | 2 +- tmp-objdir.c | 7 ++++--- 20 files changed, 39 insertions(+), 34 deletions(-)
builtin/commit-graph.c +2 -2
@@ -95,7 +95,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)usage_with_options (builtin_commit_graph_verify_usage, options);if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.shallow) flags |=COMMIT_GRAPH_VERIFY_SHALLOW ;if (opts.progress)
@@ -275,7 +275,7 @@ static int graph_write(int argc, const char **argv, const char *prefix)if (opts.reachable + opts.stdin_packs + opts.stdin_commits >1 )die (_ ("use at most one of --reachable, --stdin-commits, or --stdin-packs" ));if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.append) flags |=COMMIT_GRAPH_WRITE_APPEND ;if (opts.split)
builtin/count-objects.c +1 -1
@@ -116,7 +116,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)report_linked_checkout_garbage (the_repository); } -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), count_loose, count_cruft,NULL ,NULL );if (verbose) {
builtin/multi-pack-index.c +1 -1
@@ -63,7 +63,7 @@ static int parse_object_dir(const struct option *opt, const char *arg,char **value = opt->value;free (*value);if (unset) - *value =xstrdup (get_object_directory ()); + *value =xstrdup (repo_get_object_directory (the_repository));else *value =real_pathdup (arg,1 );return 0 ;
builtin/pack-objects.c +1 -1
@@ -3940,7 +3940,7 @@ static int add_loose_object(const struct object_id *oid, const char *path,*/ static void add_unreachable_loose_objects (void ) { -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), add_loose_object,NULL ,NULL ,NULL ); }
builtin/prune.c +4 -4
@@ -193,12 +193,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix) revs.exclude_promisor_objects =1 ; } -for_each_loose_file_in_objdir (get_object_directory (), prune_object, - prune_cruft, prune_subdir, &revs); +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), + prune_object, prune_cruft, prune_subdir, &revs);prune_packed_objects (show_only ?PRUNE_PACKED_DRY_RUN :0 ); -remove_temporary_files (get_object_directory ()); - s =mkpathdup ("%s/pack" ,get_object_directory ()); +remove_temporary_files (repo_get_object_directory (the_repository)); + s =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository));remove_temporary_files (s);free (s);
builtin/repack.c +4 -3
@@ -1240,7 +1240,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)if (write_midx && write_bitmaps) {struct strbuf path =STRBUF_INIT ; -strbuf_addf (&path,"%s/%s_XXXXXX" ,get_object_directory (), +strbuf_addf (&path,"%s/%s_XXXXXX" ,repo_get_object_directory (the_repository),"bitmap-ref-tips" ); refs_snapshot =xmks_tempfile (path.buf);
@@ -1249,7 +1249,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)strbuf_release (&path); } - packdir =mkpathdup ("%s/pack" ,get_object_directory ()); + packdir =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository)); packtmp_name =xstrfmt (".tmp-%d-pack" , (int )getpid ()); packtmp =mkpathdup ("%s/%s" , packdir, packtmp_name);
@@ -1519,7 +1519,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)unsigned flags =0 ;if (git_env_bool (GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL ,0 )) flags |=MIDX_WRITE_INCREMENTAL ; -write_midx_file (get_object_directory (),NULL ,NULL , flags); +write_midx_file (repo_get_object_directory (the_repository), +NULL ,NULL , flags); } cleanup:
bulk-checkin.c +2 -2
@@ -75,7 +75,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)close (fd); } -strbuf_addf (&packname,"%s/pack/pack-%s." ,get_object_directory (), +strbuf_addf (&packname,"%s/pack/pack-%s." ,repo_get_object_directory (the_repository),hash_to_hex (hash)); finish_tmp_packfile(&packname, state->pack_tmp_name, state->written, state->nr_written,
@@ -113,7 +113,7 @@ static void flush_batch_fsync(void)* to ensure that the data in each new object file is durable before * the final name is visible. */ -strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,get_object_directory ()); +strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,repo_get_object_directory (the_repository)); temp =xmks_tempfile (temp_path.buf);fsync_or_die (get_tempfile_fd (temp),get_tempfile_path (temp));delete_tempfile (&temp);
environment.c +0 -7
@@ -273,13 +273,6 @@ const char *get_git_work_tree(void)return the_repository->worktree; } -const char *get_object_directory (void ) -{ -if (!the_repository->objects->odb) -BUG ("git environment hasn't been setup" ); -return the_repository->objects->odb->path; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);
fetch-pack.c +1 -1
@@ -1839,7 +1839,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,string_list_append_nodup (pack_lockfiles,xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), +repo_get_object_directory (the_repository), packname)); }string_list_clear (&packfile_uris,0 );
http-backend.c +1 -1
@@ -601,7 +601,7 @@ static void get_head(struct strbuf *hdr, char *arg UNUSED) static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { -size_t objdirlen =strlen (get_object_directory ()); +size_t objdirlen =strlen (repo_get_object_directory (the_repository));struct strbuf buf =STRBUF_INIT ;struct packed_git *p;size_t cnt =0 ;
object-file.c +2 -2
@@ -2053,7 +2053,7 @@ static int start_loose_object_common(struct strbuf *tmp_file,else if (errno ==EACCES )return error (_ ("insufficient permission for adding " "an object to repository database %s" ), -get_object_directory ()); +repo_get_object_directory (the_repository));else return error_errno (_ ("unable to create temporary file" ));
@@ -2228,7 +2228,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,prepare_loose_object_bulk_checkin ();/* Since oid is not determined, save tmp file to odb path. */ -strbuf_addf (&filename,"%s/" ,get_object_directory ()); +strbuf_addf (&filename,"%s/" ,repo_get_object_directory (the_repository)); hdrlen =format_object_header (hdr,sizeof (hdr),OBJ_BLOB , len);/*
pack-write.c +1 -1
@@ -473,7 +473,7 @@ char *index_pack_lockfile(int ip_out, int *is_well_formed) packname[len-1 ] =0 ;if (skip_prefix (packname,"keep\t" , &name))return xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), name); +repo_get_object_directory (the_repository), name);return NULL ; }if (is_well_formed)
packfile.c +1 -1
@@ -30,7 +30,7 @@ char *odb_pack_name(struct strbuf *buf, const char *ext) {strbuf_reset (buf); -strbuf_addf (buf,"%s/pack/pack-%s.%s" ,get_object_directory (), +strbuf_addf (buf,"%s/pack/pack-%s.%s" ,repo_get_object_directory (the_repository),hash_to_hex (hash), ext);return buf->buf; }
prune-packed.c +3 -1
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "gettext.h"
@@ -37,7 +39,7 @@ void prune_packed_objects(int opts)if (opts &PRUNE_PACKED_VERBOSE ) progress =start_delayed_progress (_ ("Removing duplicate objects" ),256 ); -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), prune_object,NULL , prune_subdir, &opts);/* Ensure we show 100% before finishing progress */
repository.c +7 -0
@@ -105,6 +105,13 @@ const char *repo_get_common_dir(struct repository *repo)return repo->commondir; } +const char *repo_get_object_directory (struct repository *repo) +{ +if (!repo->objects->odb) +BUG ("git environment hasn't been setup" ); +return repo->objects->odb->path; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -208,6 +208,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo); +const char *repo_get_object_directory (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
server-info.c +2 -1
@@ -342,7 +342,8 @@ static int write_pack_info_file(struct update_info_ctx *uic)static int update_info_packs (int force) { -char *infofile =mkpathdup ("%s/info/packs" ,get_object_directory ()); +char *infofile =mkpathdup ("%s/info/packs" , +repo_get_object_directory (the_repository));int ret;init_pack_info (infofile, force);
setup.c +1 -1
@@ -2282,7 +2282,7 @@ static void create_object_directory(void)struct strbuf path =STRBUF_INIT ;size_t baselen; -strbuf_addstr (&path,get_object_directory ()); +strbuf_addstr (&path,repo_get_object_directory (the_repository)); baselen = path.len;safe_create_dir (path.buf,1 );
tmp-objdir.c +4 -3
@@ -132,7 +132,8 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix)* can recognize any stale objdirs left behind by a crash and delete * them. */ -strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" ,get_object_directory (), prefix); +strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" , +repo_get_object_directory (the_repository), prefix);if (!mkdtemp (t->path.buf)) {/* free, not destroy, as we never touched the filesystem */
@@ -152,7 +153,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) }env_append (&t->env,ALTERNATE_DB_ENVIRONMENT , -absolute_path (get_object_directory ())); +absolute_path (repo_get_object_directory (the_repository)));env_replace (&t->env,DB_ENVIRONMENT ,absolute_path (t->path.buf));env_replace (&t->env,GIT_QUARANTINE_ENVIRONMENT ,absolute_path (t->path.buf));
@@ -267,7 +268,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t) }strbuf_addbuf (&src, &t->path); -strbuf_addstr (&dst,get_object_directory ()); +strbuf_addstr (&dst,repo_get_object_directory (the_repository)); ret =migrate_paths (&src, &dst);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 4/21 environment: make `get_index_file()` accept a repository
In reply to Patrick SteinhardtThe get_index_file() function retrieves the path to the index file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/am.c | 8 ++++++-- builtin/commit.c | 6 +++--- builtin/merge.c | 14 ++++++++------ builtin/stash.c | 12 ++++++------ builtin/update-index.c | 2 +- builtin/write-tree.c | 3 ++- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + wt-status.c | 2 +- 11 files changed, 35 insertions(+), 28 deletions(-)
builtin/am.c +6 -2
@@ -1668,7 +1668,9 @@ static void do_commit(const struct am_state *state)if (!state->no_verify &&run_hooks (the_repository,"pre-applypatch" ))exit (1 ); -if (write_index_as_tree (&tree, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&tree, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" ));if (!repo_get_oid_commit (the_repository,"HEAD" , &parent)) {
@@ -2078,7 +2080,9 @@ static int clean_index(const struct object_id *head, const struct object_id *remif (fast_forward_to (head_tree, head_tree,1 ))return -1 ; -if (write_index_as_tree (&index, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&index, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))return -1 ; index_tree =parse_tree_indirect (&index);
builtin/commit.c +3 -3
@@ -472,7 +472,7 @@ static const char *prepare_index(const char **argv, const char *prefix, COMMIT_LOCK | SKIP_IF_UNCHANGED))die (_ ("unable to write new index file" )); commit_style =COMMIT_AS_IS ; - ret =get_index_file (); + ret =repo_get_index_file (the_repository); goto out; }
@@ -1873,8 +1873,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)repo_rerere (the_repository,0 );run_auto_maintenance (quiet); -run_commit_hook (use_editor,get_index_file (),NULL ,"post-commit" , -NULL ); +run_commit_hook (use_editor,repo_get_index_file (the_repository), +NULL ,"post-commit" ,NULL );if (amend && !no_post_rewrite) {commit_post_rewrite (the_repository, current_head, &oid); }
builtin/merge.c +8 -6
@@ -695,7 +695,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,static void write_tree_trivial (struct object_id *oid) { -if (write_index_as_tree (oid, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (oid, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" )); }
@@ -757,7 +759,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, }if (write_locked_index (the_repository->index, &lock,COMMIT_LOCK |SKIP_IF_UNCHANGED )) -die (_ ("unable to write %s" ),get_index_file ()); +die (_ ("unable to write %s" ),repo_get_index_file (the_repository));return clean ?0 :1 ; }else { return try_merge_command(the_repository,
@@ -839,7 +841,7 @@ static void write_merge_heads(struct commit_list *);static void prepare_to_commit (struct commit_list *remoteheads) {struct strbuf msg =STRBUF_INIT ; -const char *index_file =get_index_file (); +const char *index_file =repo_get_index_file (the_repository);if (!no_verify) {int invoked_hook;
@@ -879,8 +881,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)append_signoff (&msg,ignored_log_message_bytes (msg.buf, msg.len),0 );write_merge_heads (remoteheads);write_file_buf (git_path_merge_msg (the_repository), msg.buf, msg.len); -if (run_commit_hook (0 < option_edit,get_index_file (),NULL , -"prepare-commit-msg" , +if (run_commit_hook (0 < option_edit,repo_get_index_file (the_repository), +NULL ,"prepare-commit-msg" ,git_path_merge_msg (the_repository),"merge" ,NULL ))abort_commit (remoteheads,NULL );if (0 < option_edit) {
@@ -888,7 +890,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)abort_commit (remoteheads,NULL ); } -if (!no_verify &&run_commit_hook (0 < option_edit,get_index_file (), +if (!no_verify &&run_commit_hook (0 < option_edit,repo_get_index_file (the_repository),NULL ,"commit-msg" ,git_path_merge_msg (the_repository),NULL ))abort_commit (remoteheads,NULL );
builtin/stash.c +6 -6
@@ -539,8 +539,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, NULL, NULL, NULL))return error (_ ("could not write index" )); -if (write_index_as_tree (&c_tree, the_repository->index,get_index_file (),0 , -NULL )) +if (write_index_as_tree (&c_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("cannot apply a stash in the middle of a merge" ));if (index) {
@@ -565,7 +565,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,discard_index (the_repository->index);repo_read_index (the_repository);if (write_index_as_tree (&index_tree, the_repository->index, -get_index_file (),0 ,NULL )) +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("could not save index tree" ));reset_head ();
@@ -1405,8 +1405,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_bstrbuf_addf (&commit_tree_label,"index on %s\n" , msg.buf);commit_list_insert (head_commit, &parents); -if (write_index_as_tree (&info->i_tree, the_repository->index,get_index_file (),0 , -NULL ) || +if (write_index_as_tree (&info->i_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ) ||commit_tree (commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit,NULL ,NULL )) {if (!quiet)
@@ -1904,7 +1904,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - index_file =get_index_file (); + index_file =repo_get_index_file (the_repository);strbuf_addf (&stash_index_path,"%s.stash.%" PRIuMAX, index_file, (uintmax_t )pid);
builtin/update-index.c +1 -1
@@ -1239,7 +1239,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)if (newfd <0 ) {if (refresh_args.flags &REFRESH_QUIET )exit (128 ); -unable_to_lock_die (get_index_file (), lock_error); +unable_to_lock_die (repo_get_index_file (the_repository), lock_error); }if (write_locked_index (the_repository->index, &lock_file,COMMIT_LOCK ))die ("Unable to write new index file" );
builtin/write-tree.c +2 -1
@@ -44,7 +44,8 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - ret =write_index_as_tree (&oid, the_repository->index,get_index_file (), + ret =write_index_as_tree (&oid, the_repository->index, +repo_get_index_file (the_repository), flags, tree_prefix);switch (ret) {case 0 :
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_index_file (void ) -{ -if (!the_repository->index_file) -BUG ("git environment hasn't been setup" ); -return the_repository->index_file; -} -char *get_graft_file (struct repository *r) {if (!r->graft_file)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );
repository.c +7 -0
@@ -112,6 +112,13 @@ const char *repo_get_object_directory(struct repository *repo)return repo->objects->odb->path; } +const char *repo_get_index_file (struct repository *repo) +{ +if (!repo->index_file) +BUG ("git environment hasn't been setup" ); +return repo->index_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -209,6 +209,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo); +const char *repo_get_index_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
wt-status.c +1 -1
@@ -152,7 +152,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) "HEAD", 0, NULL, NULL); s->reference ="HEAD" ; s->fp = stdout; - s->index_file =get_index_file (); + s->index_file =repo_get_index_file (the_repository); s->change.strdup_strings =1 ; s->untracked.strdup_strings =1 ; s->ignored.strdup_strings =1 ;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 5/21 environment: make `get_graft_file()` accept a repository
In reply to Patrick SteinhardtThe get_graft_file() function retrieves the path to the graft file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/replace.c | 2 +- commit.c | 4 ++-- environment.c | 7 ------- environment.h | 2 -- repository.c | 7 +++++++ repository.h | 1 + 6 files changed, 11 insertions(+), 12 deletions(-)
builtin/replace.c +1 -1
@@ -514,7 +514,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)static int convert_graft_file (int force) { -const char *graft_file =get_graft_file (the_repository); +const char *graft_file =repo_get_graft_file (the_repository);FILE *fp =fopen_or_warn (graft_file,"r" );struct strbuf buf =STRBUF_INIT , err =STRBUF_INIT ;struct strvec args =STRVEC_INIT ;
commit.c +2 -2
@@ -292,14 +292,14 @@ static int read_graft_file(struct repository *r, const char *graft_file)void prepare_commit_graft (struct repository *r) { -char *graft_file; +const char *graft_file;if (r->parsed_objects->commit_graft_prepared)return ;if (!startup_info->have_repository)return ; - graft_file =get_graft_file (r); + graft_file =repo_get_graft_file (r);read_graft_file (r, graft_file);/* make sure shallows are read */ is_repository_shallow (r);
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_graft_file (struct repository *r) -{ -if (!r->graft_file) -BUG ("git environment hasn't been setup" ); -return r->graft_file; -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -2
@@ -1,7 +1,6 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct repository ;struct strvec ;/*
@@ -106,7 +105,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref);
repository.c +7 -0
@@ -119,6 +119,13 @@ const char *repo_get_index_file(struct repository *repo)return repo->index_file; } +const char *repo_get_graft_file (struct repository *repo) +{ +if (!repo->graft_file) +BUG ("git environment hasn't been setup" ); +return repo->graft_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -210,6 +210,7 @@ const char *repo_get_git_dir(struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo); +const char *repo_get_graft_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 6/21 environment: make `get_git_work_tree()` accept a repository
In reply to Patrick SteinhardtThe get_git_work_tree() function retrieves the path of the work tree of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/blame.c | 2 +- builtin/difftool.c | 4 ++-- builtin/fsmonitor--daemon.c | 3 ++- builtin/init-db.c | 4 ++-- builtin/reset.c | 4 ++-- builtin/rev-parse.c | 4 ++-- builtin/stash.c | 2 +- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 2 +- dir.c | 2 +- environment.c | 7 +------ environment.h | 1 - fsmonitor.c | 2 +- pathspec.c | 2 +- repository.c | 5 +++++ repository.h | 1 + setup.c | 16 ++++++++-------- trace.c | 2 +- 18 files changed, 33 insertions(+), 32 deletions(-)
builtin/blame.c +1 -1
@@ -1081,7 +1081,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) path =add_prefix (prefix, argv[1 ]); argv[1 ] = argv[2 ]; }else {/* (2a) */ -if (argc ==2 &&is_a_rev (argv[1 ]) && !get_git_work_tree ()) +if (argc ==2 &&is_a_rev (argv[1 ]) && !repo_get_work_tree (the_repository))die ("missing <path> to blame" ); path =add_prefix (prefix, argv[argc -1 ]); }
builtin/difftool.c +2 -2
@@ -377,7 +377,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,struct hashmap wt_modified, tmp_modified;int indices_loaded =0 ; - workdir =get_git_work_tree (); + workdir =repo_get_work_tree (the_repository);/* Setup temp directories */ tmp =getenv ("TMPDIR" );
@@ -738,7 +738,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree ();setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 ); -setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); +setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (repo_get_work_tree (the_repository)),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -1
@@ -1291,7 +1291,8 @@ static int fsmonitor_run_daemon(void)/* Prepare to (recursively) watch the <worktree-root> directory. */ strbuf_init (&state.path_worktree_watch,0 ); -strbuf_addstr (&state.path_worktree_watch,absolute_path (get_git_work_tree ())); +strbuf_addstr (&state.path_worktree_watch, +absolute_path (repo_get_work_tree (the_repository))); state.nr_paths_watching =1 ;strbuf_init (&state.alias.alias,0 );
builtin/init-db.c +2 -2
@@ -231,9 +231,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)set_git_work_tree (work_tree); elseset_git_work_tree (git_work_tree_cfg ); -if (access (get_git_work_tree (),X_OK )) +if (access (repo_get_work_tree (the_repository),X_OK ))die_errno (_ ("Cannot access work tree '%s'" ), -get_git_work_tree ()); +repo_get_work_tree (the_repository)); }else {if (real_git_dir)
builtin/reset.c +2 -2
@@ -441,7 +441,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)else trace2_cmd_mode (reset_type_names[reset_type]); -if (reset_type !=SOFT && (reset_type !=MIXED ||get_git_work_tree ())) +if (reset_type !=SOFT && (reset_type !=MIXED ||repo_get_work_tree (the_repository)))setup_work_tree ();if (reset_type ==MIXED &&is_bare_repository ())
@@ -474,7 +474,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) goto cleanup; } the_repository->index->updated_skipworktree =1 ; -if (!no_refresh &&get_git_work_tree ()) { +if (!no_refresh &&repo_get_work_tree (the_repository)) {uint64_t t_begin, t_delta_in_ms; t_begin =getnanotime ();
builtin/rev-parse.c +2 -2
@@ -966,7 +966,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--show-toplevel" )) { -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);if (work_tree)print_path (work_tree, prefix, format,DEFAULT_UNMODIFIED );else
@@ -991,7 +991,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)const char *pfx = prefix;if (!is_inside_work_tree ()) {const char *work_tree = -get_git_work_tree (); +repo_get_work_tree (the_repository);if (work_tree)printf ("%s\n" , work_tree);continue ;
builtin/stash.c +1 -1
@@ -640,7 +640,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, cp.git_cmd =1 ; cp.dir = prefix;strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" , -absolute_path (get_git_work_tree ())); +absolute_path (repo_get_work_tree (the_repository)));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" ,absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );
builtin/submodule--helper.c +1 -1
@@ -1709,7 +1709,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,exit (128 );if (!is_absolute_path (clone_data->path)) - clone_data_path = to_free =xstrfmt ("%s/%s" ,get_git_work_tree (), + clone_data_path = to_free =xstrfmt ("%s/%s" ,repo_get_work_tree (the_repository), clone_data->path);if (validate_submodule_git_dir (sm_gitdir, clone_data->name) <0 )
builtin/update-index.c +1 -1
@@ -1194,7 +1194,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)"remove or change it, if you really want to " "enable the untracked cache"));add_untracked_cache (the_repository->index); -report (_ ("Untracked cache enabled for '%s'" ),get_git_work_tree ()); +report (_ ("Untracked cache enabled for '%s'" ),repo_get_work_tree (the_repository));break ;default :BUG ("bad untracked_cache value: %d" , untracked_cache);
dir.c +1 -1
@@ -2838,7 +2838,7 @@ static const char *get_ident_string(void)return sb.buf;if (uname (&uts) <0 )die_errno (_ ("failed to get kernel name and information" )); -strbuf_addf (&sb,"Location %s, system %s" ,get_git_work_tree (), +strbuf_addf (&sb,"Location %s, system %s" ,repo_get_work_tree (the_repository), uts.sysname);return sb.buf; }
environment.c +1 -6
@@ -219,7 +219,7 @@ void setup_git_env(const char *git_dir)int is_bare_repository (void ) {/* if core.bare is not 'false', let's see if there is a work tree */ -return is_bare_repository_cfg && !get_git_work_tree (); +return is_bare_repository_cfg && !repo_get_work_tree (the_repository); }int have_git_dir (void )
@@ -268,11 +268,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -const char *get_git_work_tree (void ) -{ -return the_repository->worktree; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -108,7 +108,6 @@ extern char *git_work_tree_cfg;void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); -const char *get_git_work_tree (void );void set_git_work_tree (const char *tree);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
fsmonitor.c +1 -1
@@ -169,7 +169,7 @@ static int query_fsmonitor_hook(struct repository *r,strvec_pushf (&cp.args,"%d" , version);strvec_pushf (&cp.args,"%s" , last_update); cp.use_shell =1 ; - cp.dir =get_git_work_tree (); + cp.dir =repo_get_work_tree (the_repository);trace2_region_enter ("fsm_hook" ,"query" ,NULL );
pathspec.c +1 -1
@@ -495,7 +495,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,if (!have_git_dir ())die (_ ("'%s' is outside the directory tree" ), copyfrom); - hint_path =get_git_work_tree (); + hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("%s: '%s' is outside repository at '%s'"), elt,
repository.c +5 -0
@@ -126,6 +126,11 @@ const char *repo_get_graft_file(struct repository *repo)return repo->graft_file; } +const char *repo_get_work_tree (struct repository *repo) +{ +return repo->worktree; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -211,6 +211,7 @@ const char *repo_get_common_dir(struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo);const char *repo_get_graft_file (struct repository *repo); +const char *repo_get_work_tree (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +8 -8
@@ -51,7 +51,7 @@ static int abspath_part_inside_repo(char *path)size_t wtlen;char *path0;int off; -const char *work_tree =precompose_string_if_needed (get_git_work_tree ()); +const char *work_tree =precompose_string_if_needed (repo_get_work_tree (the_repository));struct strbuf realpath =STRBUF_INIT ;if (!work_tree)
@@ -147,7 +147,7 @@ char *prefix_path(const char *prefix, int len, const char *path) {char *r =prefix_path_gently (prefix, len,NULL , path);if (!r) { -const char *hint_path =get_git_work_tree (); +const char *hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("'%s' is outside repository at '%s'"), path,
@@ -475,7 +475,7 @@ int is_inside_git_dir(void)int is_inside_work_tree (void ) {if (inside_work_tree <0 ) - inside_work_tree =is_inside_dir (get_git_work_tree ()); + inside_work_tree =is_inside_dir (repo_get_work_tree (the_repository));return inside_work_tree; }
@@ -490,7 +490,7 @@ void setup_work_tree(void)if (work_tree_config_is_bogus)die (_ ("unable to set up work tree using invalid config" )); - work_tree =get_git_work_tree (); + work_tree =repo_get_work_tree (the_repository);if (!work_tree ||chdir_notify (work_tree))die (_ ("this operation must be run in a work tree" ));
@@ -547,7 +547,7 @@ static void setup_original_cwd(void)* Get our worktree; we only protect the current working directory * if it's in the worktree. */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository);if (!worktree) goto no_prevention_needed;
@@ -1062,9 +1062,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,set_git_work_tree ("." );/* set_git_work_tree() must have been called by now */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository); -/* both get_git_work_tree() and cwd are already normalized */ +/* both repo_get_work_tree() and cwd are already normalized */ if (!strcmp (cwd->buf, worktree)) {/* cwd == worktree */ set_git_dir (gitdirenv,0 );free (gitfile);
@@ -2192,7 +2192,7 @@ static int create_default_files(const char *template_path,char *path;int reinit;int filemode; -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);/* * First copy the templates -- we might have the default
trace.c +1 -1
@@ -307,7 +307,7 @@ void trace_repo_setup(void) cwd =xgetcwd (); -if (!(git_work_tree =get_git_work_tree ())) +if (!(git_work_tree =repo_get_work_tree (the_repository))) git_work_tree ="(null)" ;if (!startup_info->prefix)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 7/21 config: document `read_early_config()` and `read_very_early_config()`
In reply to Patrick SteinhardtIt's not clear what read_early_config() and read_very_early_config() do differently compared to repo_read_config() from just looking at their names. Document both of these in the header file to clarify their intent.
--- config.c | 4 ---- config.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-)
config.c +0 -4
@@ -2234,10 +2234,6 @@ void read_early_config(config_fn_t cb, void *data)strbuf_release (&gitdir); } -/* -* Read config but only enumerate system and global settings. -* Omit any repo-local, worktree-local, or command-line settings. -*/ void read_very_early_config (config_fn_t cb,void *data) {struct config_options opts = {0 };
config.h +11 -0
@@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name,void git_config_push_parameter (const char *text);void git_config_push_env (const char *spec);int git_config_from_parameters (config_fn_t fn,void *data); + +/* +* Read config when the Git directory has not yet been set up. In case +* `the_repository` has not yet been set up, try to discover the Git +* directory to read the configuration from. +*/ void read_early_config (config_fn_t cb,void *data); + +/* +* Read config but only enumerate system and global settings. +* Omit any repo-local, worktree-local, or command-line settings. +*/ void read_very_early_config (config_fn_t cb,void *data);/**
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 8/21 config: make dependency on repo in `read_early_config()` explicit
In reply to Patrick SteinhardtThe read_early_config() function can be used to read configuration where a repository has not yet been set up. As such, it is optional whether or not the_repository has already been initialized. If it was initialized we use its commondir and gitdir. If not, the function will try to detect the Git directories by itself and, if found, also parse their config files.
This means that we implicitly rely on the_repository. Make this dependency explicit by passing a struct repository. This allows us to again drop the USE_THE_REPOSITORY_VARIABLE define in "config.c".
--- alias.c | 6 ++++-- config.c | 10 ++++------ config.h | 2 +- help.c | 2 +- pager.c | 7 +++++-- t/helper/test-config.c | 3 ++- trace2/tr2_cfg.c | 4 +++- 7 files changed, 20 insertions(+), 14 deletions(-)
alias.c +4 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "alias.h" #include "config.h"
@@ -37,7 +39,7 @@ char *alias_lookup(const char *alias) {struct config_alias_data data = { alias,NULL }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data);return data.v; }
@@ -46,7 +48,7 @@ void list_aliases(struct string_list *list) {struct config_alias_data data = {NULL ,NULL , list }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data); }void quote_cmdline (struct strbuf *buf,const char **argv)
config.c +4 -6
@@ -6,8 +6,6 @@* */ -#define USE_THE_REPOSITORY_VARIABLE -#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2204,7 +2202,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config (config_fn_t cb,void *data) +void read_early_config (struct repository *repo,config_fn_t cb,void *data) {struct config_options opts = {0 };struct strbuf commondir =STRBUF_INIT ;
@@ -2212,9 +2210,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ; -if (have_git_dir ()) { - opts.commondir =repo_get_common_dir (the_repository); - opts.git_dir =repo_get_git_dir (the_repository); +if (repo && repo->gitdir) { + opts.commondir =repo_get_common_dir (repo); + opts.git_dir =repo_get_git_dir (repo);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
config.h +1 -1
@@ -198,7 +198,7 @@ int git_config_from_parameters(config_fn_t fn, void *data);* `the_repository` has not yet been set up, try to discover the Git * directory to read the configuration from. */ -void read_early_config (config_fn_t cb,void *data); +void read_early_config (struct repository *repo,config_fn_t cb,void *data);/* * Read config but only enumerate system and global settings.
help.c +1 -1
@@ -618,7 +618,7 @@ const char *help_unknown_cmd(const char *cmd)memset (&other_cmds,0 ,sizeof (other_cmds));memset (&aliases,0 ,sizeof (aliases)); -read_early_config (git_unknown_cmd_config,NULL ); +read_early_config (the_repository, git_unknown_cmd_config,NULL );/* * Disable autocorrection prompt in a non-interactive session
pager.c +5 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "editor.h"
@@ -92,7 +94,8 @@ const char *git_pager(int stdout_is_tty) pager =getenv ("GIT_PAGER" );if (!pager) {if (!pager_program) -read_early_config (core_pager_config,NULL ); +read_early_config (the_repository, + core_pager_config,NULL ); pager = pager_program; }if (!pager)
@@ -298,7 +301,7 @@ int check_pager_config(const char *cmd) data.want =-1 ; data.value =NULL ; -read_early_config (pager_command_config, &data); +read_early_config (the_repository, pager_command_config, &data);if (data.value) pager_program = data.value;
t/helper/test-config.c +2 -1
@@ -96,7 +96,8 @@ int cmd__config(int argc, const char **argv)struct config_set cs;if (argc ==3 && !strcmp (argv[1 ],"read_early_config" )) { -read_early_config (early_config_cb, (void *)argv[2 ]); +read_early_config (the_repository, early_config_cb, + (void *)argv[2 ]);return 0 ; }
trace2/tr2_cfg.c +3 -1
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "strbuf.h"
@@ -124,7 +126,7 @@ void tr2_cfg_list_config_fl(const char *file, int line)struct tr2_cfg_data data = { file, line };if (tr2_cfg_load_patterns () >0 ) -read_early_config (tr2_cfg_cb, &data); +read_early_config (the_repository, tr2_cfg_cb, &data); }void tr2_list_env_vars_fl (const char *file,int line)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 9/21 environment: move `odb_mkstemp()` into object layer
In reply to Patrick SteinhardtThe odb_mkstemp() function is quite clearly tied to the object store, but regardless of that it is located in "environment.c". Move it over, which also helps to get rid of dependencies on the_repository in the environment subsystem.
--- bundle-uri.c | 1 + environment.c | 34 ---------------------------------- environment.h | 15 --------------- object-file.c | 33 +++++++++++++++++++++++++++++++++ object-store-ll.h | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 49 deletions(-)
bundle-uri.c +1 -0
@@ -13,6 +13,7 @@#include "config.h" #include "fetch-pack.h" #include "remote.h" +#include "object-store-ll.h" static struct { enum bundle_list_heuristic heuristic;
environment.c +0 -34
@@ -23,7 +23,6 @@#include "commit.h" #include "strvec.h" #include "object-file.h" -#include "object-store-ll.h" #include "path.h" #include "replace-object.h" #include "tmp-objdir.h"
@@ -268,39 +267,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) -{ -int fd; -/* -* we let the umask do its job, don't try to be more -* restrictive except to remove write permission. -*/ -int mode =0444 ; -git_path_buf (temp_filename,"objects/%s" , pattern); - fd =git_mkstemp_mode (temp_filename->buf, mode); -if (0 <= fd) -return fd; - -/* slow path */ -/* some mkstemp implementations erase temp_filename on failure */ -git_path_buf (temp_filename,"objects/%s" , pattern); -safe_create_leading_directories (temp_filename->buf); -return xmkstemp_mode (temp_filename->buf, mode); -} - -int odb_pack_keep (const char *name) -{ -int fd; - - fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -if (0 <= fd) -return fd; - -/* slow path */ -safe_create_leading_directories_const (name); -return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -15
@@ -200,21 +200,6 @@ extern int grafts_keep_true_parents;extern int repository_format_precious_objects; -/* -* Create a temporary file rooted in the object database directory, or -* die on failure. The filename is taken from "pattern", which should have the -* usual "XXXXXX" trailer, and the resulting filename is written into the -* "template" buffer. Returns the open descriptor. -*/ -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); - -/* -* Create a pack .keep file named "name" (which should generally be the output -* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on -* error. -*/ -int odb_pack_keep (const char *name); -const char *get_log_output_encoding (void );const char *get_commit_output_encoding (void );
object-file.c +33 -0
@@ -419,6 +419,39 @@ enum scld_error safe_create_leading_directories_const(const char *path)return result; } +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) +{ +int fd; +/* +* we let the umask do its job, don't try to be more +* restrictive except to remove write permission. +*/ +int mode =0444 ; +git_path_buf (temp_filename,"objects/%s" , pattern); + fd =git_mkstemp_mode (temp_filename->buf, mode); +if (0 <= fd) +return fd; + +/* slow path */ +/* some mkstemp implementations erase temp_filename on failure */ +git_path_buf (temp_filename,"objects/%s" , pattern); +safe_create_leading_directories (temp_filename->buf); +return xmkstemp_mode (temp_filename->buf, mode); +} + +int odb_pack_keep (const char *name) +{ +int fd; + + fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +if (0 <= fd) +return fd; + +/* slow path */ +safe_create_leading_directories_const (name); +return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +} +static void fill_loose_path (struct strbuf *buf,const struct object_id *oid) {int i;
object-store-ll.h +15 -0
@@ -231,6 +231,21 @@ struct raw_object_store {struct raw_object_store *raw_object_store_new (void );void raw_object_store_clear (struct raw_object_store *o); +/* +* Create a temporary file rooted in the object database directory, or +* die on failure. The filename is taken from "pattern", which should have the +* usual "XXXXXX" trailer, and the resulting filename is written into the +* "template" buffer. Returns the open descriptor. +*/ +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); + +/* +* Create a pack .keep file named "name" (which should generally be the output +* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on +* error. +*/ +int odb_pack_keep (const char *name); +/* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid.
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 10/21 environment: make `get_git_namespace()` self-contained
In reply to Patrick SteinhardtThe logic to set up and retrieve git_namespace is distributed across different functions which communicate with each other via a global environment variable. This is rather pointless though, as the value is always derived from an environment variable, and this environment variable does not change after we have parsed global options.
Convert the function to be fully self-contained such that it lazily populates once called.
--- environment.c | 57 ++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 28 deletions(-)
environment.c +29 -28
@@ -122,8 +122,6 @@ int core_preload_index = 1;/* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; -static char *git_namespace; -/* * Repository-local GIT_* environment variables; see environment.h for details. */
@@ -146,27 +144,6 @@ const char * const local_repo_env[] = { NULL }; -static char *expand_namespace (const char *raw_namespace) -{ -struct strbuf buf =STRBUF_INIT ; -struct strbuf **components, **c; - -if (!raw_namespace || !*raw_namespace) -return xstrdup ("" ); - -strbuf_addstr (&buf, raw_namespace); - components =strbuf_split (&buf,'/' ); -strbuf_reset (&buf); -for (c = components; *c; c++) -if (strcmp ((*c)->buf,"/" ) !=0 ) -strbuf_addf (&buf,"refs/namespaces/%s" , (*c)->buf); -strbuf_list_free (components); -if (check_refname_format (buf.buf,0 )) -die (_ ("bad git namespace path \"%s\"" ), raw_namespace); -strbuf_addch (&buf,'/' ); -return strbuf_detach (&buf,NULL ); -} -const char *getenv_safe (struct strvec *argv,const char *name) {const char *value =getenv (name);
@@ -205,8 +182,6 @@ void setup_git_env(const char *git_dir) : "refs/replace/");update_ref_namespace (NAMESPACE_REPLACE , git_replace_ref_base); -free (git_namespace); - git_namespace =expand_namespace (getenv (GIT_NAMESPACE_ENVIRONMENT )); shallow_file =getenv (GIT_SHALLOW_FILE_ENVIRONMENT );if (shallow_file)set_alternate_shallow_file (the_repository, shallow_file,0 );
@@ -229,9 +204,35 @@ int have_git_dir(void)const char *get_git_namespace (void ) { -if (!git_namespace) -BUG ("git environment hasn't been setup" ); -return git_namespace; +static const char *namespace; + +struct strbuf buf =STRBUF_INIT ; +struct strbuf **components, **c; +const char *raw_namespace; + +if (namespace) +return namespace; + + raw_namespace =getenv (GIT_NAMESPACE_ENVIRONMENT ); +if (!raw_namespace || !*raw_namespace) { + namespace ="" ; +return namespace; + } + +strbuf_addstr (&buf, raw_namespace); + components =strbuf_split (&buf,'/' ); +strbuf_reset (&buf); +for (c = components; *c; c++) +if (strcmp ((*c)->buf,"/" ) !=0 ) +strbuf_addf (&buf,"refs/namespaces/%s" , (*c)->buf); +strbuf_list_free (components); +if (check_refname_format (buf.buf,0 )) +die (_ ("bad git namespace path \"%s\"" ), raw_namespace); +strbuf_addch (&buf,'/' ); + + namespace =strbuf_detach (&buf,NULL ); + +return namespace; }const char *strip_namespace (const char *namespaced_ref)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 11/21 environment: move `set_git_dir()` and related into setup layer
In reply to Patrick SteinhardtThe functions set_git_dir() and friends are used to set up repositories. As such, they are quite clearly part of the setup subsystem, but still live in "environment.c". Move them over, which also helps to get rid of dependencies on the_repository in the environment subsystem.
--- environment.c | 105 -------------------------------------------- environment.h | 2 - setup.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++--- setup.h | 3 ++ 4 files changed, 115 insertions(+), 113 deletions(-)
environment.c +0 -105
@@ -22,14 +22,9 @@#include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" -#include "object-file.h" #include "path.h" -#include "replace-object.h" -#include "tmp-objdir.h" #include "chdir-notify.h" #include "setup.h" -#include "shallow.h" -#include "trace.h" #include "write-or-die.h" int trust_executable_bit =1 ;
@@ -155,41 +150,6 @@ const char *getenv_safe(struct strvec *argv, const char *name)return argv->v[argv->nr -1 ]; } -void setup_git_env (const char *git_dir) -{ -char *git_replace_ref_base; -const char *shallow_file; -const char *replace_ref_base; -struct set_gitdir_args args = {NULL }; -struct strvec to_free =STRVEC_INIT ; - - args.commondir =getenv_safe (&to_free,GIT_COMMON_DIR_ENVIRONMENT ); - args.object_dir =getenv_safe (&to_free,DB_ENVIRONMENT ); - args.graft_file =getenv_safe (&to_free,GRAFT_ENVIRONMENT ); - args.index_file =getenv_safe (&to_free,INDEX_ENVIRONMENT ); - args.alternate_db =getenv_safe (&to_free,ALTERNATE_DB_ENVIRONMENT ); -if (getenv (GIT_QUARANTINE_ENVIRONMENT )) { - args.disable_ref_updates =1 ; - } - -repo_set_gitdir (the_repository, git_dir, &args); -strvec_clear (&to_free); - -if (getenv (NO_REPLACE_OBJECTS_ENVIRONMENT )) -disable_replace_refs (); - replace_ref_base =getenv (GIT_REPLACE_REF_BASE_ENVIRONMENT ); - git_replace_ref_base =xstrdup (replace_ref_base ? replace_ref_base - :"refs/replace/" ); -update_ref_namespace (NAMESPACE_REPLACE , git_replace_ref_base); - - shallow_file =getenv (GIT_SHALLOW_FILE_ENVIRONMENT ); -if (shallow_file) -set_alternate_shallow_file (the_repository, shallow_file,0 ); - -if (git_env_bool (NO_LAZY_FETCH_ENVIRONMENT ,0 )) - fetch_if_missing =0 ; -} -int is_bare_repository (void ) {/* if core.bare is not 'false', let's see if there is a work tree */
@@ -243,71 +203,6 @@ const char *strip_namespace(const char *namespaced_ref)return NULL ; } -static int git_work_tree_initialized; - -/* -* Note. This works only before you used a work tree. This was added -* primarily to support git-clone to work in a new repository it just -* created, and is not meant to flip between different work trees. -*/ -void set_git_work_tree (const char *new_work_tree) -{ -if (git_work_tree_initialized) { -struct strbuf realpath =STRBUF_INIT ; - -strbuf_realpath (&realpath, new_work_tree,1 ); - new_work_tree = realpath.buf; -if (strcmp (new_work_tree, the_repository->worktree)) -die ("internal error: work tree has already been set\n" -"Current worktree: %s\nNew worktree: %s" , - the_repository->worktree, new_work_tree); -strbuf_release (&realpath); -return ; - } - git_work_tree_initialized =1 ; -repo_set_worktree (the_repository, new_work_tree); -} - -static void set_git_dir_1 (const char *path) -{ -xsetenv (GIT_DIR_ENVIRONMENT , path,1 ); -setup_git_env (path); -} - -static void update_relative_gitdir(const char *name UNUSED, -const char *old_cwd, -const char *new_cwd, - void *data UNUSED) -{ -char *path =reparent_relative_path (old_cwd, new_cwd, -repo_get_git_dir (the_repository)); -struct tmp_objdir *tmp_objdir =tmp_objdir_unapply_primary_odb (); - -trace_printf_key (&trace_setup_key, -"setup: move $GIT_DIR to '%s'" , - path); -set_git_dir_1 (path); -if (tmp_objdir) -tmp_objdir_reapply_primary_odb (tmp_objdir, old_cwd, new_cwd); -free (path); -} - -void set_git_dir (const char *path,int make_realpath) -{ -struct strbuf realpath =STRBUF_INIT ; - -if (make_realpath) { -strbuf_realpath (&realpath, path,1 ); - path = realpath.buf; - } - -set_git_dir_1 (path); -if (!is_absolute_path (path)) -chdir_notify_register (NULL , update_relative_gitdir,NULL ); - -strbuf_release (&realpath); -} -const char *get_log_output_encoding (void ) { return git_log_output_encoding ? git_log_output_encoding
environment.h +0 -2
@@ -105,10 +105,8 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); -void set_git_work_tree (const char *tree);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
setup.c +112 -6
142 lines not on this page · raw message
setup.h +3 -0
@@ -94,6 +94,9 @@ static inline int discover_git_directory(struct strbuf *commondir,return 0 ; } +void set_git_dir (const char *path,int make_realpath); +void set_git_work_tree (const char *tree); +const char *setup_git_directory_gently (int *);const char *setup_git_directory (void );char *prefix_path (const char *prefix,int len,const char *path);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 12/21 environment: reorder header to split out `the_repository`-free section
In reply to Patrick SteinhardtReorder the "environment.h" header such that declarations which are free from the_repository come before those which aren't. The new structure is now:
- Defines for environment variable names.
- Things which do not rely on a repository.
- Things which do, including those that implicitly rely on a parsed repository. This includes for example variables which get populated when reading repository config.
This will allow us to guard the last category of declarations with USE_THE_REPOSITORY_VARIABLE.
--- environment.h | 81 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 41 deletions(-)
environment.h +40 -41
@@ -1,22 +1,6 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct strvec ; - -/* -* The character that begins a commented line in user-editable file -* that is subject to stripspace. -*/ -extern const char *comment_line_str; -extern char *comment_line_str_to_free; -extern int auto_comment_line_char; - -/* -* Wrapper of getenv() that returns a strdup value. This value is kept -* in argv to be freed later. -*/ -const char *getenv_safe (struct strvec *argv,const char *name); -/* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR"#define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR"
@@ -86,6 +70,8 @@ const char *getenv_safe(struct strvec *argv, const char *name);*/ #define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE" +#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" +/* * Repository-local GIT_* environment variables; these will be cleared * when git spawns a sub-process that runs inside another repository.
@@ -94,6 +80,28 @@ const char *getenv_safe(struct strvec *argv, const char *name);*/ extern const char *const local_repo_env[]; +struct strvec ; + +/* +* Wrapper of getenv() that returns a strdup value. This value is kept +* in argv to be freed later. +*/ +const char *getenv_safe (struct strvec *argv,const char *name); + +/* +* Should we print an ellipsis after an abbreviated SHA-1 value +* when doing diff-raw output or indicating a detached HEAD? +*/ +int print_sha1_ellipsis (void ); + +/* +* Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). +*/ +int use_optional_locks (void ); + +const char *get_git_namespace (void ); +const char *strip_namespace (const char *namespaced_ref); +void setup_git_env (const char *git_dir);/*
@@ -102,13 +110,19 @@ void setup_git_env(const char *git_dir);*/ int have_git_dir (void ); +/* +* Accessors for the core.sharedrepository config which lazy-load the value +* from the config (if not already set). The "reset" function can be +* used to unset "set" or cached value, meaning that the value will be loaded +* fresh from the config file on the next call to get_shared_repository(). +*/ +void set_shared_repository (int value); +int get_shared_repository (void ); +void reset_shared_repository (void ); +extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_namespace (void ); -const char *strip_namespace (const char *namespaced_ref); - -#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"/* Environment bits from configuration mechanism */ extern int trust_executable_bit;
@@ -134,16 +148,6 @@ extern unsigned long big_file_threshold;extern unsigned long pack_size_limit_cfg;extern int max_allowed_tree_depth; -/* -* Accessors for the core.sharedrepository config which lazy-load the value -* from the config (if not already set). The "reset" function can be -* used to unset "set" or cached value, meaning that the value will be loaded -* fresh from the config file on the next call to get_shared_repository(). -*/ -void set_shared_repository (int value); -int get_shared_repository (void ); -void reset_shared_repository (void ); -extern int core_preload_index;extern int precomposed_unicode;extern int protect_hfs;
@@ -153,11 +157,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -/* -* Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). -*/ -int use_optional_locks (void ); -enum log_refs_config {LOG_REFS_UNSET =-1 ,LOG_REFS_NONE =0 ,
@@ -172,6 +171,7 @@ enum rebase_setup_type {AUTOREBASE_REMOTE ,AUTOREBASE_ALWAYS }; +extern enum rebase_setup_type autorebase;enum push_default_type { PUSH_DEFAULT_NOTHING = 0,
@@ -181,15 +181,12 @@ enum push_default_type {PUSH_DEFAULT_CURRENT , PUSH_DEFAULT_UNSPECIFIED }; - -extern enum rebase_setup_type autorebase;extern enum push_default_type push_default;enum object_creation_mode {OBJECT_CREATION_USES_HARDLINKS =0 ,OBJECT_CREATION_USES_RENAMES =1 }; -extern enum object_creation_mode object_creation_mode;extern char *notes_ref_name;
@@ -209,9 +206,11 @@ extern char *askpass_program;extern char *excludes_file;/* -* Should we print an ellipsis after an abbreviated SHA-1 value -* when doing diff-raw output or indicating a detached HEAD? +* The character that begins a commented line in user-editable file +* that is subject to stripspace. */ -int print_sha1_ellipsis (void ); +extern const char *comment_line_str; +extern char *comment_line_str_to_free; +extern int auto_comment_line_char;#endif
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 13/21 environment: guard state depending on a repository
In reply to Patrick SteinhardtIn "environment.h" we have quite a lot of functions and variables that either explicitly or implicitly depend on the_repository.
The implicit set of stateful declarations includes for example variables which get populated when parsing a repository's Git configuration. This set of variables is broken by design, as their state often depends on the last repository config that has been parsed. So they may or may not represent the state of the_repository.
Fixing that is quite a big undertaking, and later patches in this series will demonstrate a solution for a first small set of those variables. So for now, let's guard these with USE_THE_REPOSITORY_VARIABLE so that callers are aware of the implicit dependency.
--- config.c | 2 ++ environment.h | 25 ++++++++++++++++++++++++- name-hash.c | 3 +++ path.c | 2 ++ preload-index.c | 3 +++ prompt.c | 2 ++ refs/files-backend.c | 2 ++ sparse-index.c | 2 ++ statinfo.c | 2 ++ t/helper/test-path-utils.c | 2 ++ tree-diff.c | 3 +++ userdiff.c | 2 ++ 12 files changed, 49 insertions(+), 1 deletion(-)
config.c +2 -0
@@ -6,6 +6,8 @@* */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
environment.h +24 -1
@@ -102,6 +102,28 @@ int use_optional_locks(void);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); +/* +* TODO: All the below state either explicitly or implicitly relies on +* `the_repository`. We should eventually get rid of these and make the +* dependency on a repository explicit: +* +* - `setup_git_env()` ideally shouldn't exist as it modifies global state, +* namely the environment. The current process shouldn't ever access that +* state via envvars though, but should instead consult a `struct +* repository`. When spawning new processes, we would ideally also pass a +* `struct repository` and then set up the environment variables for the +* child process, only. +* +* - `have_git_dir()` should not have to exist at all. Instead, we should +* decide on whether or not we have a `struct repository`. +* +* - All the global config variables should become tied to a repository. Like +* this, we'd correctly honor repository-local configuration and be able to +* distinguish configuration values from different repositories. +* +* Please do not add new global config variables here. +*/ +# ifdef USE_THE_REPOSITORY_VARIABLE void setup_git_env (const char *git_dir);/*
@@ -213,4 +235,5 @@ extern const char *comment_line_str;extern char *comment_line_str_to_free;extern int auto_comment_line_char; -#endif +# endif /* USE_THE_REPOSITORY_VARIABLE */ +#endif /* ENVIRONMENT_H */
name-hash.c +3 -0
@@ -5,6 +5,9 @@* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "gettext.h"
path.c +2 -0
@@ -2,6 +2,8 @@* Utilities for paths and pathnames */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "environment.h"
preload-index.c +3 -0
@@ -1,6 +1,9 @@/* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "pathspec.h" #include "dir.h"
prompt.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "parse.h" #include "environment.h"
refs/files-backend.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../git-compat-util.h" #include "../copy.h" #include "../environment.h"
sparse-index.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "gettext.h"
statinfo.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "statinfo.h"
t/helper/test-path-utils.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "test-tool.h" #include "abspath.h" #include "environment.h"
tree-diff.c +3 -0
@@ -1,6 +1,9 @@/* * Helper functions for tree diff generation */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "diff.h" #include "diffcore.h"
userdiff.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "userdiff.h"
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 14/21 repo-settings: split out declarations into a standalone header
In reply to Patrick SteinhardtWhile we have "repo-settings.c", we do not have a corresponding "repo-settings.h" file. Instead, this functionality is part of the "repository.h" header, making it hard to discover.
Split the declarations out of "repository.h" and create a standalone header file with them.
--- repo-settings.c | 1 + repo-settings.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ repository.h | 51 +------------------------------------------- 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 repo-settings.h
repo-settings.c +1 -0
@@ -1,5 +1,6 @@#include "git-compat-util.h" #include "config.h" +#include "repo-settings.h" #include "repository.h" #include "midx.h"
repo-settings.h new file +56 -0
56 lines not on this page · raw message
repository.h +1 -50
77 lines not on this page · raw message
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 15/21 branch: stop modifying `log_all_ref_updates` variable
In reply to Patrick SteinhardtIn "branch.c" we modify the global log_all_ref_updates variable to force creation of a reflog entry. Modifying global state like this is discouraged, as it may have all kinds of consequences in other places of our codebase.
Stop modifying the variable and pass the REF_FORCE_CREATE_REFLOG flag, which has the same effect.
--- branch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
branch.c +3 -2
@@ -601,6 +601,7 @@ void create_branch(struct repository *r,int forcing =0 ;struct ref_transaction *transaction;struct strbuf err =STRBUF_INIT ; +int flags =0 ;char *msg;if (track ==BRANCH_TRACK_OVERRIDE )
@@ -619,7 +620,7 @@ void create_branch(struct repository *r, goto cleanup;if (reflog) - log_all_ref_updates =LOG_REFS_NORMAL ; + flags |=REF_FORCE_CREATE_REFLOG ;if (forcing) msg =xstrfmt ("branch: Reset to %s" , start_name);
@@ -630,7 +631,7 @@ void create_branch(struct repository *r,if (!transaction ||ref_transaction_update (transaction, ref.buf, &oid, forcing ?NULL :null_oid (), -NULL ,NULL ,0 , msg, &err) || +NULL ,NULL , flags, msg, &err) ||ref_transaction_commit (transaction, &err))die ("%s" , err.buf);ref_transaction_free (transaction);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 16/21 refs: stop modifying global `log_all_ref_updates` variable
In reply to Patrick SteinhardtIn refs-related code we modify the global log_all_ref_updates variable, which is done because should_autocreate_reflog() does not accept passing an enum log_refs_config but instead accesses the global variable. Adapt its interface such that the value is provided by the caller, which allows us to compute the proper value locally without having to modify global state.
This change requires us to move the enum to "repo-settings.h", or otherwise we get compilation errors due to include cycles. We're about to fully move this setting into the repo-settings subsystem anyway, so this is fine.
--- builtin/checkout.c | 2 +- environment.h | 8 ++------ refs.c | 3 ++- refs.h | 4 +++- refs/files-backend.c | 22 +++++++++++----------- refs/reftable-backend.c | 12 +++++++----- repo-settings.h | 7 +++++++ 7 files changed, 33 insertions(+), 25 deletions(-)
builtin/checkout.c +1 -1
@@ -954,7 +954,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts, refname =mkpathdup ("refs/heads/%s" , opts->new_orphan_branch);if (opts->new_branch_log && - !should_autocreate_reflog (refname)) { + !should_autocreate_reflog (log_all_ref_updates, refname)) {int ret;struct strbuf err =STRBUF_INIT ;
environment.h +2 -6
@@ -1,6 +1,8 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H +#include "repo-settings.h" +/* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR"#define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR"
@@ -179,12 +181,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -enum log_refs_config { -LOG_REFS_UNSET =-1 , -LOG_REFS_NONE =0 , -LOG_REFS_NORMAL , -LOG_REFS_ALWAYS -};extern enum log_refs_config log_all_ref_updates;enum rebase_setup_type {
refs.c +2 -1
@@ -958,7 +958,8 @@ static char *normalize_reflog_message(const char *msg)return strbuf_detach (&sb,NULL ); } -int should_autocreate_reflog (const char *refname) +int should_autocreate_reflog (enum log_refs_config log_all_ref_updates, +const char *refname) {switch (log_all_ref_updates) {case LOG_REFS_ALWAYS :
refs.h +3 -1
@@ -3,6 +3,7 @@#include "commit.h" #include "repository.h" +#include "repo-settings.h" struct fsck_options ;struct object_id ;
@@ -111,7 +112,8 @@ int refs_verify_refname_available(struct ref_store *refs,int refs_ref_exists (struct ref_store *refs,const char *refname); -int should_autocreate_reflog (const char *refname); +int should_autocreate_reflog (enum log_refs_config log_all_ref_updates, +const char *refname);int is_branch (const char *refname);
refs/files-backend.c +11 -11
@@ -1443,6 +1443,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs,static int commit_ref_update (struct files_ref_store *refs,struct ref_lock *lock,const struct object_id *oid,const char *logmsg, +int flags,struct strbuf *err);/*
@@ -1586,7 +1587,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,oidcpy (&lock->old_oid, &orig_oid);if (write_ref_to_lockfile (refs, lock, &orig_oid,0 , &err) || -commit_ref_update (refs, lock, &orig_oid, logmsg, &err)) { +commit_ref_update (refs, lock, &orig_oid, logmsg,0 , &err)) {error ("unable to write current sha1 into %s: %s" , newrefname, err.buf);strbuf_release (&err); goto rollback;
@@ -1603,14 +1604,11 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, goto rollbacklog; } - flag = log_all_ref_updates; - log_all_ref_updates =LOG_REFS_NONE ;if (write_ref_to_lockfile (refs, lock, &orig_oid,0 , &err) || -commit_ref_update (refs, lock, &orig_oid,NULL , &err)) { +commit_ref_update (refs, lock, &orig_oid,NULL ,REF_SKIP_CREATE_REFLOG , &err)) {error ("unable to write current sha1 into %s: %s" , oldrefname, err.buf);strbuf_release (&err); } - log_all_ref_updates = flag; rollbacklog:if (logmoved &&rename (sb_newref.buf, sb_oldref.buf))
@@ -1705,13 +1703,17 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { + enum log_refs_config log_refs_cfg = log_all_ref_updates;struct strbuf logfile_sb =STRBUF_INIT ;char *logfile; +if (log_refs_cfg ==LOG_REFS_UNSET ) + log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; +files_reflog_path (refs, &logfile_sb, refname); logfile =strbuf_detach (&logfile_sb,NULL ); -if (force_create ||should_autocreate_reflog (refname)) { +if (force_create ||should_autocreate_reflog (log_refs_cfg, refname)) {if (raceproof_create_file (logfile, open_or_create_logfile, logfd)) {if (errno ==ENOENT ) strbuf_addf(err, "unable to create directory for '%s': "
@@ -1800,9 +1802,6 @@ static int files_log_ref_write(struct files_ref_store *refs,if (flags &REF_SKIP_CREATE_REFLOG )return 0 ; -if (log_all_ref_updates ==LOG_REFS_UNSET ) - log_all_ref_updates =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; - result =log_ref_setup (refs, refname, flags &REF_FORCE_CREATE_REFLOG , &logfd, err);
@@ -1891,6 +1890,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs,static int commit_ref_update (struct files_ref_store *refs,struct ref_lock *lock,const struct object_id *oid,const char *logmsg, +int flags,struct strbuf *err) {files_assert_main_repository (refs,"commit_ref_update" );
@@ -1898,7 +1898,7 @@ static int commit_ref_update(struct files_ref_store *refs,clear_loose_ref_cache (refs);if (files_log_ref_write (refs, lock->ref_name, &lock->old_oid, oid, - logmsg,0 , err)) { + logmsg, flags, err)) {char *old_msg =strbuf_detach (err,NULL );strbuf_addf (err,"cannot update the ref '%s': %s" , lock->ref_name, old_msg);
@@ -1931,7 +1931,7 @@ static int commit_ref_update(struct files_ref_store *refs,struct strbuf log_err =STRBUF_INIT ;if (files_log_ref_write (refs,"HEAD" , &lock->old_oid, oid, - logmsg,0 , &log_err)) { + logmsg, flags, &log_err)) {error ("%s" , log_err.buf);strbuf_release (&log_err); }
refs/reftable-backend.c +7 -5
@@ -19,6 +19,7 @@#include "../reftable/reftable-record.h" #include "../reftable/reftable-error.h" #include "../reftable/reftable-iterator.h" +#include "../repo-settings.h" #include "../setup.h" #include "../strmap.h" #include "parse.h"
@@ -158,20 +159,21 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store,static int should_write_log (struct ref_store *refs,const char *refname) { -if (log_all_ref_updates ==LOG_REFS_UNSET ) - log_all_ref_updates =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; +enum log_refs_config log_refs_cfg = log_all_ref_updates; +if (log_refs_cfg ==LOG_REFS_UNSET ) + log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; -switch (log_all_ref_updates) { +switch (log_refs_cfg) {case LOG_REFS_NONE :return refs_reflog_exists (refs, refname);case LOG_REFS_ALWAYS :return 1 ;case LOG_REFS_NORMAL : -if (should_autocreate_reflog (refname)) +if (should_autocreate_reflog (log_refs_cfg, refname))return 1 ;return refs_reflog_exists (refs, refname);default : -BUG ("unhandled core.logAllRefUpdates value %d" , log_all_ref_updates); +BUG ("unhandled core.logAllRefUpdates value %d" , log_refs_cfg); } }
repo-settings.h +7 -0
@@ -16,6 +16,13 @@ enum fetch_negotiation_setting { FETCH_NEGOTIATION_NOOP, }; +enum log_refs_config { +LOG_REFS_UNSET =-1 , +LOG_REFS_NONE =0 , +LOG_REFS_NORMAL , +LOG_REFS_ALWAYS +}; +struct repo_settings {int initialized;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 17/21 repo-settings: track defaults close to `struct repo_settings`
In reply to Patrick SteinhardtThe default values for struct repo_settings are set up in prepare_repo_settings(). This is somewhat different from how we typically do this, namely by providing an INIT macro that sets up the default values for us.
Refactor the code to do the same.
--- repo-settings.c | 9 ++++----- repo-settings.h | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-)
repo-settings.c +4 -5
@@ -20,6 +20,7 @@ static void repo_cfg_int(struct repository *r, const char *key, int *dest,void prepare_repo_settings (struct repository *r) { +const struct repo_settings defaults =REPO_SETTINGS_INIT ;int experimental;int value;const char *strval;
@@ -29,13 +30,11 @@ void prepare_repo_settings(struct repository *r)if (!r->gitdir)BUG ("Cannot add settings for uninitialized repository" ); -if (r->settings.initialized++) +if (r->settings.initialized)return ; -/* Defaults */ - r->settings.index_version =-1 ; - r->settings.core_untracked_cache =UNTRACKED_CACHE_KEEP ; - r->settings.fetch_negotiation_algorithm =FETCH_NEGOTIATION_CONSECUTIVE ; +memcpy (&r->settings, &defaults,sizeof (defaults)); + r->settings.initialized++;/* Booleans config or default, cascades to other settings */ repo_cfg_bool (r,"feature.manyfiles" , &manyfiles,0 );
repo-settings.h +5 -0
@@ -57,6 +57,11 @@ struct repo_settings {int core_multi_pack_index; }; +#define REPO_SETTINGS_INIT { \ + .index_version = -1, \ + .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ + .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ +}void prepare_repo_settings (struct repository *r);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 18/21 environment: stop storing "core.logAllRefUpdates" globally
In reply to Patrick SteinhardtThe value of "core.logAllRefUpdates" is being stored in the global variable log_all_ref_updates. This design is somewhat aged nowadays, where it is entirely possible to access multiple repositories in the same process which all have different values for this setting. So using a single global variable to track it is plain wrong.
Remove the global variable. Instead, we now provide a new function part of the repo-settings subsystem that parses the value for a specific repository. While that may require us to read the value multiple times, we work around this by reading it once when the ref backends are set up and caching the value there.
--- builtin/checkout.c | 2 ++ config.c | 10 ---------- environment.c | 1 - environment.h | 2 -- refs/files-backend.c | 4 +++- refs/reftable-backend.c | 12 +++++++----- repo-settings.c | 16 ++++++++++++++++ repo-settings.h | 3 +++ setup.c | 2 +- 9 files changed, 32 insertions(+), 20 deletions(-)
builtin/checkout.c +2 -0
@@ -950,6 +950,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,const char *old_desc, *reflog_msg;if (opts->new_branch) {if (opts->new_orphan_branch) { +enum log_refs_config log_all_ref_updates = +repo_settings_get_log_all_ref_updates (the_repository);char *refname; refname =mkpathdup ("refs/heads/%s" , opts->new_orphan_branch);
config.c +0 -10
@@ -1452,16 +1452,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.logallrefupdates" )) { -if (value && !strcasecmp (value,"always" )) - log_all_ref_updates =LOG_REFS_ALWAYS ; -else if (git_config_bool (var, value)) - log_all_ref_updates =LOG_REFS_NORMAL ; -else - log_all_ref_updates =LOG_REFS_NONE ; -return 0 ; - } -if (!strcmp (var,"core.warnambiguousrefs" )) { warn_ambiguous_refs =git_config_bool (var, value);return 0 ;
environment.c +0 -1
@@ -77,7 +77,6 @@ int sparse_expect_files_outside_of_patterns;int merge_log_config =-1 ;int precomposed_unicode =-1 ;/* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; -enum log_refs_config log_all_ref_updates =LOG_REFS_UNSET ;int max_allowed_tree_depth = #ifdef _MSC_VER/*
environment.h +0 -2
@@ -181,8 +181,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -extern enum log_refs_config log_all_ref_updates; -enum rebase_setup_type {AUTOREBASE_NEVER =0 ,AUTOREBASE_LOCAL ,
refs/files-backend.c +3 -1
@@ -74,6 +74,7 @@ struct files_ref_store {unsigned int store_flags;char *gitcommondir; +enum log_refs_config log_all_ref_updates;struct ref_cache *loose;
@@ -106,6 +107,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->gitcommondir =strbuf_detach (&sb,NULL ); refs->packed_ref_store =packed_ref_store_init (repo, refs->gitcommondir, flags); + refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo);chdir_notify_reparent ("files-backend $GIT_DIR" , &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR",
@@ -1703,7 +1705,7 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { - enum log_refs_config log_refs_cfg = log_all_ref_updates; + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;struct strbuf logfile_sb =STRBUF_INIT ;char *logfile;
refs/reftable-backend.c +7 -5
@@ -52,6 +52,7 @@ struct reftable_ref_store {struct reftable_write_options write_options;unsigned int store_flags; +enum log_refs_config log_all_ref_updates;int err; };
@@ -157,21 +158,21 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store, } } -static int should_write_log (struct ref_store *refs,const char *refname) +static int should_write_log (struct reftable_ref_store *refs,const char *refname) { -enum log_refs_config log_refs_cfg = log_all_ref_updates; +enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;if (log_refs_cfg ==LOG_REFS_UNSET ) log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ;switch (log_refs_cfg) {case LOG_REFS_NONE : -return refs_reflog_exists (refs, refname); +return refs_reflog_exists (&refs->base, refname);case LOG_REFS_ALWAYS :return 1 ;case LOG_REFS_NORMAL :if (should_autocreate_reflog (log_refs_cfg, refname))return 1 ; -return refs_reflog_exists (refs, refname); +return refs_reflog_exists (&refs->base, refname);default :BUG ("unhandled core.logAllRefUpdates value %d" , log_refs_cfg); }
@@ -278,6 +279,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,base_ref_store_init (&refs->base, repo, gitdir, &refs_be_reftable);strmap_init (&refs->worktree_stacks); refs->store_flags = store_flags; + refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo); refs->write_options.hash_id = repo->hash_algo->format_id; refs->write_options.default_permissions =calc_shared_perm (0666 & ~mask);
@@ -1220,7 +1222,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data }else if (!(u->flags &REF_SKIP_CREATE_REFLOG ) && (u->flags &REF_HAVE_NEW ) && (u->flags &REF_FORCE_CREATE_REFLOG || -should_write_log (&arg->refs->base, u->refname))) { +should_write_log (arg->refs, u->refname))) {struct reftable_log_record *log;int create_reflog =1 ;
repo-settings.c +16 -0
@@ -124,3 +124,19 @@ void prepare_repo_settings(struct repository *r)*/ r->settings.command_requires_full_index =1 ; } + +enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo) +{ +const char *value; + +if (!repo_config_get_string_tmp (repo,"core.logallrefupdates" , &value)) { +if (value && !strcasecmp (value,"always" )) +return LOG_REFS_ALWAYS ; +else if (git_config_bool ("core.logallrefupdates" , value)) +return LOG_REFS_NORMAL ; +else +return LOG_REFS_NONE ; + } + +return LOG_REFS_UNSET ; +}
repo-settings.h +3 -0
@@ -65,4 +65,7 @@ struct repo_settings {void prepare_repo_settings (struct repository *r); +/* Read the value for "core.logAllRefUpdates". */ +enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo); +#endif /* REPO_SETTINGS_H */
setup.c +1 -1
@@ -2354,7 +2354,7 @@ static int create_default_files(const char *template_path,else {git_config_set ("core.bare" ,"false" );/* allow template config file to override the default */ -if (log_all_ref_updates ==LOG_REFS_UNSET ) +if (repo_settings_get_log_all_ref_updates (the_repository) ==LOG_REFS_UNSET )git_config_set ("core.logallrefupdates" ,"true" );if (needs_work_tree_config (original_git_dir, work_tree))git_config_set ("core.worktree" , work_tree);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 19/21 environment: stop storing "core.preferSymlinkRefs" globally
In reply to Patrick SteinhardtSame as the preceding commit, storing the "core.preferSymlinkRefs" value globally is misdesigned as this setting may be set per repository.
There is only a single user of this value anyway, namely the "files" backend. So let's just remove the global variable and read the value of this setting when initializing the backend.
--- config.c | 5 ----- environment.c | 1 - environment.h | 1 - refs/files-backend.c | 5 ++++- 4 files changed, 4 insertions(+), 8 deletions(-)
config.c +0 -5
@@ -1447,11 +1447,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.prefersymlinkrefs" )) { - prefer_symlink_refs =git_config_bool (var, value); -return 0 ; - } -if (!strcmp (var,"core.warnambiguousrefs" )) { warn_ambiguous_refs =git_config_bool (var, value);return 0 ;
environment.c +0 -1
@@ -34,7 +34,6 @@ int has_symlinks = 1;int minimum_abbrev =4 , default_abbrev =-1 ;int ignore_case;int assume_unchanged; -int prefer_symlink_refs;int is_bare_repository_cfg =-1 ;/* unspecified */ int warn_ambiguous_refs =1 ;int warn_on_object_refname_ambiguity =1 ;
environment.h +0 -1
@@ -156,7 +156,6 @@ extern int has_symlinks;extern int minimum_abbrev, default_abbrev;extern int ignore_case;extern int assume_unchanged; -extern int prefer_symlink_refs;extern int warn_ambiguous_refs;extern int warn_on_object_refname_ambiguity;extern char *apply_default_whitespace;
refs/files-backend.c +4 -1
@@ -1,6 +1,7 @@#define USE_THE_REPOSITORY_VARIABLE #include "../git-compat-util.h" +#include "../config.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h"
@@ -75,6 +76,7 @@ struct files_ref_store {char *gitcommondir;enum log_refs_config log_all_ref_updates; +int prefer_symlink_refs;struct ref_cache *loose;
@@ -108,6 +110,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->packed_ref_store =packed_ref_store_init (repo, refs->gitcommondir, flags); refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo); +repo_config_get_bool (repo,"core.prefersymlinkrefs" , &refs->prefer_symlink_refs);chdir_notify_reparent ("files-backend $GIT_DIR" , &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR",
@@ -2941,7 +2944,7 @@ static int files_transaction_finish(struct ref_store *ref_store,* We try creating a symlink, if that succeeds we continue to the * next update. If not, we try and create a regular symref. */ -if (update->new_target && prefer_symlink_refs) +if (update->new_target && refs->prefer_symlink_refs)if (!create_ref_symlink (lock, update->new_target))continue ;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 20/21 environment: stop storing "core.warnAmbiguousRefs" globally
In reply to Patrick SteinhardtSame as the preceding commits, storing the "core.warnAmbiguousRefs" value globally is misdesigned as this setting may be set per repository.
Move the logic into the repo-settings subsystem. The usual pattern here is that users are expected to call prepare_repo_settings() before they access the settings themselves. This seems somewhat fragile though, as it is easy to miss and leads to somewhat ugly code patterns at the call sites.
Instead, introduce a new function that encapsulates this logic for us. This also allows us to change how exactly the lazy initialization works in the future, e.g. by only partially initializing values as requested by the caller.
--- builtin/rev-parse.c | 3 ++- config.c | 5 ----- environment.c | 1 - environment.h | 1 - object-name.c | 4 ++-- ref-filter.c | 2 +- refs.c | 4 ++-- repo-settings.c | 9 +++++++++ repo-settings.h | 4 ++++ 9 files changed, 20 insertions(+), 13 deletions(-)
builtin/rev-parse.c +2 -1
@@ -898,7 +898,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) }if (opt_with_value (arg,"--abbrev-ref" , &arg)) { abbrev_ref =1 ; - abbrev_ref_strict = warn_ambiguous_refs; + abbrev_ref_strict = +repo_settings_get_warn_ambiguous_refs (the_repository);if (arg) {if (!strcmp (arg,"strict" )) abbrev_ref_strict =1 ;
config.c +0 -5
@@ -1447,11 +1447,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.warnambiguousrefs" )) { - warn_ambiguous_refs =git_config_bool (var, value); -return 0 ; - } -if (!strcmp (var,"core.abbrev" )) {if (!value)return config_error_nonbool (var);
environment.c +0 -1
@@ -35,7 +35,6 @@ int minimum_abbrev = 4, default_abbrev = -1;int ignore_case;int assume_unchanged;int is_bare_repository_cfg =-1 ;/* unspecified */ -int warn_ambiguous_refs =1 ;int warn_on_object_refname_ambiguity =1 ;int repository_format_precious_objects;char *git_commit_encoding;
environment.h +0 -1
@@ -156,7 +156,6 @@ extern int has_symlinks;extern int minimum_abbrev, default_abbrev;extern int ignore_case;extern int assume_unchanged; -extern int warn_ambiguous_refs;extern int warn_on_object_refname_ambiguity;extern char *apply_default_whitespace;extern char *apply_default_ignorewhitespace;
object-name.c +2 -2
@@ -959,7 +959,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,int fatal = !(flags &GET_OID_QUIETLY );if (len == r->hash_algo->hexsz && !get_oid_hex (str, oid)) { -if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) { +if (repo_settings_get_warn_ambiguous_refs (r) && warn_on_object_refname_ambiguity) { refs_found =repo_dwim_ref (r, str, len, &tmp_oid, &real_ref,0 );if (refs_found >0 ) {warning (warn_msg, len, str);
@@ -1020,7 +1020,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,if (!refs_found)return -1 ; -if (warn_ambiguous_refs && !(flags &GET_OID_QUIETLY ) && +if (repo_settings_get_warn_ambiguous_refs (r) && !(flags &GET_OID_QUIETLY ) && (refs_found >1 || !get_short_oid (r, str, len, &tmp_oid,GET_OID_QUIETLY )))warning (warn_msg, len, str);
ref-filter.c +1 -1
@@ -2160,7 +2160,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname)if (atom->option ==R_SHORT )return refs_shorten_unambiguous_ref (get_main_ref_store (the_repository), refname, - warn_ambiguous_refs); +repo_settings_get_warn_ambiguous_refs (the_repository));else if (atom->option ==R_LSTRIP )return lstrip_ref_components (refname, atom->lstrip);else if (atom->option ==R_RSTRIP )
refs.c +2 -2
@@ -730,7 +730,7 @@ int expand_ref(struct repository *repo, const char *str, int len,if (r) {if (!refs_found++) *ref =xstrdup (r); -if (!warn_ambiguous_refs) +if (!repo_settings_get_warn_ambiguous_refs (repo))break ; }else if ((flag &REF_ISSYMREF ) &&strcmp (fullref.buf,"HEAD" )) {warning (_ ("ignoring dangling symref %s" ), fullref.buf);
@@ -775,7 +775,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len,if (oid)oidcpy (oid, &hash); } -if (!warn_ambiguous_refs) +if (!repo_settings_get_warn_ambiguous_refs (r))break ; }strbuf_release (&path);
repo-settings.c +9 -0
@@ -140,3 +140,12 @@ enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *rereturn LOG_REFS_UNSET ; } + +int repo_settings_get_warn_ambiguous_refs (struct repository *repo) +{ +prepare_repo_settings (repo); +if (repo->settings.warn_ambiguous_refs <0 ) +repo_cfg_bool (repo,"core.warnambiguousrefs" , + &repo->settings.warn_ambiguous_refs,1 ); +return repo->settings.warn_ambiguous_refs; +}
repo-settings.h +4 -0
@@ -56,16 +56,20 @@ struct repo_settings {enum fetch_negotiation_setting fetch_negotiation_algorithm;int core_multi_pack_index; + int warn_ambiguous_refs; /* lazily loaded via accessor */ };#define REPO_SETTINGS_INIT { \ .index_version = -1, \ .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ + .warn_ambiguous_refs = -1, \ }void prepare_repo_settings (struct repository *r);/* Read the value for "core.logAllRefUpdates". */ enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo); +/* Read the value for "core.warnAmbiguousRefs". */ +int repo_settings_get_warn_ambiguous_refs (struct repository *repo);#endif /* REPO_SETTINGS_H */
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH 21/21 environment: stop storing "core.notesRef" globally
In reply to Patrick SteinhardtStop storing the "core.notesRef" config value globally. Instead, retrieve the value in default_notes_ref(). The code is never called in a hot loop anyway, so doing this on every invocation should be perfectly fine.
--- builtin/notes.c | 22 ++++++++++++++-------- config.c | 8 -------- environment.c | 1 - environment.h | 2 -- notes.c | 21 +++++++++++++-------- notes.h | 3 ++- 6 files changed, 29 insertions(+), 28 deletions(-)
builtin/notes.c +14 -8
@@ -897,6 +897,7 @@ static int merge(int argc, const char **argv, const char *prefix) 1, PARSE_OPT_NONEG), OPT_END() }; +char *notes_ref; argc =parse_options (argc, argv, prefix, options, git_notes_merge_usage,0 );
@@ -924,7 +925,8 @@ static int merge(int argc, const char **argv, const char *prefix)if (do_commit)return merge_commit (&o); - o.local_ref =default_notes_ref (); + notes_ref =default_notes_ref (the_repository); + o.local_ref = notes_ref;strbuf_addstr (&remote_ref, argv[0 ]);expand_loose_notes_ref (&remote_ref); o.remote_ref = remote_ref.buf;
@@ -953,7 +955,7 @@ static int merge(int argc, const char **argv, const char *prefix) }strbuf_addf (&msg,"notes: Merged notes from %s into %s" , - remote_ref.buf,default_notes_ref ()); + remote_ref.buf, notes_ref);strbuf_add (&(o.commit_msg), msg.buf +7 , msg.len -7 );/* skip "notes: " */ result =notes_merge (&o, t, &result_oid);
@@ -961,7 +963,7 @@ static int merge(int argc, const char **argv, const char *prefix)if (result >=0 )/* Merge resulted (trivially) in result_oid */ /* Update default notes ref with new commit */ refs_update_ref (get_main_ref_store (the_repository), msg.buf, -default_notes_ref (), &result_oid,NULL ,0 , + notes_ref, &result_oid,NULL ,0 ,UPDATE_REFS_DIE_ON_ERR );else {/* Merge has unresolved conflicts */ struct worktree **worktrees;
@@ -973,14 +975,14 @@ static int merge(int argc, const char **argv, const char *prefix)/* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ worktrees =get_worktrees (); wt =find_shared_symref (worktrees,"NOTES_MERGE_REF" , -default_notes_ref ()); + notes_ref);if (wt)die (_ ("a notes merge into %s is already in-progress at %s" ), -default_notes_ref (), wt->path); + notes_ref, wt->path);free_worktrees (worktrees); -if (refs_update_symref (get_main_ref_store (the_repository),"NOTES_MERGE_REF" ,default_notes_ref (),NULL )) +if (refs_update_symref (get_main_ref_store (the_repository),"NOTES_MERGE_REF" , notes_ref,NULL ))die (_ ("failed to store link to current notes ref (%s)" ), -default_notes_ref ()); + notes_ref); fprintf(stderr, _("Automatic notes merge failed. Fix conflicts in %s " "and commit the result with 'git notes merge --commit', " "or abort the merge with 'git notes merge --abort'.\n"),
@@ -988,6 +990,7 @@ static int merge(int argc, const char **argv, const char *prefix) }free_notes (t); +free (notes_ref);strbuf_release (&remote_ref);strbuf_release (&msg);return result <0 ;/* return non-zero on conflicts */
@@ -1084,6 +1087,7 @@ static int prune(int argc, const char **argv, const char *prefix)static int get_ref (int argc,const char **argv,const char *prefix) {struct option options[] = {OPT_END () }; +char *notes_ref; argc =parse_options (argc, argv, prefix, options, git_notes_get_ref_usage,0 );
@@ -1092,7 +1096,9 @@ static int get_ref(int argc, const char **argv, const char *prefix)usage_with_options (git_notes_get_ref_usage, options); } -puts (default_notes_ref ()); + notes_ref =default_notes_ref (the_repository); +puts (notes_ref); +free (notes_ref);return 0 ; }
config.c +0 -8
@@ -1555,14 +1555,6 @@ static int git_default_core_config(const char *var, const char *value,return git_config_string (&check_roundtrip_encoding, var, value); } -if (!strcmp (var,"core.notesref" )) { -if (!value) -return config_error_nonbool (var); -free (notes_ref_name); - notes_ref_name =xstrdup (value); -return 0 ; - } -if (!strcmp (var,"core.editor" )) {FREE_AND_NULL (editor_program);return git_config_string (&editor_program, var, value);
environment.c +0 -1
@@ -67,7 +67,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS#endif enum object_creation_mode object_creation_mode =OBJECT_CREATION_MODE ; -char *notes_ref_name;int grafts_keep_true_parents;int core_apply_sparse_checkout;int core_sparse_checkout_cone;
environment.h +0 -2
@@ -203,8 +203,6 @@ enum object_creation_mode { };extern enum object_creation_mode object_creation_mode; -extern char *notes_ref_name; -extern int grafts_keep_true_parents;extern int repository_format_precious_objects;
notes.c +13 -8
@@ -992,15 +992,16 @@ static int notes_display_config(const char *k, const char *v,return 0 ; } -const char *default_notes_ref (void ) +char *default_notes_ref (struct repository *repo) { -const char *notes_ref =NULL ; +char *notes_ref =NULL ; +if (!notes_ref) - notes_ref =getenv (GIT_NOTES_REF_ENVIRONMENT ); + notes_ref =xstrdup_or_null (getenv (GIT_NOTES_REF_ENVIRONMENT ));if (!notes_ref) - notes_ref = notes_ref_name;/* value of core.notesRef config */ +repo_config_get_string (repo,"core.notesref" , ¬es_ref);if (!notes_ref) - notes_ref =GIT_NOTES_DEFAULT_REF ; + notes_ref =xstrdup (GIT_NOTES_DEFAULT_REF );return notes_ref; }
@@ -1010,13 +1011,14 @@ void init_notes(struct notes_tree *t, const char *notes_ref,struct object_id oid, object_oid;unsigned short mode;struct leaf_node root_tree; +char *to_free =NULL ;if (!t) t = &default_notes_tree;assert (!t->initialized);if (!notes_ref) - notes_ref =default_notes_ref (); + notes_ref = to_free =default_notes_ref (the_repository);update_ref_namespace (NAMESPACE_NOTES ,xstrdup (notes_ref));if (!combine_notes)
@@ -1033,7 +1035,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,if (flags &NOTES_INIT_EMPTY ||repo_get_oid_treeish (the_repository, notes_ref, &object_oid)) -return ; + goto out;if (flags &NOTES_INIT_WRITABLE &&refs_read_ref (get_main_ref_store (the_repository), notes_ref, &object_oid))die ("Cannot use notes ref %s" , notes_ref);if (get_tree_entry (the_repository, &object_oid,"" , &oid, &mode))
@@ -1043,6 +1045,9 @@ void init_notes(struct notes_tree *t, const char *notes_ref,oidclr (&root_tree.key_oid, the_repository->hash_algo);oidcpy (&root_tree.val_oid, &oid);load_subtree (t, &root_tree, t->root,0 ); + +out: +free (to_free); }struct notes_tree **load_notes_trees (struct string_list *refs,int flags)
@@ -1105,7 +1110,7 @@ void load_display_notes(struct display_notes_opt *opt)if (!opt || opt->use_default_notes >0 || (opt->use_default_notes ==-1 && !opt->extra_notes_refs.nr)) { -string_list_append (&display_notes_refs,default_notes_ref ()); +string_list_append_nodup (&display_notes_refs,default_notes_ref (the_repository)); display_ref_env =getenv (GIT_NOTES_DISPLAY_REF_ENVIRONMENT );if (display_ref_env) { string_list_add_refs_from_colon_sep(&display_notes_refs,
notes.h +2 -1
@@ -4,6 +4,7 @@#include "string-list.h" struct object_id ; +struct repository ;struct strbuf ;/*
@@ -70,7 +71,7 @@ extern struct notes_tree {* 3. The value of the core.notesRef config variable, if set * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits") */ -const char *default_notes_ref (void ); +char *default_notes_ref (struct repository *repo);/* * Flags controlling behaviour of notes tree initialization
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
There may be more, but I know at least of these at the moment from
https://github.com/git/git/actions/runs/10619536685/job/29437358521
Perhaps this can become [0.5/21] of the series, before globals are hidden behind the macro.
--- >8 ---
Subject: [PATCH] win32: mark the sources that depend on the_repository
These source files still need access to the global variables like "ignore_case" and "protect_ntfs".
--- compat/mingw.c | 2 ++ compat/win32/path-utils.c | 2 ++ 2 files changed, 4 insertions(+)
compat/mingw.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../git-compat-util.h" #include "win32.h" #include <aclapi.h>
compat/win32/path-utils.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../../git-compat-util.h" #include "../../environment.h"
Signature · 1 line
2.46.0-567-gbce23f156d
Re: [PATCH 01/21] environment: make `get_git_dir()` accept a repository
In reply to Patrick SteinhardtQuoted 5 lines · Patrick Steinhardt
The
get_git_dir()function retrieves the path to the Git directory forthe_repository. Make it accept astruct repositorysuch that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance onthe_repositoryand clarifies scope.
Seems sensible to me. We are simply making it so the_repository is no longer implicit to the function.
Quoted 3 lines
Signed-off-by Patrick Steinhardt <[email protected]>---
[snip]
builtin/commit.c static const char *prepare_index(const char **argv, const char *prefix, · line 410
Quoted 8 lines
builtin/commit.c +1
-1@@ -407,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index);read_index_from (the_repository->index,get_lock_file_path (&index_lock), -get_git_dir ()); +repo_get_git_dir (the_repository));
Now that the repo_get_git_dir() function has been moved to "repository.h" should we also directly include this header in the c file? Or is the implicit reference sufficent? From our coding guidelines is seems we preferred to be direct.
It looks like there are several other hunks missing direct references to "repository.h" too.
[snip]
builtin/fsmonitor--daemon.c static int fsmonitor_run_daemon(void) · line 1315
Quoted 11 lines
builtin/fsmonitor--daemon.c +2
-1@@ -1311,7 +1311,8 @@ static int fsmonitor_run_daemon(void)strbuf_addstr (&state.path_gitdir_watch,"/.git" );if (!is_directory (state.path_gitdir_watch.buf)) {strbuf_reset (&state.path_gitdir_watch); -strbuf_addstr (&state.path_gitdir_watch,absolute_path (get_git_dir ())); +strbuf_addstr (&state.path_gitdir_watch, +absolute_path (repo_get_git_dir (the_repository)));
In this c file, now that repo_get_git_dir() lives in "repository.h", is the "environment.h" header file needed anymore?
-Justin
Quoted 5 lines · Junio C Hamano
There may be more, but I know at least of these at the moment from
https://github.com/git/git/actions/runs/10619536685/job/29437358521Perhaps this can become [0.5/21] of the series, before globals are hidden behind the macro.
Thanks, I'll add these. I really need to spend some time to finally get Win32 builds set up in GitLab CI.
Patrick
Quoted 35 lines
--- >8 ---
Subject: [PATCH] win32: mark the sources that depend onthe_repositoryThese source files still need access to the global variables like "
ignore_case" and "protect_ntfs".Signed-off-by Junio C Hamano <[email protected]>--- compat/mingw.c | 2 ++ compat/win32/path-utils.c | 2 ++ 2 files changed, 4 insertions(+)compat/mingw.c +2
-0@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../git-compat-util.h" #include "win32.h" #include <aclapi.h> compat/win32/path-utils.c +2
-0@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../../git-compat-util.h" #include "../../environment.h" Signature · 1 line
2.46.0-567-gbce23f156d
Re: [PATCH 01/21] environment: make `get_git_dir()` accept a repository
In reply to Justin ToblerQuoted 16 lines · Justin Tobler
On 24/08/29 11:38AM, Patrick Steinhardt wrote:
[snip]builtin/commit.c static const char *prepare_index(const char **argv, const char *prefix, · line 410
Quoted 8 lines
builtin/commit.c +1
-1@@ -407,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index);read_index_from (the_repository->index,get_lock_file_path (&index_lock), -get_git_dir ()); +repo_get_git_dir (the_repository));Now that the
repo_get_git_dir()function has been moved to "repository.h" should we also directly include this header in the c file? Or is the implicit reference sufficent? From our coding guidelines is seems we preferred to be direct.
Quoted 2 lines
It looks like there are several other hunks missing direct references to "
repository.h" too.
Yeah, you're right. Let me go through all the commits and double check whether includes need to change. Oh, well... sounds like fun *sigh*
Patrick
v2 cover environment: guard reliance on `the_repository`
In reply to Patrick SteinhardtHi,
this is the second version of my patch series which guards functions and variables in the environment subsystem that rely on the_repository with the USE_THE_REPOSITORY_VARIABLE define.
Changes compared to v1:
- Clean up now-unnecessary and add newly-necessary includes.
- Stop reordering includes in "setup.c".
- Fix missing USE_THE_REPOSITORY_VARIABLE defines in Win32 code.
Thanks!
Patrick
Patrick Steinhardt (21):
environment: make get_git_dir() accept a repository
environment: make get_git_common_dir() accept a repository
environment: make get_object_directory() accept a repository
environment: make get_index_file() accept a repository
environment: make get_graft_file() accept a repository
environment: make get_git_work_tree() accept a repository
config: document read_early_config() and read_very_early_config()
config: make dependency on repo in read_early_config() explicit
environment: move odb_mkstemp() into object layer
environment: make get_git_namespace() self-contained
environment: move set_git_dir() and related into setup layer
environment: reorder header to split out the_repository-free section
environment: guard state depending on a repository
repo-settings: split out declarations into a standalone header
repo-settings: track defaults close to struct repo_settings
branch: stop modifying log_all_ref_updates variable
refs: stop modifying global log_all_ref_updates variable
environment: stop storing "core.logAllRefUpdates" globally
environment: stop storing "core.preferSymlinkRefs" globally
environment: stop storing "core.warnAmbiguousRefs" globally
environment: stop storing "core.notesRef" globally
alias.c | 6 +- apply.c | 3 +- branch.c | 5 +- builtin/am.c | 13 +- builtin/blame.c | 2 +- builtin/checkout.c | 5 +- builtin/commit-graph.c | 5 +- builtin/commit.c | 13 +- builtin/config.c | 4 +- builtin/count-objects.c | 3 +- builtin/difftool.c | 9 +- builtin/fsmonitor--daemon.c | 7 +- builtin/gc.c | 2 +- builtin/init-db.c | 4 +- builtin/merge.c | 18 +-- builtin/multi-pack-index.c | 4 +- builtin/notes.c | 22 ++-- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 +- builtin/repack.c | 7 +- builtin/replace.c | 3 +- builtin/reset.c | 5 +- builtin/rev-parse.c | 11 +- builtin/stash.c | 17 +-- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 4 +- builtin/worktree.c | 4 +- builtin/write-tree.c | 4 +- bulk-checkin.c | 4 +- bundle-uri.c | 2 +- cache-tree.c | 5 +- commit.c | 4 +- compat/mingw.c | 2 + compat/win32/path-utils.c | 2 + config.c | 42 +------ config.h | 13 +- dir.c | 3 +- environment.c | 237 +++++------------------------------- environment.h | 142 ++++++++++----------- fetch-pack.c | 2 +- fsmonitor.c | 3 +- help.c | 2 +- http-backend.c | 2 +- name-hash.c | 3 + notes.c | 21 ++-- notes.h | 3 +- object-file.c | 37 +++++- object-name.c | 5 +- object-store-ll.h | 15 +++ pack-write.c | 3 +- packfile.c | 2 +- pager.c | 7 +- path.c | 2 + pathspec.c | 4 +- preload-index.c | 3 + prompt.c | 2 + prune-packed.c | 6 +- read-cache.c | 6 +- ref-filter.c | 3 +- refs.c | 9 +- refs.h | 4 +- refs/files-backend.c | 32 +++-- refs/reftable-backend.c | 22 ++-- repo-settings.c | 35 +++++- repo-settings.h | 75 ++++++++++++ repository.c | 40 ++++++ repository.h | 58 ++------- server-info.c | 4 +- setup.c | 140 ++++++++++++++++++--- setup.h | 5 +- sparse-index.c | 2 + statinfo.c | 2 + submodule.c | 2 +- t/helper/test-config.c | 3 +- t/helper/test-path-utils.c | 2 + tmp-objdir.c | 8 +- trace.c | 10 +- trace2/tr2_cfg.c | 4 +- transport-helper.c | 2 +- tree-diff.c | 3 + userdiff.c | 2 + worktree.c | 12 +- wt-status.c | 3 +- 83 files changed, 698 insertions(+), 560 deletions(-) create mode 100644 repo-settings.h
Range-diff against v1:
1: 0fe3e3e1ccc ! 1: a1969c5b073 environment: make get_git_dir() accept a repository
@@ Commit message
## apply.c ##
+@@
+ #include "path.h"
+ #include "quote.h"
+ #include "read-cache.h"
++#include "repository.h"
+ #include "rerere.h"
+ #include "apply.h"
+ #include "entry.h"
@@ apply.c: static int read_apply_cache(struct apply_state *state)
{
if (state->index_file)
@@ builtin/am.c: static int fall_back_threeway(const struct am_state *state, const
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
## builtin/commit.c ##
+@@
+ #include "path.h"
+ #include "preload-index.h"
+ #include "read-cache.h"
++#include "repository.h"
+ #include "string-list.h"
+ #include "rerere.h"
+ #include "unpack-trees.h"
@@ builtin/commit.c: static const char *prepare_index(const char **argv, const char *prefix,
discard_index(the_repository->index);
@@ builtin/config.c: static void location_options_init(struct config_location_optio
## builtin/difftool.c ##
+@@
+ #include "hex.h"
+ #include "parse-options.h"
+ #include "read-cache-ll.h"
++#include "repository.h"
+ #include "sparse-index.h"
+ #include "strvec.h"
+ #include "strbuf.h"
@@ builtin/difftool.c: static void changed_files(struct hashmap *result, const char *index_path,
struct child_process update_index = CHILD_PROCESS_INIT;
struct child_process diff_files = CHILD_PROCESS_INIT;
@@ builtin/fsmonitor--daemon.c: static int fsmonitor_run_daemon(void)
## builtin/merge.c ##
+@@
+ #include "object-name.h"
+ #include "parse-options.h"
+ #include "lockfile.h"
++#include "repository.h"
+ #include "run-command.h"
+ #include "hook.h"
+ #include "diff.h"
@@ builtin/merge.c: static void prepare_to_commit(struct commit_list *remoteheads)
if (invoked_hook)
discard_index(the_repository->index);
@@ builtin/merge.c: static void prepare_to_commit(struct commit_list *remoteheads)
BUG("the control must not reach here under --squash");
## builtin/stash.c ##
+@@
+ #include "entry.h"
+ #include "preload-index.h"
+ #include "read-cache.h"
++#include "repository.h"
+ #include "rerere.h"
+ #include "revision.h"
+ #include "setup.h"
@@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info *info,
strvec_pushf(&cp.env, GIT_WORK_TREE_ENVIRONMENT"=%s",
absolute_path(get_git_work_tree()));
@@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info
}
## cache-tree.c ##
+@@
+ #define USE_THE_REPOSITORY_VARIABLE
+
+ #include "git-compat-util.h"
+-#include "environment.h"
+ #include "hex.h"
+ #include "lockfile.h"
+ #include "tree.h"
+@@
+ #include "object-store-ll.h"
+ #include "read-cache-ll.h"
+ #include "replace-object.h"
++#include "repository.h"
+ #include "promisor-remote.h"
+ #include "trace.h"
+ #include "trace2.h"
@@ cache-tree.c: int write_index_as_tree(struct object_id *oid, struct index_state *index_state,
hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
@@ pathspec.c: static void init_pathspec_item(struct pathspec_item *item, unsigned
}
## read-cache.c ##
+@@
+ #include "path.h"
+ #include "preload-index.h"
+ #include "read-cache.h"
++#include "repository.h"
+ #include "resolve-undo.h"
+ #include "revision.h"
+ #include "strbuf.h"
@@ read-cache.c: static int should_delete_shared_index(const char *shared_index_path)
static int clean_shared_index_files(const char *current_hex)
{
@@ trace.c
#include "git-compat-util.h"
#include "abspath.h"
#include "environment.h"
++#include "repository.h"
+ #include "quote.h"
+ #include "setup.h"
+ #include "trace.h"
@@ trace.c: void trace_repo_setup(void)
if (!startup_info->prefix)
prefix = "(null)";
2: cdd6dd308c3 ! 2: deebf2c5205 environment: make get_git_common_dir() accept a repository
@@ builtin/gc.c: static int schtasks_schedule_task(const char *exec_path, enum sche
## builtin/rev-parse.c ##
+@@
+ #include "path.h"
+ #include "diff.h"
+ #include "read-cache-ll.h"
++#include "repository.h"
+ #include "revision.h"
+ #include "setup.h"
+ #include "split-index.h"
@@ builtin/rev-parse.c: int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
3: bb01e4fab9d ! 3: 43abfa7b139 environment: make get_object_directory() accept a repository
@@ Commit message
## builtin/commit-graph.c ##
+@@
+ #include "builtin.h"
+ #include "commit.h"
+ #include "config.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "hex.h"
+ #include "parse-options.h"
@@ builtin/commit-graph.c: static int graph_verify(int argc, const char **argv, const char *prefix)
usage_with_options(builtin_commit_graph_verify_usage, options);
@@ builtin/commit-graph.c: static int graph_write(int argc, const char **argv, cons
if (opts.split)
## builtin/count-objects.c ##
+@@
+ #include "builtin.h"
+ #include "config.h"
+ #include "dir.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "path.h"
+ #include "repository.h"
@@ builtin/count-objects.c: int cmd_count_objects(int argc, const char **argv, const char *prefix)
report_linked_checkout_garbage(the_repository);
}
@@ builtin/count-objects.c: int cmd_count_objects(int argc, const char **argv, cons
if (verbose) {
## builtin/multi-pack-index.c ##
+@@
+ #include "builtin.h"
+ #include "abspath.h"
+ #include "config.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "parse-options.h"
+ #include "midx.h"
+@@
+ #include "trace2.h"
+ #include "object-store-ll.h"
+ #include "replace-object.h"
++#include "repository.h"
+
+ #define BUILTIN_MIDX_WRITE_USAGE \
+ N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \
@@ builtin/multi-pack-index.c: static int parse_object_dir(const struct option *opt, const char *arg,
char **value = opt->value;
free(*value);
@@ object-file.c: int stream_loose_object(struct input_stream *in_stream, size_t le
/*
## pack-write.c ##
+@@
+ #include "pack-objects.h"
+ #include "pack-revindex.h"
+ #include "path.h"
++#include "repository.h"
+ #include "strbuf.h"
+
+ void reset_pack_idx_option(struct pack_idx_option *opts)
@@ pack-write.c: char *index_pack_lockfile(int ip_out, int *is_well_formed)
packname[len-1] = 0;
if (skip_prefix(packname, "keep\t", &name))
@@ prune-packed.c
+#define USE_THE_REPOSITORY_VARIABLE
+
#include "git-compat-util.h"
- #include "environment.h"
+-#include "environment.h"
#include "gettext.h"
+ #include "object-store-ll.h"
+ #include "packfile.h"
+ #include "progress.h"
+ #include "prune-packed.h"
++#include "repository.h"
+
+ static struct progress *progress;
+
@@ prune-packed.c: void prune_packed_objects(int opts)
if (opts & PRUNE_PACKED_VERBOSE)
progress = start_delayed_progress(_("Removing duplicate objects"), 256);
@@ repository.h: extern struct repository *the_repository;
* Define a custom repository layout. Any field can be NULL, which
## server-info.c ##
+@@
+
+ #include "git-compat-util.h"
+ #include "dir.h"
+-#include "environment.h"
+ #include "hex.h"
+ #include "repository.h"
+ #include "refs.h"
@@ server-info.c: static int write_pack_info_file(struct update_info_ctx *uic)
static int update_info_packs(int force)
@@ setup.c: static void create_object_directory(void)
safe_create_dir(path.buf, 1);
## tmp-objdir.c ##
+@@
+ #include "strvec.h"
+ #include "quote.h"
+ #include "object-store-ll.h"
++#include "repository.h"
+
+ struct tmp_objdir {
+ struct strbuf path;
@@ tmp-objdir.c: struct tmp_objdir *tmp_objdir_create(const char *prefix)
* can recognize any stale objdirs left behind by a crash and delete
* them.
4: d857c5fab44 ! 4: d7554cb0fe0 environment: make get_index_file() accept a repository
@@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const
die("Unable to write new index file");
## builtin/write-tree.c ##
+@@
+
+ #include "builtin.h"
+ #include "config.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "hex.h"
+ #include "tree.h"
@@ builtin/write-tree.c: int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix)
prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0;
@@ repository.h: extern struct repository *the_repository;
* Define a custom repository layout. Any field can be NULL, which
## wt-status.c ##
+@@
+ #include "revision.h"
+ #include "diffcore.h"
+ #include "quote.h"
++#include "repository.h"
+ #include "run-command.h"
+ #include "strvec.h"
+ #include "remote.h"
@@ wt-status.c: void wt_status_prepare(struct repository *r, struct wt_status *s)
"HEAD", 0, NULL, NULL);
s->reference = "HEAD";
5: ac27d7128a4 ! 5: 1cc727e4763 environment: make get_graft_file() accept a repository
@@ Commit message
## builtin/replace.c ##
+@@
+ #include "builtin.h"
+ #include "config.h"
+ #include "editor.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "hex.h"
+ #include "refs.h"
@@ builtin/replace.c: static int create_graft(int argc, const char **argv, int force, int gentle)
static int convert_graft_file(int force)
6: 7fc346d3bb5 ! 6: 22e9dcb28a9 environment: make get_git_work_tree() accept a repository
@@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *pr
## builtin/fsmonitor--daemon.c ##
+@@
+ #include "abspath.h"
+ #include "config.h"
+ #include "dir.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "parse-options.h"
+ #include "fsmonitor-ll.h"
@@ builtin/fsmonitor--daemon.c: static int fsmonitor_run_daemon(void)
/* Prepare to (recursively) watch the <worktree-root> directory. */
@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
if (real_git_dir)
## builtin/reset.c ##
+@@
+ #include "object-name.h"
+ #include "parse-options.h"
+ #include "path.h"
++#include "repository.h"
+ #include "unpack-trees.h"
+ #include "cache-tree.h"
+ #include "setup.h"
@@ builtin/reset.c: int cmd_reset(int argc, const char **argv, const char *prefix)
else
trace2_cmd_mode(reset_type_names[reset_type]);
@@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const
BUG("bad untracked_cache value: %d", untracked_cache);
## dir.c ##
+@@
+ #include "object-store-ll.h"
+ #include "path.h"
+ #include "refs.h"
++#include "repository.h"
+ #include "wildmatch.h"
+ #include "pathspec.h"
+ #include "utf8.h"
@@ dir.c: static const char *get_ident_string(void)
return sb.buf;
if (uname(&uts) < 0)
@@ environment.h: extern char *git_work_tree_cfg;
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
## fsmonitor.c ##
+@@
+ #include "fsmonitor.h"
+ #include "fsmonitor-ipc.h"
+ #include "name-hash.h"
++#include "repository.h"
+ #include "run-command.h"
+ #include "strbuf.h"
+ #include "trace2.h"
@@ fsmonitor.c: static int query_fsmonitor_hook(struct repository *r,
strvec_pushf(&cp.args, "%d", version); strvec_pushf(&cp.args, "%s", last_update);
@@ setup.c: static int create_default_files(const char *template_path,
* First copy the templates -- we might have the default
## trace.c ##
+@@
+
+ #include "git-compat-util.h"
+ #include "abspath.h"
+-#include "environment.h"
+ #include "repository.h"
+ #include "quote.h"
+ #include "setup.h"
@@ trace.c: void trace_repo_setup(void)
cwd = xgetcwd();
7: d2f81a540a2 = 7: ec4804a99bf config: document `read_early_config()` and `read_very_early_config()` 8: 85e40696cc9 = 8: b8aa5dcc0b6 config: make dependency on repo in `read_early_config()` explicit 9: 8321454adc8 ! 9: ac2cc4e0371 environment: move `odb_mkstemp()` into object layer
@@ Commit message
## bundle-uri.c ##
+@@
+ #include "bundle-uri.h"
+ #include "bundle.h"
+ #include "copy.h"
+-#include "environment.h"
+ #include "gettext.h"
+ #include "refs.h"
+ #include "run-command.h"
@@
#include "config.h"
#include "fetch-pack.h"
10: 0b3916b2d0d = 10: f0d3794dfc4 environment: make `get_git_namespace()` self-contained
11: c20f6c04dfa ! 11: 9e0e2528b94 environment: move `set_git_dir()` and related into setup layer
@@ environment.h: int have_git_dir(void);
## setup.c ##
@@
-
- #include "git-compat-util.h"
- #include "abspath.h"
-+#include "chdir-notify.h"
-+#include "config.h"
- #include "copy.h"
-+#include "dir.h"
- #include "environment.h"
#include "exec-cmd.h"
-+#include "exec-cmd.h"
#include "gettext.h"
#include "hex.h"
+#include "object-file.h"
#include "object-name.h"
-+#include "path.h"
-+#include "quote.h"
#include "refs.h"
+#include "replace-object.h"
#include "repository.h"
--#include "config.h"
--#include "dir.h"
+ #include "config.h"
+ #include "dir.h"
#include "setup.h"
+#include "shallow.h"
#include "string-list.h"
--#include "chdir-notify.h"
--#include "path.h"
--#include "quote.h"
+#include "strvec.h"
+ #include "chdir-notify.h"
+ #include "path.h"
+ #include "quote.h"
+#include "tmp-objdir.h"
+#include "trace.h"
#include "trace2.h"
#include "worktree.h"
--#include "exec-cmd.h"
-
- static int inside_git_dir = -1;
- static int inside_work_tree = -1;
+ #include "exec-cmd.h"
@@ setup.c: enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
return result;
}
12: a5a78db1697 = 12: 78f77a006a0 environment: reorder header to split out `the_repository`-free section
13: 27a7d00de78 ! 13: 9a3f466b530 environment: guard state depending on a repository
@@ Commit message
Signed-off-by: Patrick Steinhardt <[email protected]>
+ ## compat/mingw.c ##
+@@
++#define USE_THE_REPOSITORY_VARIABLE
++
+ #include "../git-compat-util.h"
+ #include "win32.h"
+ #include <aclapi.h>
+
+ ## compat/win32/path-utils.c ##
+@@
++#define USE_THE_REPOSITORY_VARIABLE
++
+ #include "../../git-compat-util.h"
+ #include "../../environment.h"
+
+
## config.c ##
@@
*
14: b2c11c8e316 = 14: 0d7365c5190 repo-settings: split out declarations into a standalone header
17: d22209121ce = 15: 231c52ce82f repo-settings: track defaults close to `struct repo_settings`
15: f1b6807fae3 = 16: fc30365e1f1 branch: stop modifying `log_all_ref_updates` variable
16: 626e24aac7a ! 17: 9cc8518a02d refs: stop modifying global `log_all_ref_updates` variable@@ Commit message
## builtin/checkout.c ##
+@@
+ #include "read-cache.h"
+ #include "refs.h"
+ #include "remote.h"
++#include "repo-settings.h"
+ #include "resolve-undo.h"
+ #include "revision.h"
+ #include "setup.h"
@@ builtin/checkout.c: static void update_refs_for_switch(const struct checkout_opts *opts,
refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
@@ environment.h: extern int core_apply_sparse_checkout;
enum rebase_setup_type {
## refs.c ##
+@@
+ #include "submodule.h"
+ #include "worktree.h"
+ #include "strvec.h"
+-#include "repository.h"
++#include "repo-settings.h"
+ #include "setup.h"
+ #include "sigchain.h"
+ #include "date.h"
@@ refs.c: static char *normalize_reflog_message(const char *msg)
return strbuf_detach(&sb, NULL);
}
@@ refs.h: int refs_verify_refname_available(struct ref_store *refs,
## refs/files-backend.c ##
+@@
+ #include "../hex.h"
+ #include "../fsck.h"
+ #include "../refs.h"
++#include "../repo-settings.h"
+ #include "refs-internal.h"
+ #include "ref-cache.h"
+ #include "packed-backend.h"
@@ refs/files-backend.c: static int write_ref_to_lockfile(struct files_ref_store *refs,
static int commit_ref_update(struct files_ref_store *refs,
struct ref_lock *lock,
18: b6a9eb981ee = 18: b5ed6928070 environment: stop storing "core.logAllRefUpdates" globally 19: ef312f67f76 = 19: 194d858877f environment: stop storing "core.preferSymlinkRefs" globally 20: f2a28d38e5d ! 20: fc6fcebf7f7 environment: stop storing "core.warnAmbiguousRefs" globally
@@ Commit message
## builtin/rev-parse.c ##
+@@
+ #include "path.h"
+ #include "diff.h"
+ #include "read-cache-ll.h"
++#include "repo-settings.h"
+ #include "repository.h"
+ #include "revision.h"
+ #include "setup.h"
@@ builtin/rev-parse.c: int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (opt_with_value(arg, "--abbrev-ref", &arg)) {
@@ environment.h: extern int has_symlinks;
extern char *apply_default_ignorewhitespace;
## object-name.c ##
+@@
+ #include "pretty.h"
+ #include "object-store-ll.h"
+ #include "read-cache-ll.h"
++#include "repo-settings.h"
+ #include "repository.h"
+ #include "setup.h"
+ #include "midx.h"
@@ object-name.c: static int get_oid_basic(struct repository *r, const char *str, int len,
int fatal = !(flags & GET_OID_QUIETLY);
@@ object-name.c: static int get_oid_basic(struct repository *r, const char *str, i
warning(warn_msg, len, str);
## ref-filter.c ##
+@@
+ #include "object-name.h"
+ #include "object-store-ll.h"
+ #include "oid-array.h"
++#include "repo-settings.h"
+ #include "repository.h"
+ #include "commit.h"
+ #include "mailmap.h"
@@ ref-filter.c: static const char *show_ref(struct refname_atom *atom, const char *refname)
if (atom->option == R_SHORT)
return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
21: ecafe1585f8 = 21: a0b75c4bc99 environment: stop storing "core.notesRef" globally
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 1/21 environment: make `get_git_dir()` accept a repository
The get_git_dir() function retrieves the path to the Git directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- apply.c | 3 ++- builtin/am.c | 5 +++-- builtin/commit.c | 7 ++++--- builtin/config.c | 2 +- builtin/difftool.c | 5 +++-- builtin/fsmonitor--daemon.c | 3 ++- builtin/merge.c | 4 +++- builtin/stash.c | 3 ++- cache-tree.c | 5 +++-- config.c | 4 +++- environment.c | 10 ++-------- environment.h | 1 - pathspec.c | 2 +- read-cache.c | 6 ++++-- repository.c | 7 +++++++ repository.h | 2 ++ setup.c | 12 ++++++------ setup.h | 2 +- trace.c | 5 ++++- transport-helper.c | 2 +- worktree.c | 4 ++-- 21 files changed, 56 insertions(+), 38 deletions(-)
apply.c +2 -1
@@ -30,6 +30,7 @@#include "path.h" #include "quote.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "apply.h" #include "entry.h"
@@ -4111,7 +4112,7 @@ static int read_apply_cache(struct apply_state *state) {if (state->index_file)return read_index_from (state->repo->index, state->index_file, -get_git_dir ()); +repo_get_git_dir (the_repository));else return repo_read_index (state->repo); }
builtin/am.c +3 -2
@@ -1544,7 +1544,8 @@ static int run_apply(const struct am_state *state, const char *index_file)if (index_file) {/* Reload index as apply_all_patches() will have modified it. */ discard_index (the_repository->index); -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository)); }return 0 ;
@@ -1587,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pareturn error ("could not build fake ancestor" );discard_index (the_repository->index); -read_index_from (the_repository->index, index_path,get_git_dir ()); +read_index_from (the_repository->index, index_path,repo_get_git_dir (the_repository));if (write_index_as_tree (&bases[0 ], the_repository->index, index_path,0 ,NULL ))return error (_ ("Repository lacks necessary blobs to fall back on 3-way merge." ));
builtin/commit.c +4 -3
@@ -26,6 +26,7 @@#include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "string-list.h" #include "rerere.h" #include "unpack-trees.h"
@@ -407,7 +408,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index);read_index_from (the_repository->index,get_lock_file_path (&index_lock), -get_git_dir ()); +repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,WRITE_TREE_SILENT ) ==0 ) {if (reopen_lock_file (&index_lock) <0 )die (_ ("unable to write index file" ));
@@ -534,7 +535,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index); ret =get_lock_file_path (&false_lock); -read_index_from (the_repository->index, ret,get_git_dir ()); +read_index_from (the_repository->index, ret,repo_get_git_dir (the_repository)); out:string_list_clear (&partial,0 );clear_pathspec (&pathspec);
@@ -1072,7 +1073,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,*/ discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file,repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,0 )) {error (_ ("Error building trees" ));
builtin/config.c +1 -1
@@ -808,7 +808,7 @@ static void location_options_init(struct config_location_options *opts, opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { opts->options.commondir =get_git_common_dir (); - opts->options.git_dir =get_git_dir (); + opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/difftool.c +3 -2
@@ -22,6 +22,7 @@#include "hex.h" #include "parse-options.h" #include "read-cache-ll.h" +#include "repository.h" #include "sparse-index.h" #include "strvec.h" #include "strbuf.h"
@@ -214,7 +215,7 @@ static void changed_files(struct hashmap *result, const char *index_path,struct child_process update_index =CHILD_PROCESS_INIT ;struct child_process diff_files =CHILD_PROCESS_INIT ;struct strbuf buf =STRBUF_INIT ; -const char *git_dir =absolute_path (get_git_dir ()); +const char *git_dir =absolute_path (repo_get_git_dir (the_repository));FILE *fp; strvec_pushl(&update_index.args,
@@ -737,7 +738,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree (); -setenv (GIT_DIR_ENVIRONMENT ,absolute_path (get_git_dir ()),1 ); +setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 );setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -1
@@ -1311,7 +1311,8 @@ static int fsmonitor_run_daemon(void)strbuf_addstr (&state.path_gitdir_watch,"/.git" );if (!is_directory (state.path_gitdir_watch.buf)) {strbuf_reset (&state.path_gitdir_watch); -strbuf_addstr (&state.path_gitdir_watch,absolute_path (get_git_dir ())); +strbuf_addstr (&state.path_gitdir_watch, +absolute_path (repo_get_git_dir (the_repository))); state.nr_paths_watching =2 ; }
builtin/merge.c +3 -1
@@ -17,6 +17,7 @@#include "object-name.h" #include "parse-options.h" #include "lockfile.h" +#include "repository.h" #include "run-command.h" #include "hook.h" #include "diff.h"
@@ -855,7 +856,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)if (invoked_hook)discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository));strbuf_addbuf (&msg, &merge_msg);if (squash)BUG ("the control must not reach here under --squash" );
builtin/stash.c +2 -1
@@ -19,6 +19,7 @@#include "entry.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "revision.h" #include "setup.h"
@@ -642,7 +643,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" ,absolute_path (get_git_work_tree ()));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" , -absolute_path (get_git_dir ())); +absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );run_command (&cp); }
cache-tree.c +3 -2
@@ -1,7 +1,6 @@#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "environment.h" #include "hex.h" #include "lockfile.h" #include "tree.h"
@@ -12,6 +11,7 @@#include "object-store-ll.h" #include "read-cache-ll.h" #include "replace-object.h" +#include "repository.h" #include "promisor-remote.h" #include "trace.h" #include "trace2.h"
@@ -725,7 +725,8 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,hold_lock_file_for_update (&lock_file, index_path,LOCK_DIE_ON_ERROR ); - entries =read_index_from (index_state, index_path,get_git_dir ()); + entries =read_index_from (index_state, index_path, +repo_get_git_dir (the_repository));if (entries <0 ) { ret =WRITE_TREE_UNREADABLE_INDEX ; goto out;
config.c +3 -1
@@ -6,6 +6,8 @@* */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2212,7 +2214,7 @@ void read_early_config(config_fn_t cb, void *data)if (have_git_dir ()) { opts.commondir =get_git_common_dir (); - opts.git_dir =get_git_dir (); + opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
environment.c +2 -8
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_dir (void ) -{ -if (!the_repository->gitdir) -BUG ("git environment hasn't been setup" ); -return the_repository->gitdir; -} -const char *get_git_common_dir (void ) {if (!the_repository->commondir)
@@ -352,7 +345,8 @@ static void update_relative_gitdir(const char *name UNUSED,const char *new_cwd, void *data UNUSED) { - char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); + char *path = reparent_relative_path(old_cwd, new_cwd, +repo_get_git_dir (the_repository));struct tmp_objdir *tmp_objdir =tmp_objdir_unapply_primary_odb (); trace_printf_key(&trace_setup_key,
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_dir (void );const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );
pathspec.c +1 -1
@@ -497,7 +497,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, copyfrom); hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("%s: '%s' is outside repository at '%s'" ), elt, copyfrom,absolute_path (hint_path)); }
read-cache.c +4 -2
@@ -31,6 +31,7 @@#include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "resolve-undo.h" #include "revision.h" #include "strbuf.h"
@@ -3238,10 +3239,11 @@ static int should_delete_shared_index(const char *shared_index_path)static int clean_shared_index_files (const char *current_hex) {struct dirent *de; -DIR *dir =opendir (get_git_dir ()); +DIR *dir =opendir (repo_get_git_dir (the_repository));if (!dir) -return error_errno (_ ("unable to open git dir: %s" ),get_git_dir ()); +return error_errno (_ ("unable to open git dir: %s" ), +repo_get_git_dir (the_repository));while ((de =readdir (dir)) !=NULL ) {const char *sha1_hex;
repository.c +7 -0
@@ -91,6 +91,13 @@ static void expand_base_dir(char **out, const char *in, *out =xstrfmt ("%s/%s" , base_dir, def_in); } +const char *repo_get_git_dir (struct repository *repo) +{ +if (!repo->gitdir) +BUG ("git environment hasn't been setup" ); +return repo->gitdir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +2 -0
@@ -206,6 +206,8 @@ struct repository {extern struct repository *the_repository;#endif +const char *repo_get_git_dir (struct repository *repo); +/* * Define a custom repository layout. Any field can be NULL, which * will default back to the path according to the default layout.
setup.c +6 -6
@@ -149,7 +149,7 @@ char *prefix_path(const char *prefix, int len, const char *path)if (!r) {const char *hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("'%s' is outside repository at '%s'" ), path,absolute_path (hint_path)); }
@@ -468,7 +468,7 @@ int is_nonbare_repository_dir(struct strbuf *path)int is_inside_git_dir (void ) {if (inside_git_dir <0 ) - inside_git_dir =is_inside_dir (get_git_dir ()); + inside_git_dir =is_inside_dir (repo_get_git_dir (the_repository));return inside_git_dir; }
@@ -1836,7 +1836,7 @@ void check_repository_format(struct repository_format *fmt)struct repository_format repo_fmt =REPOSITORY_FORMAT_INIT ;if (!fmt) fmt = &repo_fmt; -check_repository_format_gently (get_git_dir (), fmt,NULL ); +check_repository_format_gently (repo_get_git_dir (the_repository), fmt,NULL ); startup_info->have_repository =1 ;repo_set_hash_algo (the_repository, fmt->hash_algo);repo_set_compat_hash_algo (the_repository, fmt->compat_hash_algo);
@@ -2224,7 +2224,7 @@ static int create_default_files(const char *template_path,* shared-repository settings, we would need to fix them up. */ if (get_shared_repository ()) { -adjust_shared_perm (get_git_dir ()); +adjust_shared_perm (repo_get_git_dir (the_repository)); }initialize_repository_version (fmt->hash_algo, fmt->ref_storage_format,0 );
@@ -2434,12 +2434,12 @@ int init_db(const char *git_dir, const char *real_git_dir,die (_ ("%s already exists" ), real_git_dir);set_git_dir (real_git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository);separate_git_dir (git_dir, original_git_dir); }else {set_git_dir (git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository); } startup_info->have_repository =1 ;
setup.h +1 -1
@@ -176,7 +176,7 @@ 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(), +* Check the repository format version in the path found in repo_get_git_dir(the_repository), * 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?".
trace.c +4 -1
@@ -21,9 +21,12 @@* along with this program; if not, see <https://www.gnu.org/licenses/>. */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "environment.h" +#include "repository.h" #include "quote.h" #include "setup.h" #include "trace.h"
@@ -311,7 +314,7 @@ void trace_repo_setup(void)if (!startup_info->prefix) prefix ="(null)" ; -trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (get_git_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ()));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));
transport-helper.c +1 -1
@@ -143,7 +143,7 @@ static struct child_process *get_helper(struct transport *transport)if (have_git_dir ())strvec_pushf (&helper->env,"%s=%s" , -GIT_DIR_ENVIRONMENT ,get_git_dir ()); +GIT_DIR_ENVIRONMENT ,repo_get_git_dir (the_repository)); helper->trace2_child_class = helper->args.v[0 ];/* "remote-<name>" */
worktree.c +2 -2
@@ -57,7 +57,7 @@ static void add_head_info(struct worktree *wt)static int is_current_worktree (struct worktree *wt) { -char *git_dir =absolute_pathdup (get_git_dir ()); +char *git_dir =absolute_pathdup (repo_get_git_dir (the_repository));const char *wt_git_dir =get_worktree_git_dir (wt);int is_current = !fspathcmp (git_dir,absolute_path (wt_git_dir));free (git_dir);
@@ -171,7 +171,7 @@ struct worktree **get_worktrees(void)const char *get_worktree_git_dir (const struct worktree *wt) {if (!wt) -return get_git_dir (); +return repo_get_git_dir (the_repository);else if (!wt->id)return get_git_common_dir ();else
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 2/21 environment: make `get_git_common_dir()` accept a repository
In reply to Patrick SteinhardtThe get_git_common_dir() function retrieves the path to the common directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/config.c | 2 +- builtin/gc.c | 2 +- builtin/rev-parse.c | 3 ++- builtin/worktree.c | 4 ++-- config.c | 2 +- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + setup.c | 2 +- submodule.c | 2 +- trace.c | 2 +- worktree.c | 8 ++++---- 13 files changed, 22 insertions(+), 21 deletions(-)
builtin/config.c +1 -1
@@ -807,7 +807,7 @@ static void location_options_init(struct config_location_options *opts,else opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { - opts->options.commondir =get_git_common_dir (); + opts->options.commondir =repo_get_common_dir (the_repository); opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/gc.c +1 -1
@@ -2132,7 +2132,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priorityget_schedule_cmd (&cmd,NULL );strbuf_addf (&tfilename,"%s/schedule_%s_XXXXXX" , -get_git_common_dir (), frequency); +repo_get_common_dir (the_repository), frequency); tfile =xmks_tempfile (tfilename.buf);strbuf_release (&tfilename);
builtin/rev-parse.c +2 -1
@@ -19,6 +19,7 @@#include "path.h" #include "diff.h" #include "read-cache-ll.h" +#include "repository.h" #include "revision.h" #include "setup.h" #include "split-index.h"
@@ -1042,7 +1043,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--git-common-dir" )) { -print_path (get_git_common_dir (), prefix, format,DEFAULT_RELATIVE_IF_SHARED ); +print_path (repo_get_common_dir (the_repository), prefix, format,DEFAULT_RELATIVE_IF_SHARED );continue ; }if (!strcmp (arg,"--is-inside-git-dir" )) {
builtin/worktree.c +2 -2
@@ -219,7 +219,7 @@ static void prune_worktrees(void) }closedir (dir); -strbuf_add_absolute_path (&main_path,get_git_common_dir ()); +strbuf_add_absolute_path (&main_path,repo_get_common_dir (the_repository));/* massage main worktree absolute path to match 'gitdir' content */ strbuf_strip_suffix (&main_path,"/." );string_list_append_nodup (&kept,strbuf_detach (&main_path,NULL ));
@@ -492,7 +492,7 @@ static int add_worktree(const char *path, const char *refname,strbuf_addf (&sb,"%s/gitdir" , sb_repo.buf);strbuf_realpath (&realpath, sb_git.buf,1 );write_file (sb.buf,"%s" , realpath.buf); -strbuf_realpath (&realpath,get_git_common_dir (),1 ); +strbuf_realpath (&realpath,repo_get_common_dir (the_repository),1 );write_file (sb_git.buf,"gitdir: %s/worktrees/%s" , realpath.buf, name);strbuf_reset (&sb);
config.c +1 -1
@@ -2213,7 +2213,7 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ;if (have_git_dir ()) { - opts.commondir =get_git_common_dir (); + opts.commondir =repo_get_common_dir (the_repository); opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the
environment.c +0 -7
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_common_dir (void ) -{ -if (!the_repository->commondir) -BUG ("git environment hasn't been setup" ); -return the_repository->commondir; -} -const char *get_git_namespace (void ) {if (!git_namespace)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);
repository.c +7 -0
@@ -98,6 +98,13 @@ const char *repo_get_git_dir(struct repository *repo)return repo->gitdir; } +const char *repo_get_common_dir (struct repository *repo) +{ +if (!repo->commondir) +BUG ("git environment hasn't been setup" ); +return repo->commondir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -207,6 +207,7 @@ extern struct repository *the_repository;#endif const char *repo_get_git_dir (struct repository *repo); +const char *repo_get_common_dir (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +1 -1
@@ -2068,7 +2068,7 @@ static void copy_templates(const char *option_template) goto close_free_return; } -strbuf_addstr (&path,get_git_common_dir ()); +strbuf_addstr (&path,repo_get_common_dir (the_repository));strbuf_complete (&path,'/' );copy_templates_1 (&path, &template_path, dir); close_free_return:
submodule.c +1 -1
@@ -2462,7 +2462,7 @@ void absorb_git_dir_into_superproject(const char *path, }else {/* Is it already absorbed into the superprojects git dir? */ char *real_sub_git_dir =real_pathdup (sub_git_dir,1 ); -char *real_common_git_dir =real_pathdup (get_git_common_dir (),1 ); +char *real_common_git_dir =real_pathdup (repo_get_common_dir (the_repository),1 );if (!starts_with (real_sub_git_dir, real_common_git_dir))relocate_single_git_dir_into_superproject (path, super_prefix);
trace.c +1 -1
@@ -315,7 +315,7 @@ void trace_repo_setup(void) prefix ="(null)" ;trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository))); -trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (repo_get_common_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));trace_printf_key (&trace_setup_key,"setup: prefix: %s\n" ,quote_crnl (prefix));
worktree.c +4 -4
@@ -72,7 +72,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)struct worktree *worktree =NULL ;struct strbuf worktree_path =STRBUF_INIT ; -strbuf_add_real_path (&worktree_path,get_git_common_dir ()); +strbuf_add_real_path (&worktree_path,repo_get_common_dir (the_repository));strbuf_strip_suffix (&worktree_path,"/.git" );CALLOC_ARRAY (worktree,1 );
@@ -143,7 +143,7 @@ static struct worktree **get_worktrees_internal(int skip_reading_head) list[counter++] =get_main_worktree (skip_reading_head); -strbuf_addf (&path,"%s/worktrees" ,get_git_common_dir ()); +strbuf_addf (&path,"%s/worktrees" ,repo_get_common_dir (the_repository)); dir =opendir (path.buf);strbuf_release (&path);if (dir) {
@@ -173,7 +173,7 @@ const char *get_worktree_git_dir(const struct worktree *wt)if (!wt)return repo_get_git_dir (the_repository);else if (!wt->id) -return get_git_common_dir (); +return repo_get_common_dir (the_repository);else return git_common_path ("worktrees/%s" , wt->id); }
@@ -626,7 +626,7 @@ static int is_main_worktree_path(const char *path)strbuf_add_real_path (&target, path);strbuf_strip_suffix (&target,"/.git" ); -strbuf_add_real_path (&maindir,get_git_common_dir ()); +strbuf_add_real_path (&maindir,repo_get_common_dir (the_repository));strbuf_strip_suffix (&maindir,"/.git" ); cmp =fspathcmp (maindir.buf, target.buf);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 3/21 environment: make `get_object_directory()` accept a repository
In reply to Patrick SteinhardtThe get_object_directory() function retrieves the path to the object directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/commit-graph.c | 5 ++--- builtin/count-objects.c | 3 +-- builtin/multi-pack-index.c | 4 ++-- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 ++++---- builtin/repack.c | 7 ++++--- bulk-checkin.c | 4 ++-- environment.c | 7 ------- environment.h | 1 - fetch-pack.c | 2 +- http-backend.c | 2 +- object-file.c | 4 ++-- pack-write.c | 3 ++- packfile.c | 2 +- prune-packed.c | 6 ++++-- repository.c | 7 +++++++ repository.h | 1 + server-info.c | 4 ++-- setup.c | 2 +- tmp-objdir.c | 8 +++++--- 20 files changed, 43 insertions(+), 39 deletions(-)
builtin/commit-graph.c +2 -3
@@ -1,7 +1,6 @@#include "builtin.h" #include "commit.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h"
@@ -95,7 +94,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)usage_with_options (builtin_commit_graph_verify_usage, options);if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.shallow) flags |=COMMIT_GRAPH_VERIFY_SHALLOW ;if (opts.progress)
@@ -275,7 +274,7 @@ static int graph_write(int argc, const char **argv, const char *prefix)if (opts.reachable + opts.stdin_packs + opts.stdin_commits >1 )die (_ ("use at most one of --reachable, --stdin-commits, or --stdin-packs" ));if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.append) flags |=COMMIT_GRAPH_WRITE_APPEND ;if (opts.split)
builtin/count-objects.c +1 -2
@@ -7,7 +7,6 @@#include "builtin.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "path.h" #include "repository.h"
@@ -116,7 +115,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)report_linked_checkout_garbage (the_repository); } -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), count_loose, count_cruft,NULL ,NULL );if (verbose) {
builtin/multi-pack-index.c +2 -2
@@ -1,7 +1,6 @@#include "builtin.h" #include "abspath.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h"
@@ -9,6 +8,7 @@#include "trace2.h" #include "object-store-ll.h" #include "replace-object.h" +#include "repository.h" #define BUILTIN_MIDX_WRITE_USAGE \ N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \
@@ -63,7 +63,7 @@ static int parse_object_dir(const struct option *opt, const char *arg,char **value = opt->value;free (*value);if (unset) - *value =xstrdup (get_object_directory ()); + *value =xstrdup (repo_get_object_directory (the_repository));else *value =real_pathdup (arg,1 );return 0 ;
builtin/pack-objects.c +1 -1
@@ -3940,7 +3940,7 @@ static int add_loose_object(const struct object_id *oid, const char *path,*/ static void add_unreachable_loose_objects (void ) { -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), add_loose_object,NULL ,NULL ,NULL ); }
builtin/prune.c +4 -4
@@ -193,12 +193,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix) revs.exclude_promisor_objects =1 ; } -for_each_loose_file_in_objdir (get_object_directory (), prune_object, - prune_cruft, prune_subdir, &revs); +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), + prune_object, prune_cruft, prune_subdir, &revs);prune_packed_objects (show_only ?PRUNE_PACKED_DRY_RUN :0 ); -remove_temporary_files (get_object_directory ()); - s =mkpathdup ("%s/pack" ,get_object_directory ()); +remove_temporary_files (repo_get_object_directory (the_repository)); + s =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository));remove_temporary_files (s);free (s);
builtin/repack.c +4 -3
@@ -1240,7 +1240,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)if (write_midx && write_bitmaps) {struct strbuf path =STRBUF_INIT ; -strbuf_addf (&path,"%s/%s_XXXXXX" ,get_object_directory (), +strbuf_addf (&path,"%s/%s_XXXXXX" ,repo_get_object_directory (the_repository),"bitmap-ref-tips" ); refs_snapshot =xmks_tempfile (path.buf);
@@ -1249,7 +1249,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)strbuf_release (&path); } - packdir =mkpathdup ("%s/pack" ,get_object_directory ()); + packdir =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository)); packtmp_name =xstrfmt (".tmp-%d-pack" , (int )getpid ()); packtmp =mkpathdup ("%s/%s" , packdir, packtmp_name);
@@ -1519,7 +1519,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)unsigned flags =0 ;if (git_env_bool (GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL ,0 )) flags |=MIDX_WRITE_INCREMENTAL ; -write_midx_file (get_object_directory (),NULL ,NULL , flags); +write_midx_file (repo_get_object_directory (the_repository), +NULL ,NULL , flags); } cleanup:
bulk-checkin.c +2 -2
@@ -75,7 +75,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)close (fd); } -strbuf_addf (&packname,"%s/pack/pack-%s." ,get_object_directory (), +strbuf_addf (&packname,"%s/pack/pack-%s." ,repo_get_object_directory (the_repository),hash_to_hex (hash)); finish_tmp_packfile(&packname, state->pack_tmp_name, state->written, state->nr_written,
@@ -113,7 +113,7 @@ static void flush_batch_fsync(void)* to ensure that the data in each new object file is durable before * the final name is visible. */ -strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,get_object_directory ()); +strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,repo_get_object_directory (the_repository)); temp =xmks_tempfile (temp_path.buf);fsync_or_die (get_tempfile_fd (temp),get_tempfile_path (temp));delete_tempfile (&temp);
environment.c +0 -7
@@ -273,13 +273,6 @@ const char *get_git_work_tree(void)return the_repository->worktree; } -const char *get_object_directory (void ) -{ -if (!the_repository->objects->odb) -BUG ("git environment hasn't been setup" ); -return the_repository->objects->odb->path; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);
fetch-pack.c +1 -1
@@ -1839,7 +1839,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,string_list_append_nodup (pack_lockfiles,xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), +repo_get_object_directory (the_repository), packname)); }string_list_clear (&packfile_uris,0 );
http-backend.c +1 -1
@@ -601,7 +601,7 @@ static void get_head(struct strbuf *hdr, char *arg UNUSED) static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { -size_t objdirlen =strlen (get_object_directory ()); +size_t objdirlen =strlen (repo_get_object_directory (the_repository));struct strbuf buf =STRBUF_INIT ;struct packed_git *p;size_t cnt =0 ;
object-file.c +2 -2
@@ -2053,7 +2053,7 @@ static int start_loose_object_common(struct strbuf *tmp_file,else if (errno ==EACCES )return error (_ ("insufficient permission for adding " "an object to repository database %s" ), -get_object_directory ()); +repo_get_object_directory (the_repository));else return error_errno (_ ("unable to create temporary file" ));
@@ -2228,7 +2228,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,prepare_loose_object_bulk_checkin ();/* Since oid is not determined, save tmp file to odb path. */ -strbuf_addf (&filename,"%s/" ,get_object_directory ()); +strbuf_addf (&filename,"%s/" ,repo_get_object_directory (the_repository)); hdrlen =format_object_header (hdr,sizeof (hdr),OBJ_BLOB , len);/*
pack-write.c +2 -1
@@ -12,6 +12,7 @@#include "pack-objects.h" #include "pack-revindex.h" #include "path.h" +#include "repository.h" #include "strbuf.h" void reset_pack_idx_option (struct pack_idx_option *opts)
@@ -473,7 +474,7 @@ char *index_pack_lockfile(int ip_out, int *is_well_formed) packname[len-1 ] =0 ;if (skip_prefix (packname,"keep\t" , &name))return xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), name); +repo_get_object_directory (the_repository), name);return NULL ; }if (is_well_formed)
packfile.c +1 -1
@@ -30,7 +30,7 @@ char *odb_pack_name(struct strbuf *buf, const char *ext) {strbuf_reset (buf); -strbuf_addf (buf,"%s/pack/pack-%s.%s" ,get_object_directory (), +strbuf_addf (buf,"%s/pack/pack-%s.%s" ,repo_get_object_directory (the_repository),hash_to_hex (hash), ext);return buf->buf; }
prune-packed.c +4 -2
@@ -1,10 +1,12 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" -#include "environment.h" #include "gettext.h" #include "object-store-ll.h" #include "packfile.h" #include "progress.h" #include "prune-packed.h" +#include "repository.h" static struct progress *progress;
@@ -37,7 +39,7 @@ void prune_packed_objects(int opts)if (opts &PRUNE_PACKED_VERBOSE ) progress =start_delayed_progress (_ ("Removing duplicate objects" ),256 ); -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), prune_object,NULL , prune_subdir, &opts);/* Ensure we show 100% before finishing progress */
repository.c +7 -0
@@ -105,6 +105,13 @@ const char *repo_get_common_dir(struct repository *repo)return repo->commondir; } +const char *repo_get_object_directory (struct repository *repo) +{ +if (!repo->objects->odb) +BUG ("git environment hasn't been setup" ); +return repo->objects->odb->path; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -208,6 +208,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo); +const char *repo_get_object_directory (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
server-info.c +2 -2
@@ -2,7 +2,6 @@#include "git-compat-util.h" #include "dir.h" -#include "environment.h" #include "hex.h" #include "repository.h" #include "refs.h"
@@ -342,7 +341,8 @@ static int write_pack_info_file(struct update_info_ctx *uic)static int update_info_packs (int force) { -char *infofile =mkpathdup ("%s/info/packs" ,get_object_directory ()); +char *infofile =mkpathdup ("%s/info/packs" , +repo_get_object_directory (the_repository));int ret;init_pack_info (infofile, force);
setup.c +1 -1
@@ -2282,7 +2282,7 @@ static void create_object_directory(void)struct strbuf path =STRBUF_INIT ;size_t baselen; -strbuf_addstr (&path,get_object_directory ()); +strbuf_addstr (&path,repo_get_object_directory (the_repository)); baselen = path.len;safe_create_dir (path.buf,1 );
tmp-objdir.c +5 -3
@@ -13,6 +13,7 @@#include "strvec.h" #include "quote.h" #include "object-store-ll.h" +#include "repository.h" struct tmp_objdir {struct strbuf path;
@@ -132,7 +133,8 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix)* can recognize any stale objdirs left behind by a crash and delete * them. */ -strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" ,get_object_directory (), prefix); +strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" , +repo_get_object_directory (the_repository), prefix);if (!mkdtemp (t->path.buf)) {/* free, not destroy, as we never touched the filesystem */
@@ -152,7 +154,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) }env_append (&t->env,ALTERNATE_DB_ENVIRONMENT , -absolute_path (get_object_directory ())); +absolute_path (repo_get_object_directory (the_repository)));env_replace (&t->env,DB_ENVIRONMENT ,absolute_path (t->path.buf));env_replace (&t->env,GIT_QUARANTINE_ENVIRONMENT ,absolute_path (t->path.buf));
@@ -267,7 +269,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t) }strbuf_addbuf (&src, &t->path); -strbuf_addstr (&dst,get_object_directory ()); +strbuf_addstr (&dst,repo_get_object_directory (the_repository)); ret =migrate_paths (&src, &dst);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 4/21 environment: make `get_index_file()` accept a repository
In reply to Patrick SteinhardtThe get_index_file() function retrieves the path to the index file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/am.c | 8 ++++++-- builtin/commit.c | 6 +++--- builtin/merge.c | 14 ++++++++------ builtin/stash.c | 12 ++++++------ builtin/update-index.c | 2 +- builtin/write-tree.c | 4 ++-- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + wt-status.c | 3 ++- 11 files changed, 36 insertions(+), 29 deletions(-)
builtin/am.c +6 -2
@@ -1668,7 +1668,9 @@ static void do_commit(const struct am_state *state)if (!state->no_verify &&run_hooks (the_repository,"pre-applypatch" ))exit (1 ); -if (write_index_as_tree (&tree, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&tree, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" ));if (!repo_get_oid_commit (the_repository,"HEAD" , &parent)) {
@@ -2078,7 +2080,9 @@ static int clean_index(const struct object_id *head, const struct object_id *remif (fast_forward_to (head_tree, head_tree,1 ))return -1 ; -if (write_index_as_tree (&index, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&index, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))return -1 ; index_tree =parse_tree_indirect (&index);
builtin/commit.c +3 -3
@@ -473,7 +473,7 @@ static const char *prepare_index(const char **argv, const char *prefix, COMMIT_LOCK | SKIP_IF_UNCHANGED))die (_ ("unable to write new index file" )); commit_style =COMMIT_AS_IS ; - ret =get_index_file (); + ret =repo_get_index_file (the_repository); goto out; }
@@ -1874,8 +1874,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)repo_rerere (the_repository,0 );run_auto_maintenance (quiet); -run_commit_hook (use_editor,get_index_file (),NULL ,"post-commit" , -NULL ); +run_commit_hook (use_editor,repo_get_index_file (the_repository), +NULL ,"post-commit" ,NULL );if (amend && !no_post_rewrite) {commit_post_rewrite (the_repository, current_head, &oid); }
builtin/merge.c +8 -6
@@ -696,7 +696,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,static void write_tree_trivial (struct object_id *oid) { -if (write_index_as_tree (oid, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (oid, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" )); }
@@ -758,7 +760,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, }if (write_locked_index (the_repository->index, &lock,COMMIT_LOCK |SKIP_IF_UNCHANGED )) -die (_ ("unable to write %s" ),get_index_file ()); +die (_ ("unable to write %s" ),repo_get_index_file (the_repository));return clean ?0 :1 ; }else { return try_merge_command(the_repository,
@@ -840,7 +842,7 @@ static void write_merge_heads(struct commit_list *);static void prepare_to_commit (struct commit_list *remoteheads) {struct strbuf msg =STRBUF_INIT ; -const char *index_file =get_index_file (); +const char *index_file =repo_get_index_file (the_repository);if (!no_verify) {int invoked_hook;
@@ -880,8 +882,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)append_signoff (&msg,ignored_log_message_bytes (msg.buf, msg.len),0 );write_merge_heads (remoteheads);write_file_buf (git_path_merge_msg (the_repository), msg.buf, msg.len); -if (run_commit_hook (0 < option_edit,get_index_file (),NULL , -"prepare-commit-msg" , +if (run_commit_hook (0 < option_edit,repo_get_index_file (the_repository), +NULL ,"prepare-commit-msg" ,git_path_merge_msg (the_repository),"merge" ,NULL ))abort_commit (remoteheads,NULL );if (0 < option_edit) {
@@ -889,7 +891,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)abort_commit (remoteheads,NULL ); } -if (!no_verify &&run_commit_hook (0 < option_edit,get_index_file (), +if (!no_verify &&run_commit_hook (0 < option_edit,repo_get_index_file (the_repository),NULL ,"commit-msg" ,git_path_merge_msg (the_repository),NULL ))abort_commit (remoteheads,NULL );
builtin/stash.c +6 -6
@@ -540,8 +540,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, NULL, NULL, NULL))return error (_ ("could not write index" )); -if (write_index_as_tree (&c_tree, the_repository->index,get_index_file (),0 , -NULL )) +if (write_index_as_tree (&c_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("cannot apply a stash in the middle of a merge" ));if (index) {
@@ -566,7 +566,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,discard_index (the_repository->index);repo_read_index (the_repository);if (write_index_as_tree (&index_tree, the_repository->index, -get_index_file (),0 ,NULL )) +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("could not save index tree" ));reset_head ();
@@ -1406,8 +1406,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_bstrbuf_addf (&commit_tree_label,"index on %s\n" , msg.buf);commit_list_insert (head_commit, &parents); -if (write_index_as_tree (&info->i_tree, the_repository->index,get_index_file (),0 , -NULL ) || +if (write_index_as_tree (&info->i_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ) ||commit_tree (commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit,NULL ,NULL )) {if (!quiet)
@@ -1905,7 +1905,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - index_file =get_index_file (); + index_file =repo_get_index_file (the_repository);strbuf_addf (&stash_index_path,"%s.stash.%" PRIuMAX, index_file, (uintmax_t )pid);
builtin/update-index.c +1 -1
@@ -1239,7 +1239,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)if (newfd <0 ) {if (refresh_args.flags &REFRESH_QUIET )exit (128 ); -unable_to_lock_die (get_index_file (), lock_error); +unable_to_lock_die (repo_get_index_file (the_repository), lock_error); }if (write_locked_index (the_repository->index, &lock_file,COMMIT_LOCK ))die ("Unable to write new index file" );
builtin/write-tree.c +2 -2
@@ -6,7 +6,6 @@#include "builtin.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h"
@@ -44,7 +43,8 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - ret =write_index_as_tree (&oid, the_repository->index,get_index_file (), + ret =write_index_as_tree (&oid, the_repository->index, +repo_get_index_file (the_repository), flags, tree_prefix);switch (ret) {case 0 :
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_index_file (void ) -{ -if (!the_repository->index_file) -BUG ("git environment hasn't been setup" ); -return the_repository->index_file; -} -char *get_graft_file (struct repository *r) {if (!r->graft_file)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );
repository.c +7 -0
@@ -112,6 +112,13 @@ const char *repo_get_object_directory(struct repository *repo)return repo->objects->odb->path; } +const char *repo_get_index_file (struct repository *repo) +{ +if (!repo->index_file) +BUG ("git environment hasn't been setup" ); +return repo->index_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -209,6 +209,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo); +const char *repo_get_index_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
wt-status.c +2 -1
@@ -16,6 +16,7 @@#include "revision.h" #include "diffcore.h" #include "quote.h" +#include "repository.h" #include "run-command.h" #include "strvec.h" #include "remote.h"
@@ -152,7 +153,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) "HEAD", 0, NULL, NULL); s->reference ="HEAD" ; s->fp = stdout; - s->index_file =get_index_file (); + s->index_file =repo_get_index_file (the_repository); s->change.strdup_strings =1 ; s->untracked.strdup_strings =1 ; s->ignored.strdup_strings =1 ;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 5/21 environment: make `get_graft_file()` accept a repository
In reply to Patrick SteinhardtThe get_graft_file() function retrieves the path to the graft file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/replace.c | 3 +-- commit.c | 4 ++-- environment.c | 7 ------- environment.h | 2 -- repository.c | 7 +++++++ repository.h | 1 + 6 files changed, 11 insertions(+), 13 deletions(-)
builtin/replace.c +1 -2
@@ -11,7 +11,6 @@#include "builtin.h" #include "config.h" #include "editor.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h"
@@ -514,7 +513,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)static int convert_graft_file (int force) { -const char *graft_file =get_graft_file (the_repository); +const char *graft_file =repo_get_graft_file (the_repository);FILE *fp =fopen_or_warn (graft_file,"r" );struct strbuf buf =STRBUF_INIT , err =STRBUF_INIT ;struct strvec args =STRVEC_INIT ;
commit.c +2 -2
@@ -292,14 +292,14 @@ static int read_graft_file(struct repository *r, const char *graft_file)void prepare_commit_graft (struct repository *r) { -char *graft_file; +const char *graft_file;if (r->parsed_objects->commit_graft_prepared)return ;if (!startup_info->have_repository)return ; - graft_file =get_graft_file (r); + graft_file =repo_get_graft_file (r);read_graft_file (r, graft_file);/* make sure shallows are read */ is_repository_shallow (r);
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_graft_file (struct repository *r) -{ -if (!r->graft_file) -BUG ("git environment hasn't been setup" ); -return r->graft_file; -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -2
@@ -1,7 +1,6 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct repository ;struct strvec ;/*
@@ -106,7 +105,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref);
repository.c +7 -0
@@ -119,6 +119,13 @@ const char *repo_get_index_file(struct repository *repo)return repo->index_file; } +const char *repo_get_graft_file (struct repository *repo) +{ +if (!repo->graft_file) +BUG ("git environment hasn't been setup" ); +return repo->graft_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -210,6 +210,7 @@ const char *repo_get_git_dir(struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo); +const char *repo_get_graft_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 6/21 environment: make `get_git_work_tree()` accept a repository
In reply to Patrick SteinhardtThe get_git_work_tree() function retrieves the path of the work tree of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/blame.c | 2 +- builtin/difftool.c | 4 ++-- builtin/fsmonitor--daemon.c | 4 ++-- builtin/init-db.c | 4 ++-- builtin/reset.c | 5 +++-- builtin/rev-parse.c | 4 ++-- builtin/stash.c | 2 +- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 2 +- dir.c | 3 ++- environment.c | 7 +------ environment.h | 1 - fsmonitor.c | 3 ++- pathspec.c | 2 +- repository.c | 5 +++++ repository.h | 1 + setup.c | 16 ++++++++-------- trace.c | 3 +-- 18 files changed, 36 insertions(+), 34 deletions(-)
builtin/blame.c +1 -1
@@ -1081,7 +1081,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) path =add_prefix (prefix, argv[1 ]); argv[1 ] = argv[2 ]; }else {/* (2a) */ -if (argc ==2 &&is_a_rev (argv[1 ]) && !get_git_work_tree ()) +if (argc ==2 &&is_a_rev (argv[1 ]) && !repo_get_work_tree (the_repository))die ("missing <path> to blame" ); path =add_prefix (prefix, argv[argc -1 ]); }
builtin/difftool.c +2 -2
@@ -378,7 +378,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,struct hashmap wt_modified, tmp_modified;int indices_loaded =0 ; - workdir =get_git_work_tree (); + workdir =repo_get_work_tree (the_repository);/* Setup temp directories */ tmp =getenv ("TMPDIR" );
@@ -739,7 +739,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree ();setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 ); -setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); +setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (repo_get_work_tree (the_repository)),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -2
@@ -2,7 +2,6 @@#include "abspath.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h"
@@ -1291,7 +1290,8 @@ static int fsmonitor_run_daemon(void)/* Prepare to (recursively) watch the <worktree-root> directory. */ strbuf_init (&state.path_worktree_watch,0 ); -strbuf_addstr (&state.path_worktree_watch,absolute_path (get_git_work_tree ())); +strbuf_addstr (&state.path_worktree_watch, +absolute_path (repo_get_work_tree (the_repository))); state.nr_paths_watching =1 ;strbuf_init (&state.alias.alias,0 );
builtin/init-db.c +2 -2
@@ -231,9 +231,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)set_git_work_tree (work_tree); elseset_git_work_tree (git_work_tree_cfg ); -if (access (get_git_work_tree (),X_OK )) +if (access (repo_get_work_tree (the_repository),X_OK ))die_errno (_ ("Cannot access work tree '%s'" ), -get_git_work_tree ()); +repo_get_work_tree (the_repository)); }else {if (real_git_dir)
builtin/reset.c +3 -2
@@ -26,6 +26,7 @@#include "object-name.h" #include "parse-options.h" #include "path.h" +#include "repository.h" #include "unpack-trees.h" #include "cache-tree.h" #include "setup.h"
@@ -441,7 +442,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)else trace2_cmd_mode (reset_type_names[reset_type]); -if (reset_type !=SOFT && (reset_type !=MIXED ||get_git_work_tree ())) +if (reset_type !=SOFT && (reset_type !=MIXED ||repo_get_work_tree (the_repository)))setup_work_tree ();if (reset_type ==MIXED &&is_bare_repository ())
@@ -474,7 +475,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) goto cleanup; } the_repository->index->updated_skipworktree =1 ; -if (!no_refresh &&get_git_work_tree ()) { +if (!no_refresh &&repo_get_work_tree (the_repository)) {uint64_t t_begin, t_delta_in_ms; t_begin =getnanotime ();
builtin/rev-parse.c +2 -2
@@ -967,7 +967,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--show-toplevel" )) { -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);if (work_tree)print_path (work_tree, prefix, format,DEFAULT_UNMODIFIED );else
@@ -992,7 +992,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)const char *pfx = prefix;if (!is_inside_work_tree ()) {const char *work_tree = -get_git_work_tree (); +repo_get_work_tree (the_repository);if (work_tree)printf ("%s\n" , work_tree);continue ;
builtin/stash.c +1 -1
@@ -641,7 +641,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, cp.git_cmd =1 ; cp.dir = prefix;strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" , -absolute_path (get_git_work_tree ())); +absolute_path (repo_get_work_tree (the_repository)));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" ,absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );
builtin/submodule--helper.c +1 -1
@@ -1709,7 +1709,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,exit (128 );if (!is_absolute_path (clone_data->path)) - clone_data_path = to_free =xstrfmt ("%s/%s" ,get_git_work_tree (), + clone_data_path = to_free =xstrfmt ("%s/%s" ,repo_get_work_tree (the_repository), clone_data->path);if (validate_submodule_git_dir (sm_gitdir, clone_data->name) <0 )
builtin/update-index.c +1 -1
@@ -1194,7 +1194,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)"remove or change it, if you really want to " "enable the untracked cache"));add_untracked_cache (the_repository->index); -report (_ ("Untracked cache enabled for '%s'" ),get_git_work_tree ()); +report (_ ("Untracked cache enabled for '%s'" ),repo_get_work_tree (the_repository));break ;default :BUG ("bad untracked_cache value: %d" , untracked_cache);
dir.c +2 -1
@@ -20,6 +20,7 @@#include "object-store-ll.h" #include "path.h" #include "refs.h" +#include "repository.h" #include "wildmatch.h" #include "pathspec.h" #include "utf8.h"
@@ -2838,7 +2839,7 @@ static const char *get_ident_string(void)return sb.buf;if (uname (&uts) <0 )die_errno (_ ("failed to get kernel name and information" )); -strbuf_addf (&sb,"Location %s, system %s" ,get_git_work_tree (), +strbuf_addf (&sb,"Location %s, system %s" ,repo_get_work_tree (the_repository), uts.sysname);return sb.buf; }
environment.c +1 -6
@@ -219,7 +219,7 @@ void setup_git_env(const char *git_dir)int is_bare_repository (void ) {/* if core.bare is not 'false', let's see if there is a work tree */ -return is_bare_repository_cfg && !get_git_work_tree (); +return is_bare_repository_cfg && !repo_get_work_tree (the_repository); }int have_git_dir (void )
@@ -268,11 +268,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -const char *get_git_work_tree (void ) -{ -return the_repository->worktree; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -108,7 +108,6 @@ extern char *git_work_tree_cfg;void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); -const char *get_git_work_tree (void );void set_git_work_tree (const char *tree);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
fsmonitor.c +2 -1
@@ -8,6 +8,7 @@#include "fsmonitor.h" #include "fsmonitor-ipc.h" #include "name-hash.h" +#include "repository.h" #include "run-command.h" #include "strbuf.h" #include "trace2.h"
@@ -169,7 +170,7 @@ static int query_fsmonitor_hook(struct repository *r,strvec_pushf (&cp.args,"%d" , version);strvec_pushf (&cp.args,"%s" , last_update); cp.use_shell =1 ; - cp.dir =get_git_work_tree (); + cp.dir =repo_get_work_tree (the_repository);trace2_region_enter ("fsm_hook" ,"query" ,NULL );
pathspec.c +1 -1
@@ -495,7 +495,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,if (!have_git_dir ())die (_ ("'%s' is outside the directory tree" ), copyfrom); - hint_path =get_git_work_tree (); + hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("%s: '%s' is outside repository at '%s'"), elt,
repository.c +5 -0
@@ -126,6 +126,11 @@ const char *repo_get_graft_file(struct repository *repo)return repo->graft_file; } +const char *repo_get_work_tree (struct repository *repo) +{ +return repo->worktree; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -211,6 +211,7 @@ const char *repo_get_common_dir(struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo);const char *repo_get_graft_file (struct repository *repo); +const char *repo_get_work_tree (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +8 -8
@@ -51,7 +51,7 @@ static int abspath_part_inside_repo(char *path)size_t wtlen;char *path0;int off; -const char *work_tree =precompose_string_if_needed (get_git_work_tree ()); +const char *work_tree =precompose_string_if_needed (repo_get_work_tree (the_repository));struct strbuf realpath =STRBUF_INIT ;if (!work_tree)
@@ -147,7 +147,7 @@ char *prefix_path(const char *prefix, int len, const char *path) {char *r =prefix_path_gently (prefix, len,NULL , path);if (!r) { -const char *hint_path =get_git_work_tree (); +const char *hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("'%s' is outside repository at '%s'"), path,
@@ -475,7 +475,7 @@ int is_inside_git_dir(void)int is_inside_work_tree (void ) {if (inside_work_tree <0 ) - inside_work_tree =is_inside_dir (get_git_work_tree ()); + inside_work_tree =is_inside_dir (repo_get_work_tree (the_repository));return inside_work_tree; }
@@ -490,7 +490,7 @@ void setup_work_tree(void)if (work_tree_config_is_bogus)die (_ ("unable to set up work tree using invalid config" )); - work_tree =get_git_work_tree (); + work_tree =repo_get_work_tree (the_repository);if (!work_tree ||chdir_notify (work_tree))die (_ ("this operation must be run in a work tree" ));
@@ -547,7 +547,7 @@ static void setup_original_cwd(void)* Get our worktree; we only protect the current working directory * if it's in the worktree. */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository);if (!worktree) goto no_prevention_needed;
@@ -1062,9 +1062,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,set_git_work_tree ("." );/* set_git_work_tree() must have been called by now */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository); -/* both get_git_work_tree() and cwd are already normalized */ +/* both repo_get_work_tree() and cwd are already normalized */ if (!strcmp (cwd->buf, worktree)) {/* cwd == worktree */ set_git_dir (gitdirenv,0 );free (gitfile);
@@ -2192,7 +2192,7 @@ static int create_default_files(const char *template_path,char *path;int reinit;int filemode; -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);/* * First copy the templates -- we might have the default
trace.c +1 -2
@@ -25,7 +25,6 @@#include "git-compat-util.h" #include "abspath.h" -#include "environment.h" #include "repository.h" #include "quote.h" #include "setup.h"
@@ -308,7 +307,7 @@ void trace_repo_setup(void) cwd =xgetcwd (); -if (!(git_work_tree =get_git_work_tree ())) +if (!(git_work_tree =repo_get_work_tree (the_repository))) git_work_tree ="(null)" ;if (!startup_info->prefix)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 7/21 config: document `read_early_config()` and `read_very_early_config()`
In reply to Patrick SteinhardtIt's not clear what read_early_config() and read_very_early_config() do differently compared to repo_read_config() from just looking at their names. Document both of these in the header file to clarify their intent.
--- config.c | 4 ---- config.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-)
config.c +0 -4
@@ -2234,10 +2234,6 @@ void read_early_config(config_fn_t cb, void *data)strbuf_release (&gitdir); } -/* -* Read config but only enumerate system and global settings. -* Omit any repo-local, worktree-local, or command-line settings. -*/ void read_very_early_config (config_fn_t cb,void *data) {struct config_options opts = {0 };
config.h +11 -0
@@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name,void git_config_push_parameter (const char *text);void git_config_push_env (const char *spec);int git_config_from_parameters (config_fn_t fn,void *data); + +/* +* Read config when the Git directory has not yet been set up. In case +* `the_repository` has not yet been set up, try to discover the Git +* directory to read the configuration from. +*/ void read_early_config (config_fn_t cb,void *data); + +/* +* Read config but only enumerate system and global settings. +* Omit any repo-local, worktree-local, or command-line settings. +*/ void read_very_early_config (config_fn_t cb,void *data);/**
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 8/21 config: make dependency on repo in `read_early_config()` explicit
In reply to Patrick SteinhardtThe read_early_config() function can be used to read configuration where a repository has not yet been set up. As such, it is optional whether or not the_repository has already been initialized. If it was initialized we use its commondir and gitdir. If not, the function will try to detect the Git directories by itself and, if found, also parse their config files.
This means that we implicitly rely on the_repository. Make this dependency explicit by passing a struct repository. This allows us to again drop the USE_THE_REPOSITORY_VARIABLE define in "config.c".
--- alias.c | 6 ++++-- config.c | 10 ++++------ config.h | 2 +- help.c | 2 +- pager.c | 7 +++++-- t/helper/test-config.c | 3 ++- trace2/tr2_cfg.c | 4 +++- 7 files changed, 20 insertions(+), 14 deletions(-)
alias.c +4 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "alias.h" #include "config.h"
@@ -37,7 +39,7 @@ char *alias_lookup(const char *alias) {struct config_alias_data data = { alias,NULL }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data);return data.v; }
@@ -46,7 +48,7 @@ void list_aliases(struct string_list *list) {struct config_alias_data data = {NULL ,NULL , list }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data); }void quote_cmdline (struct strbuf *buf,const char **argv)
config.c +4 -6
@@ -6,8 +6,6 @@* */ -#define USE_THE_REPOSITORY_VARIABLE -#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2204,7 +2202,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config (config_fn_t cb,void *data) +void read_early_config (struct repository *repo,config_fn_t cb,void *data) {struct config_options opts = {0 };struct strbuf commondir =STRBUF_INIT ;
@@ -2212,9 +2210,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ; -if (have_git_dir ()) { - opts.commondir =repo_get_common_dir (the_repository); - opts.git_dir =repo_get_git_dir (the_repository); +if (repo && repo->gitdir) { + opts.commondir =repo_get_common_dir (repo); + opts.git_dir =repo_get_git_dir (repo);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
config.h +1 -1
@@ -198,7 +198,7 @@ int git_config_from_parameters(config_fn_t fn, void *data);* `the_repository` has not yet been set up, try to discover the Git * directory to read the configuration from. */ -void read_early_config (config_fn_t cb,void *data); +void read_early_config (struct repository *repo,config_fn_t cb,void *data);/* * Read config but only enumerate system and global settings.
help.c +1 -1
@@ -618,7 +618,7 @@ const char *help_unknown_cmd(const char *cmd)memset (&other_cmds,0 ,sizeof (other_cmds));memset (&aliases,0 ,sizeof (aliases)); -read_early_config (git_unknown_cmd_config,NULL ); +read_early_config (the_repository, git_unknown_cmd_config,NULL );/* * Disable autocorrection prompt in a non-interactive session
pager.c +5 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "editor.h"
@@ -92,7 +94,8 @@ const char *git_pager(int stdout_is_tty) pager =getenv ("GIT_PAGER" );if (!pager) {if (!pager_program) -read_early_config (core_pager_config,NULL ); +read_early_config (the_repository, + core_pager_config,NULL ); pager = pager_program; }if (!pager)
@@ -298,7 +301,7 @@ int check_pager_config(const char *cmd) data.want =-1 ; data.value =NULL ; -read_early_config (pager_command_config, &data); +read_early_config (the_repository, pager_command_config, &data);if (data.value) pager_program = data.value;
t/helper/test-config.c +2 -1
@@ -96,7 +96,8 @@ int cmd__config(int argc, const char **argv)struct config_set cs;if (argc ==3 && !strcmp (argv[1 ],"read_early_config" )) { -read_early_config (early_config_cb, (void *)argv[2 ]); +read_early_config (the_repository, early_config_cb, + (void *)argv[2 ]);return 0 ; }
trace2/tr2_cfg.c +3 -1
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "strbuf.h"
@@ -124,7 +126,7 @@ void tr2_cfg_list_config_fl(const char *file, int line)struct tr2_cfg_data data = { file, line };if (tr2_cfg_load_patterns () >0 ) -read_early_config (tr2_cfg_cb, &data); +read_early_config (the_repository, tr2_cfg_cb, &data); }void tr2_list_env_vars_fl (const char *file,int line)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 9/21 environment: move `odb_mkstemp()` into object layer
In reply to Patrick SteinhardtThe odb_mkstemp() function is quite clearly tied to the object store, but regardless of that it is located in "environment.c". Move it over, which also helps to get rid of dependencies on the_repository in the environment subsystem.
--- bundle-uri.c | 2 +- environment.c | 34 ---------------------------------- environment.h | 15 --------------- object-file.c | 33 +++++++++++++++++++++++++++++++++ object-store-ll.h | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 50 deletions(-)
bundle-uri.c +1 -1
@@ -4,7 +4,6 @@#include "bundle-uri.h" #include "bundle.h" #include "copy.h" -#include "environment.h" #include "gettext.h" #include "refs.h" #include "run-command.h"
@@ -13,6 +12,7 @@#include "config.h" #include "fetch-pack.h" #include "remote.h" +#include "object-store-ll.h" static struct { enum bundle_list_heuristic heuristic;
environment.c +0 -34
@@ -23,7 +23,6 @@#include "commit.h" #include "strvec.h" #include "object-file.h" -#include "object-store-ll.h" #include "path.h" #include "replace-object.h" #include "tmp-objdir.h"
@@ -268,39 +267,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) -{ -int fd; -/* -* we let the umask do its job, don't try to be more -* restrictive except to remove write permission. -*/ -int mode =0444 ; -git_path_buf (temp_filename,"objects/%s" , pattern); - fd =git_mkstemp_mode (temp_filename->buf, mode); -if (0 <= fd) -return fd; - -/* slow path */ -/* some mkstemp implementations erase temp_filename on failure */ -git_path_buf (temp_filename,"objects/%s" , pattern); -safe_create_leading_directories (temp_filename->buf); -return xmkstemp_mode (temp_filename->buf, mode); -} - -int odb_pack_keep (const char *name) -{ -int fd; - - fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -if (0 <= fd) -return fd; - -/* slow path */ -safe_create_leading_directories_const (name); -return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -15
@@ -200,21 +200,6 @@ extern int grafts_keep_true_parents;extern int repository_format_precious_objects; -/* -* Create a temporary file rooted in the object database directory, or -* die on failure. The filename is taken from "pattern", which should have the -* usual "XXXXXX" trailer, and the resulting filename is written into the -* "template" buffer. Returns the open descriptor. -*/ -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); - -/* -* Create a pack .keep file named "name" (which should generally be the output -* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on -* error. -*/ -int odb_pack_keep (const char *name); -const char *get_log_output_encoding (void );const char *get_commit_output_encoding (void );
object-file.c +33 -0
@@ -419,6 +419,39 @@ enum scld_error safe_create_leading_directories_const(const char *path)return result; } +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) +{ +int fd; +/* +* we let the umask do its job, don't try to be more +* restrictive except to remove write permission. +*/ +int mode =0444 ; +git_path_buf (temp_filename,"objects/%s" , pattern); + fd =git_mkstemp_mode (temp_filename->buf, mode); +if (0 <= fd) +return fd; + +/* slow path */ +/* some mkstemp implementations erase temp_filename on failure */ +git_path_buf (temp_filename,"objects/%s" , pattern); +safe_create_leading_directories (temp_filename->buf); +return xmkstemp_mode (temp_filename->buf, mode); +} + +int odb_pack_keep (const char *name) +{ +int fd; + + fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +if (0 <= fd) +return fd; + +/* slow path */ +safe_create_leading_directories_const (name); +return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +} +static void fill_loose_path (struct strbuf *buf,const struct object_id *oid) {int i;
object-store-ll.h +15 -0
@@ -231,6 +231,21 @@ struct raw_object_store {struct raw_object_store *raw_object_store_new (void );void raw_object_store_clear (struct raw_object_store *o); +/* +* Create a temporary file rooted in the object database directory, or +* die on failure. The filename is taken from "pattern", which should have the +* usual "XXXXXX" trailer, and the resulting filename is written into the +* "template" buffer. Returns the open descriptor. +*/ +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); + +/* +* Create a pack .keep file named "name" (which should generally be the output +* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on +* error. +*/ +int odb_pack_keep (const char *name); +/* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid.
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 10/21 environment: make `get_git_namespace()` self-contained
In reply to Patrick SteinhardtThe logic to set up and retrieve git_namespace is distributed across different functions which communicate with each other via a global environment variable. This is rather pointless though, as the value is always derived from an environment variable, and this environment variable does not change after we have parsed global options.
Convert the function to be fully self-contained such that it lazily populates once called.
--- environment.c | 57 ++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 28 deletions(-)
environment.c +29 -28
@@ -122,8 +122,6 @@ int core_preload_index = 1;/* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; -static char *git_namespace; -/* * Repository-local GIT_* environment variables; see environment.h for details. */
@@ -146,27 +144,6 @@ const char * const local_repo_env[] = { NULL }; -static char *expand_namespace (const char *raw_namespace) -{ -struct strbuf buf =STRBUF_INIT ; -struct strbuf **components, **c; - -if (!raw_namespace || !*raw_namespace) -return xstrdup ("" ); - -strbuf_addstr (&buf, raw_namespace); - components =strbuf_split (&buf,'/' ); -strbuf_reset (&buf); -for (c = components; *c; c++) -if (strcmp ((*c)->buf,"/" ) !=0 ) -strbuf_addf (&buf,"refs/namespaces/%s" , (*c)->buf); -strbuf_list_free (components); -if (check_refname_format (buf.buf,0 )) -die (_ ("bad git namespace path \"%s\"" ), raw_namespace); -strbuf_addch (&buf,'/' ); -return strbuf_detach (&buf,NULL ); -} -const char *getenv_safe (struct strvec *argv,const char *name) {const char *value =getenv (name);
@@ -205,8 +182,6 @@ void setup_git_env(const char *git_dir) : "refs/replace/");update_ref_namespace (NAMESPACE_REPLACE , git_replace_ref_base); -free (git_namespace); - git_namespace =expand_namespace (getenv (GIT_NAMESPACE_ENVIRONMENT )); shallow_file =getenv (GIT_SHALLOW_FILE_ENVIRONMENT );if (shallow_file)set_alternate_shallow_file (the_repository, shallow_file,0 );
@@ -229,9 +204,35 @@ int have_git_dir(void)const char *get_git_namespace (void ) { -if (!git_namespace) -BUG ("git environment hasn't been setup" ); -return git_namespace; +static const char *namespace; + +struct strbuf buf =STRBUF_INIT ; +struct strbuf **components, **c; +const char *raw_namespace; + +if (namespace) +return namespace; + + raw_namespace =getenv (GIT_NAMESPACE_ENVIRONMENT ); +if (!raw_namespace || !*raw_namespace) { + namespace ="" ; +return namespace; + } + +strbuf_addstr (&buf, raw_namespace); + components =strbuf_split (&buf,'/' ); +strbuf_reset (&buf); +for (c = components; *c; c++) +if (strcmp ((*c)->buf,"/" ) !=0 ) +strbuf_addf (&buf,"refs/namespaces/%s" , (*c)->buf); +strbuf_list_free (components); +if (check_refname_format (buf.buf,0 )) +die (_ ("bad git namespace path \"%s\"" ), raw_namespace); +strbuf_addch (&buf,'/' ); + + namespace =strbuf_detach (&buf,NULL ); + +return namespace; }const char *strip_namespace (const char *namespaced_ref)
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 11/21 environment: move `set_git_dir()` and related into setup layer
In reply to Patrick SteinhardtThe functions set_git_dir() and friends are used to set up repositories. As such, they are quite clearly part of the setup subsystem, but still live in "environment.c". Move them over, which also helps to get rid of dependencies on the_repository in the environment subsystem.
--- environment.c | 105 ------------------------------------------------- environment.h | 2 - setup.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ setup.h | 3 ++ 4 files changed, 109 insertions(+), 107 deletions(-)
environment.c +0 -105
@@ -22,14 +22,9 @@#include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" -#include "object-file.h" #include "path.h" -#include "replace-object.h" -#include "tmp-objdir.h" #include "chdir-notify.h" #include "setup.h" -#include "shallow.h" -#include "trace.h" #include "write-or-die.h" int trust_executable_bit =1 ;
@@ -155,41 +150,6 @@ const char *getenv_safe(struct strvec *argv, const char *name)return argv->v[argv->nr -1 ]; } -void setup_git_env (const char *git_dir) -{ -char *git_replace_ref_base; -const char *shallow_file; -const char *replace_ref_base; -struct set_gitdir_args args = {NULL }; -struct strvec to_free =STRVEC_INIT ; - - args.commondir =getenv_safe (&to_free,GIT_COMMON_DIR_ENVIRONMENT ); - args.object_dir =getenv_safe (&to_free,DB_ENVIRONMENT ); - args.graft_file =getenv_safe (&to_free,GRAFT_ENVIRONMENT ); - args.index_file =getenv_safe (&to_free,INDEX_ENVIRONMENT ); - args.alternate_db =getenv_safe (&to_free,ALTERNATE_DB_ENVIRONMENT ); -if (getenv (GIT_QUARANTINE_ENVIRONMENT )) { - args.disable_ref_updates =1 ; - } - -repo_set_gitdir (the_repository, git_dir, &args); -strvec_clear (&to_free); - -if (getenv (NO_REPLACE_OBJECTS_ENVIRONMENT )) -disable_replace_refs (); - replace_ref_base =getenv (GIT_REPLACE_REF_BASE_ENVIRONMENT ); - git_replace_ref_base =xstrdup (replace_ref_base ? replace_ref_base - :"refs/replace/" ); -update_ref_namespace (NAMESPACE_REPLACE , git_replace_ref_base); - - shallow_file =getenv (GIT_SHALLOW_FILE_ENVIRONMENT ); -if (shallow_file) -set_alternate_shallow_file (the_repository, shallow_file,0 ); - -if (git_env_bool (NO_LAZY_FETCH_ENVIRONMENT ,0 )) - fetch_if_missing =0 ; -} -int is_bare_repository (void ) {/* if core.bare is not 'false', let's see if there is a work tree */
@@ -243,71 +203,6 @@ const char *strip_namespace(const char *namespaced_ref)return NULL ; } -static int git_work_tree_initialized; - -/* -* Note. This works only before you used a work tree. This was added -* primarily to support git-clone to work in a new repository it just -* created, and is not meant to flip between different work trees. -*/ -void set_git_work_tree (const char *new_work_tree) -{ -if (git_work_tree_initialized) { -struct strbuf realpath =STRBUF_INIT ; - -strbuf_realpath (&realpath, new_work_tree,1 ); - new_work_tree = realpath.buf; -if (strcmp (new_work_tree, the_repository->worktree)) -die ("internal error: work tree has already been set\n" -"Current worktree: %s\nNew worktree: %s" , - the_repository->worktree, new_work_tree); -strbuf_release (&realpath); -return ; - } - git_work_tree_initialized =1 ; -repo_set_worktree (the_repository, new_work_tree); -} - -static void set_git_dir_1 (const char *path) -{ -xsetenv (GIT_DIR_ENVIRONMENT , path,1 ); -setup_git_env (path); -} - -static void update_relative_gitdir(const char *name UNUSED, -const char *old_cwd, -const char *new_cwd, - void *data UNUSED) -{ -char *path =reparent_relative_path (old_cwd, new_cwd, -repo_get_git_dir (the_repository)); -struct tmp_objdir *tmp_objdir =tmp_objdir_unapply_primary_odb (); - -trace_printf_key (&trace_setup_key, -"setup: move $GIT_DIR to '%s'" , - path); -set_git_dir_1 (path); -if (tmp_objdir) -tmp_objdir_reapply_primary_odb (tmp_objdir, old_cwd, new_cwd); -free (path); -} - -void set_git_dir (const char *path,int make_realpath) -{ -struct strbuf realpath =STRBUF_INIT ; - -if (make_realpath) { -strbuf_realpath (&realpath, path,1 ); - path = realpath.buf; - } - -set_git_dir_1 (path); -if (!is_absolute_path (path)) -chdir_notify_register (NULL , update_relative_gitdir,NULL ); - -strbuf_release (&realpath); -} -const char *get_log_output_encoding (void ) { return git_log_output_encoding ? git_log_output_encoding
environment.h +0 -2
@@ -105,10 +105,8 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); -void set_git_work_tree (const char *tree);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
setup.c +106 -0
128 lines not on this page · raw message
setup.h +3 -0
@@ -94,6 +94,9 @@ static inline int discover_git_directory(struct strbuf *commondir,return 0 ; } +void set_git_dir (const char *path,int make_realpath); +void set_git_work_tree (const char *tree); +const char *setup_git_directory_gently (int *);const char *setup_git_directory (void );char *prefix_path (const char *prefix,int len,const char *path);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 12/21 environment: reorder header to split out `the_repository`-free section
In reply to Patrick SteinhardtReorder the "environment.h" header such that declarations which are free from the_repository come before those which aren't. The new structure is now:
- Defines for environment variable names.
- Things which do not rely on a repository.
- Things which do, including those that implicitly rely on a parsed repository. This includes for example variables which get populated when reading repository config.
This will allow us to guard the last category of declarations with USE_THE_REPOSITORY_VARIABLE.
--- environment.h | 81 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 41 deletions(-)
environment.h +40 -41
@@ -1,22 +1,6 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct strvec ; - -/* -* The character that begins a commented line in user-editable file -* that is subject to stripspace. -*/ -extern const char *comment_line_str; -extern char *comment_line_str_to_free; -extern int auto_comment_line_char; - -/* -* Wrapper of getenv() that returns a strdup value. This value is kept -* in argv to be freed later. -*/ -const char *getenv_safe (struct strvec *argv,const char *name); -/* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR"#define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR"
@@ -86,6 +70,8 @@ const char *getenv_safe(struct strvec *argv, const char *name);*/ #define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE" +#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" +/* * Repository-local GIT_* environment variables; these will be cleared * when git spawns a sub-process that runs inside another repository.
@@ -94,6 +80,28 @@ const char *getenv_safe(struct strvec *argv, const char *name);*/ extern const char *const local_repo_env[]; +struct strvec ; + +/* +* Wrapper of getenv() that returns a strdup value. This value is kept +* in argv to be freed later. +*/ +const char *getenv_safe (struct strvec *argv,const char *name); + +/* +* Should we print an ellipsis after an abbreviated SHA-1 value +* when doing diff-raw output or indicating a detached HEAD? +*/ +int print_sha1_ellipsis (void ); + +/* +* Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). +*/ +int use_optional_locks (void ); + +const char *get_git_namespace (void ); +const char *strip_namespace (const char *namespaced_ref); +void setup_git_env (const char *git_dir);/*
@@ -102,13 +110,19 @@ void setup_git_env(const char *git_dir);*/ int have_git_dir (void ); +/* +* Accessors for the core.sharedrepository config which lazy-load the value +* from the config (if not already set). The "reset" function can be +* used to unset "set" or cached value, meaning that the value will be loaded +* fresh from the config file on the next call to get_shared_repository(). +*/ +void set_shared_repository (int value); +int get_shared_repository (void ); +void reset_shared_repository (void ); +extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_namespace (void ); -const char *strip_namespace (const char *namespaced_ref); - -#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"/* Environment bits from configuration mechanism */ extern int trust_executable_bit;
@@ -134,16 +148,6 @@ extern unsigned long big_file_threshold;extern unsigned long pack_size_limit_cfg;extern int max_allowed_tree_depth; -/* -* Accessors for the core.sharedrepository config which lazy-load the value -* from the config (if not already set). The "reset" function can be -* used to unset "set" or cached value, meaning that the value will be loaded -* fresh from the config file on the next call to get_shared_repository(). -*/ -void set_shared_repository (int value); -int get_shared_repository (void ); -void reset_shared_repository (void ); -extern int core_preload_index;extern int precomposed_unicode;extern int protect_hfs;
@@ -153,11 +157,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -/* -* Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). -*/ -int use_optional_locks (void ); -enum log_refs_config {LOG_REFS_UNSET =-1 ,LOG_REFS_NONE =0 ,
@@ -172,6 +171,7 @@ enum rebase_setup_type {AUTOREBASE_REMOTE ,AUTOREBASE_ALWAYS }; +extern enum rebase_setup_type autorebase;enum push_default_type { PUSH_DEFAULT_NOTHING = 0,
@@ -181,15 +181,12 @@ enum push_default_type {PUSH_DEFAULT_CURRENT , PUSH_DEFAULT_UNSPECIFIED }; - -extern enum rebase_setup_type autorebase;extern enum push_default_type push_default;enum object_creation_mode {OBJECT_CREATION_USES_HARDLINKS =0 ,OBJECT_CREATION_USES_RENAMES =1 }; -extern enum object_creation_mode object_creation_mode;extern char *notes_ref_name;
@@ -209,9 +206,11 @@ extern char *askpass_program;extern char *excludes_file;/* -* Should we print an ellipsis after an abbreviated SHA-1 value -* when doing diff-raw output or indicating a detached HEAD? +* The character that begins a commented line in user-editable file +* that is subject to stripspace. */ -int print_sha1_ellipsis (void ); +extern const char *comment_line_str; +extern char *comment_line_str_to_free; +extern int auto_comment_line_char;#endif
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 13/21 environment: guard state depending on a repository
In reply to Patrick SteinhardtIn "environment.h" we have quite a lot of functions and variables that either explicitly or implicitly depend on the_repository.
The implicit set of stateful declarations includes for example variables which get populated when parsing a repository's Git configuration. This set of variables is broken by design, as their state often depends on the last repository config that has been parsed. So they may or may not represent the state of the_repository.
Fixing that is quite a big undertaking, and later patches in this series will demonstrate a solution for a first small set of those variables. So for now, let's guard these with USE_THE_REPOSITORY_VARIABLE so that callers are aware of the implicit dependency.
--- compat/mingw.c | 2 ++ compat/win32/path-utils.c | 2 ++ config.c | 2 ++ environment.h | 25 ++++++++++++++++++++++++- name-hash.c | 3 +++ path.c | 2 ++ preload-index.c | 3 +++ prompt.c | 2 ++ refs/files-backend.c | 2 ++ sparse-index.c | 2 ++ statinfo.c | 2 ++ t/helper/test-path-utils.c | 2 ++ tree-diff.c | 3 +++ userdiff.c | 2 ++ 14 files changed, 53 insertions(+), 1 deletion(-)
compat/mingw.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../git-compat-util.h" #include "win32.h" #include <aclapi.h>
compat/win32/path-utils.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../../git-compat-util.h" #include "../../environment.h"
config.c +2 -0
@@ -6,6 +6,8 @@* */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
environment.h +24 -1
@@ -102,6 +102,28 @@ int use_optional_locks(void);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); +/* +* TODO: All the below state either explicitly or implicitly relies on +* `the_repository`. We should eventually get rid of these and make the +* dependency on a repository explicit: +* +* - `setup_git_env()` ideally shouldn't exist as it modifies global state, +* namely the environment. The current process shouldn't ever access that +* state via envvars though, but should instead consult a `struct +* repository`. When spawning new processes, we would ideally also pass a +* `struct repository` and then set up the environment variables for the +* child process, only. +* +* - `have_git_dir()` should not have to exist at all. Instead, we should +* decide on whether or not we have a `struct repository`. +* +* - All the global config variables should become tied to a repository. Like +* this, we'd correctly honor repository-local configuration and be able to +* distinguish configuration values from different repositories. +* +* Please do not add new global config variables here. +*/ +# ifdef USE_THE_REPOSITORY_VARIABLE void setup_git_env (const char *git_dir);/*
@@ -213,4 +235,5 @@ extern const char *comment_line_str;extern char *comment_line_str_to_free;extern int auto_comment_line_char; -#endif +# endif /* USE_THE_REPOSITORY_VARIABLE */ +#endif /* ENVIRONMENT_H */
name-hash.c +3 -0
@@ -5,6 +5,9 @@* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "gettext.h"
path.c +2 -0
@@ -2,6 +2,8 @@* Utilities for paths and pathnames */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "environment.h"
preload-index.c +3 -0
@@ -1,6 +1,9 @@/* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "pathspec.h" #include "dir.h"
prompt.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "parse.h" #include "environment.h"
refs/files-backend.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "../git-compat-util.h" #include "../copy.h" #include "../environment.h"
sparse-index.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "gettext.h"
statinfo.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "environment.h" #include "statinfo.h"
t/helper/test-path-utils.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "test-tool.h" #include "abspath.h" #include "environment.h"
tree-diff.c +3 -0
@@ -1,6 +1,9 @@/* * Helper functions for tree diff generation */ + +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "diff.h" #include "diffcore.h"
userdiff.c +2 -0
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "userdiff.h"
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 14/21 repo-settings: split out declarations into a standalone header
In reply to Patrick SteinhardtWhile we have "repo-settings.c", we do not have a corresponding "repo-settings.h" file. Instead, this functionality is part of the "repository.h" header, making it hard to discover.
Split the declarations out of "repository.h" and create a standalone header file with them.
--- repo-settings.c | 1 + repo-settings.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ repository.h | 51 +------------------------------------------- 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 repo-settings.h
repo-settings.c +1 -0
@@ -1,5 +1,6 @@#include "git-compat-util.h" #include "config.h" +#include "repo-settings.h" #include "repository.h" #include "midx.h"
repo-settings.h new file +56 -0
56 lines not on this page · raw message
repository.h +1 -50
77 lines not on this page · raw message
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 15/21 repo-settings: track defaults close to `struct repo_settings`
In reply to Patrick SteinhardtThe default values for struct repo_settings are set up in prepare_repo_settings(). This is somewhat different from how we typically do this, namely by providing an INIT macro that sets up the default values for us.
Refactor the code to do the same.
--- repo-settings.c | 9 ++++----- repo-settings.h | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-)
repo-settings.c +4 -5
@@ -20,6 +20,7 @@ static void repo_cfg_int(struct repository *r, const char *key, int *dest,void prepare_repo_settings (struct repository *r) { +const struct repo_settings defaults =REPO_SETTINGS_INIT ;int experimental;int value;const char *strval;
@@ -29,13 +30,11 @@ void prepare_repo_settings(struct repository *r)if (!r->gitdir)BUG ("Cannot add settings for uninitialized repository" ); -if (r->settings.initialized++) +if (r->settings.initialized)return ; -/* Defaults */ - r->settings.index_version =-1 ; - r->settings.core_untracked_cache =UNTRACKED_CACHE_KEEP ; - r->settings.fetch_negotiation_algorithm =FETCH_NEGOTIATION_CONSECUTIVE ; +memcpy (&r->settings, &defaults,sizeof (defaults)); + r->settings.initialized++;/* Booleans config or default, cascades to other settings */ repo_cfg_bool (r,"feature.manyfiles" , &manyfiles,0 );
repo-settings.h +5 -0
@@ -50,6 +50,11 @@ struct repo_settings {int core_multi_pack_index; }; +#define REPO_SETTINGS_INIT { \ + .index_version = -1, \ + .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ + .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ +}void prepare_repo_settings (struct repository *r);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 16/21 branch: stop modifying `log_all_ref_updates` variable
In reply to Patrick SteinhardtIn "branch.c" we modify the global log_all_ref_updates variable to force creation of a reflog entry. Modifying global state like this is discouraged, as it may have all kinds of consequences in other places of our codebase.
Stop modifying the variable and pass the REF_FORCE_CREATE_REFLOG flag, which has the same effect.
--- branch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
branch.c +3 -2
@@ -601,6 +601,7 @@ void create_branch(struct repository *r,int forcing =0 ;struct ref_transaction *transaction;struct strbuf err =STRBUF_INIT ; +int flags =0 ;char *msg;if (track ==BRANCH_TRACK_OVERRIDE )
@@ -619,7 +620,7 @@ void create_branch(struct repository *r, goto cleanup;if (reflog) - log_all_ref_updates =LOG_REFS_NORMAL ; + flags |=REF_FORCE_CREATE_REFLOG ;if (forcing) msg =xstrfmt ("branch: Reset to %s" , start_name);
@@ -630,7 +631,7 @@ void create_branch(struct repository *r,if (!transaction ||ref_transaction_update (transaction, ref.buf, &oid, forcing ?NULL :null_oid (), -NULL ,NULL ,0 , msg, &err) || +NULL ,NULL , flags, msg, &err) ||ref_transaction_commit (transaction, &err))die ("%s" , err.buf);ref_transaction_free (transaction);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 17/21 refs: stop modifying global `log_all_ref_updates` variable
In reply to Patrick SteinhardtIn refs-related code we modify the global log_all_ref_updates variable, which is done because should_autocreate_reflog() does not accept passing an enum log_refs_config but instead accesses the global variable. Adapt its interface such that the value is provided by the caller, which allows us to compute the proper value locally without having to modify global state.
This change requires us to move the enum to "repo-settings.h", or otherwise we get compilation errors due to include cycles. We're about to fully move this setting into the repo-settings subsystem anyway, so this is fine.
--- builtin/checkout.c | 3 ++- environment.h | 8 ++------ refs.c | 5 +++-- refs.h | 4 +++- refs/files-backend.c | 23 ++++++++++++----------- refs/reftable-backend.c | 12 +++++++----- repo-settings.h | 7 +++++++ 7 files changed, 36 insertions(+), 26 deletions(-)
builtin/checkout.c +2 -1
@@ -23,6 +23,7 @@#include "read-cache.h" #include "refs.h" #include "remote.h" +#include "repo-settings.h" #include "resolve-undo.h" #include "revision.h" #include "setup.h"
@@ -954,7 +955,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts, refname =mkpathdup ("refs/heads/%s" , opts->new_orphan_branch);if (opts->new_branch_log && - !should_autocreate_reflog (refname)) { + !should_autocreate_reflog (log_all_ref_updates, refname)) {int ret;struct strbuf err =STRBUF_INIT ;
environment.h +2 -6
@@ -1,6 +1,8 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H +#include "repo-settings.h" +/* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR"#define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR"
@@ -179,12 +181,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -enum log_refs_config { -LOG_REFS_UNSET =-1 , -LOG_REFS_NONE =0 , -LOG_REFS_NORMAL , -LOG_REFS_ALWAYS -};extern enum log_refs_config log_all_ref_updates;enum rebase_setup_type {
refs.c +3 -2
@@ -24,7 +24,7 @@#include "submodule.h" #include "worktree.h" #include "strvec.h" -#include "repository.h" +#include "repo-settings.h" #include "setup.h" #include "sigchain.h" #include "date.h"
@@ -958,7 +958,8 @@ static char *normalize_reflog_message(const char *msg)return strbuf_detach (&sb,NULL ); } -int should_autocreate_reflog (const char *refname) +int should_autocreate_reflog (enum log_refs_config log_all_ref_updates, +const char *refname) {switch (log_all_ref_updates) {case LOG_REFS_ALWAYS :
refs.h +3 -1
@@ -3,6 +3,7 @@#include "commit.h" #include "repository.h" +#include "repo-settings.h" struct fsck_options ;struct object_id ;
@@ -111,7 +112,8 @@ int refs_verify_refname_available(struct ref_store *refs,int refs_ref_exists (struct ref_store *refs,const char *refname); -int should_autocreate_reflog (const char *refname); +int should_autocreate_reflog (enum log_refs_config log_all_ref_updates, +const char *refname);int is_branch (const char *refname);
refs/files-backend.c +12 -11
@@ -8,6 +8,7 @@#include "../hex.h" #include "../fsck.h" #include "../refs.h" +#include "../repo-settings.h" #include "refs-internal.h" #include "ref-cache.h" #include "packed-backend.h"
@@ -1443,6 +1444,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs,static int commit_ref_update (struct files_ref_store *refs,struct ref_lock *lock,const struct object_id *oid,const char *logmsg, +int flags,struct strbuf *err);/*
@@ -1586,7 +1588,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,oidcpy (&lock->old_oid, &orig_oid);if (write_ref_to_lockfile (refs, lock, &orig_oid,0 , &err) || -commit_ref_update (refs, lock, &orig_oid, logmsg, &err)) { +commit_ref_update (refs, lock, &orig_oid, logmsg,0 , &err)) {error ("unable to write current sha1 into %s: %s" , newrefname, err.buf);strbuf_release (&err); goto rollback;
@@ -1603,14 +1605,11 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, goto rollbacklog; } - flag = log_all_ref_updates; - log_all_ref_updates =LOG_REFS_NONE ;if (write_ref_to_lockfile (refs, lock, &orig_oid,0 , &err) || -commit_ref_update (refs, lock, &orig_oid,NULL , &err)) { +commit_ref_update (refs, lock, &orig_oid,NULL ,REF_SKIP_CREATE_REFLOG , &err)) {error ("unable to write current sha1 into %s: %s" , oldrefname, err.buf);strbuf_release (&err); } - log_all_ref_updates = flag; rollbacklog:if (logmoved &&rename (sb_newref.buf, sb_oldref.buf))
@@ -1705,13 +1704,17 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { + enum log_refs_config log_refs_cfg = log_all_ref_updates;struct strbuf logfile_sb =STRBUF_INIT ;char *logfile; +if (log_refs_cfg ==LOG_REFS_UNSET ) + log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; +files_reflog_path (refs, &logfile_sb, refname); logfile =strbuf_detach (&logfile_sb,NULL ); -if (force_create ||should_autocreate_reflog (refname)) { +if (force_create ||should_autocreate_reflog (log_refs_cfg, refname)) {if (raceproof_create_file (logfile, open_or_create_logfile, logfd)) {if (errno ==ENOENT ) strbuf_addf(err, "unable to create directory for '%s': "
@@ -1800,9 +1803,6 @@ static int files_log_ref_write(struct files_ref_store *refs,if (flags &REF_SKIP_CREATE_REFLOG )return 0 ; -if (log_all_ref_updates ==LOG_REFS_UNSET ) - log_all_ref_updates =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; - result =log_ref_setup (refs, refname, flags &REF_FORCE_CREATE_REFLOG , &logfd, err);
@@ -1891,6 +1891,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs,static int commit_ref_update (struct files_ref_store *refs,struct ref_lock *lock,const struct object_id *oid,const char *logmsg, +int flags,struct strbuf *err) {files_assert_main_repository (refs,"commit_ref_update" );
@@ -1898,7 +1899,7 @@ static int commit_ref_update(struct files_ref_store *refs,clear_loose_ref_cache (refs);if (files_log_ref_write (refs, lock->ref_name, &lock->old_oid, oid, - logmsg,0 , err)) { + logmsg, flags, err)) {char *old_msg =strbuf_detach (err,NULL );strbuf_addf (err,"cannot update the ref '%s': %s" , lock->ref_name, old_msg);
@@ -1931,7 +1932,7 @@ static int commit_ref_update(struct files_ref_store *refs,struct strbuf log_err =STRBUF_INIT ;if (files_log_ref_write (refs,"HEAD" , &lock->old_oid, oid, - logmsg,0 , &log_err)) { + logmsg, flags, &log_err)) {error ("%s" , log_err.buf);strbuf_release (&log_err); }
refs/reftable-backend.c +7 -5
@@ -19,6 +19,7 @@#include "../reftable/reftable-record.h" #include "../reftable/reftable-error.h" #include "../reftable/reftable-iterator.h" +#include "../repo-settings.h" #include "../setup.h" #include "../strmap.h" #include "parse.h"
@@ -158,20 +159,21 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store,static int should_write_log (struct ref_store *refs,const char *refname) { -if (log_all_ref_updates ==LOG_REFS_UNSET ) - log_all_ref_updates =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; +enum log_refs_config log_refs_cfg = log_all_ref_updates; +if (log_refs_cfg ==LOG_REFS_UNSET ) + log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ; -switch (log_all_ref_updates) { +switch (log_refs_cfg) {case LOG_REFS_NONE :return refs_reflog_exists (refs, refname);case LOG_REFS_ALWAYS :return 1 ;case LOG_REFS_NORMAL : -if (should_autocreate_reflog (refname)) +if (should_autocreate_reflog (log_refs_cfg, refname))return 1 ;return refs_reflog_exists (refs, refname);default : -BUG ("unhandled core.logAllRefUpdates value %d" , log_all_ref_updates); +BUG ("unhandled core.logAllRefUpdates value %d" , log_refs_cfg); } }
repo-settings.h +7 -0
@@ -16,6 +16,13 @@ enum fetch_negotiation_setting { FETCH_NEGOTIATION_NOOP, }; +enum log_refs_config { +LOG_REFS_UNSET =-1 , +LOG_REFS_NONE =0 , +LOG_REFS_NORMAL , +LOG_REFS_ALWAYS +}; +struct repo_settings {int initialized;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 18/21 environment: stop storing "core.logAllRefUpdates" globally
In reply to Patrick SteinhardtThe value of "core.logAllRefUpdates" is being stored in the global variable log_all_ref_updates. This design is somewhat aged nowadays, where it is entirely possible to access multiple repositories in the same process which all have different values for this setting. So using a single global variable to track it is plain wrong.
Remove the global variable. Instead, we now provide a new function part of the repo-settings subsystem that parses the value for a specific repository. While that may require us to read the value multiple times, we work around this by reading it once when the ref backends are set up and caching the value there.
--- builtin/checkout.c | 2 ++ config.c | 10 ---------- environment.c | 1 - environment.h | 2 -- refs/files-backend.c | 4 +++- refs/reftable-backend.c | 12 +++++++----- repo-settings.c | 16 ++++++++++++++++ repo-settings.h | 3 +++ setup.c | 2 +- 9 files changed, 32 insertions(+), 20 deletions(-)
builtin/checkout.c +2 -0
@@ -951,6 +951,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,const char *old_desc, *reflog_msg;if (opts->new_branch) {if (opts->new_orphan_branch) { +enum log_refs_config log_all_ref_updates = +repo_settings_get_log_all_ref_updates (the_repository);char *refname; refname =mkpathdup ("refs/heads/%s" , opts->new_orphan_branch);
config.c +0 -10
@@ -1452,16 +1452,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.logallrefupdates" )) { -if (value && !strcasecmp (value,"always" )) - log_all_ref_updates =LOG_REFS_ALWAYS ; -else if (git_config_bool (var, value)) - log_all_ref_updates =LOG_REFS_NORMAL ; -else - log_all_ref_updates =LOG_REFS_NONE ; -return 0 ; - } -if (!strcmp (var,"core.warnambiguousrefs" )) { warn_ambiguous_refs =git_config_bool (var, value);return 0 ;
environment.c +0 -1
@@ -77,7 +77,6 @@ int sparse_expect_files_outside_of_patterns;int merge_log_config =-1 ;int precomposed_unicode =-1 ;/* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; -enum log_refs_config log_all_ref_updates =LOG_REFS_UNSET ;int max_allowed_tree_depth = #ifdef _MSC_VER/*
environment.h +0 -2
@@ -181,8 +181,6 @@ extern int core_apply_sparse_checkout;extern int core_sparse_checkout_cone;extern int sparse_expect_files_outside_of_patterns; -extern enum log_refs_config log_all_ref_updates; -enum rebase_setup_type {AUTOREBASE_NEVER =0 ,AUTOREBASE_LOCAL ,
refs/files-backend.c +3 -1
@@ -75,6 +75,7 @@ struct files_ref_store {unsigned int store_flags;char *gitcommondir; +enum log_refs_config log_all_ref_updates;struct ref_cache *loose;
@@ -107,6 +108,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->gitcommondir =strbuf_detach (&sb,NULL ); refs->packed_ref_store =packed_ref_store_init (repo, refs->gitcommondir, flags); + refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo);chdir_notify_reparent ("files-backend $GIT_DIR" , &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR",
@@ -1704,7 +1706,7 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { - enum log_refs_config log_refs_cfg = log_all_ref_updates; + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;struct strbuf logfile_sb =STRBUF_INIT ;char *logfile;
refs/reftable-backend.c +7 -5
@@ -52,6 +52,7 @@ struct reftable_ref_store {struct reftable_write_options write_options;unsigned int store_flags; +enum log_refs_config log_all_ref_updates;int err; };
@@ -157,21 +158,21 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store, } } -static int should_write_log (struct ref_store *refs,const char *refname) +static int should_write_log (struct reftable_ref_store *refs,const char *refname) { -enum log_refs_config log_refs_cfg = log_all_ref_updates; +enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;if (log_refs_cfg ==LOG_REFS_UNSET ) log_refs_cfg =is_bare_repository () ?LOG_REFS_NONE :LOG_REFS_NORMAL ;switch (log_refs_cfg) {case LOG_REFS_NONE : -return refs_reflog_exists (refs, refname); +return refs_reflog_exists (&refs->base, refname);case LOG_REFS_ALWAYS :return 1 ;case LOG_REFS_NORMAL :if (should_autocreate_reflog (log_refs_cfg, refname))return 1 ; -return refs_reflog_exists (refs, refname); +return refs_reflog_exists (&refs->base, refname);default :BUG ("unhandled core.logAllRefUpdates value %d" , log_refs_cfg); }
@@ -278,6 +279,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,base_ref_store_init (&refs->base, repo, gitdir, &refs_be_reftable);strmap_init (&refs->worktree_stacks); refs->store_flags = store_flags; + refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo); refs->write_options.hash_id = repo->hash_algo->format_id; refs->write_options.default_permissions =calc_shared_perm (0666 & ~mask);
@@ -1220,7 +1222,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data }else if (!(u->flags &REF_SKIP_CREATE_REFLOG ) && (u->flags &REF_HAVE_NEW ) && (u->flags &REF_FORCE_CREATE_REFLOG || -should_write_log (&arg->refs->base, u->refname))) { +should_write_log (arg->refs, u->refname))) {struct reftable_log_record *log;int create_reflog =1 ;
repo-settings.c +16 -0
@@ -124,3 +124,19 @@ void prepare_repo_settings(struct repository *r)*/ r->settings.command_requires_full_index =1 ; } + +enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo) +{ +const char *value; + +if (!repo_config_get_string_tmp (repo,"core.logallrefupdates" , &value)) { +if (value && !strcasecmp (value,"always" )) +return LOG_REFS_ALWAYS ; +else if (git_config_bool ("core.logallrefupdates" , value)) +return LOG_REFS_NORMAL ; +else +return LOG_REFS_NONE ; + } + +return LOG_REFS_UNSET ; +}
repo-settings.h +3 -0
@@ -65,4 +65,7 @@ struct repo_settings {void prepare_repo_settings (struct repository *r); +/* Read the value for "core.logAllRefUpdates". */ +enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo); +#endif /* REPO_SETTINGS_H */
setup.c +1 -1
@@ -2354,7 +2354,7 @@ static int create_default_files(const char *template_path,else {git_config_set ("core.bare" ,"false" );/* allow template config file to override the default */ -if (log_all_ref_updates ==LOG_REFS_UNSET ) +if (repo_settings_get_log_all_ref_updates (the_repository) ==LOG_REFS_UNSET )git_config_set ("core.logallrefupdates" ,"true" );if (needs_work_tree_config (original_git_dir, work_tree))git_config_set ("core.worktree" , work_tree);
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 19/21 environment: stop storing "core.preferSymlinkRefs" globally
In reply to Patrick SteinhardtSame as the preceding commit, storing the "core.preferSymlinkRefs" value globally is misdesigned as this setting may be set per repository.
There is only a single user of this value anyway, namely the "files" backend. So let's just remove the global variable and read the value of this setting when initializing the backend.
--- config.c | 5 ----- environment.c | 1 - environment.h | 1 - refs/files-backend.c | 5 ++++- 4 files changed, 4 insertions(+), 8 deletions(-)
config.c +0 -5
@@ -1447,11 +1447,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.prefersymlinkrefs" )) { - prefer_symlink_refs =git_config_bool (var, value); -return 0 ; - } -if (!strcmp (var,"core.warnambiguousrefs" )) { warn_ambiguous_refs =git_config_bool (var, value);return 0 ;
environment.c +0 -1
@@ -34,7 +34,6 @@ int has_symlinks = 1;int minimum_abbrev =4 , default_abbrev =-1 ;int ignore_case;int assume_unchanged; -int prefer_symlink_refs;int is_bare_repository_cfg =-1 ;/* unspecified */ int warn_ambiguous_refs =1 ;int warn_on_object_refname_ambiguity =1 ;
environment.h +0 -1
@@ -156,7 +156,6 @@ extern int has_symlinks;extern int minimum_abbrev, default_abbrev;extern int ignore_case;extern int assume_unchanged; -extern int prefer_symlink_refs;extern int warn_ambiguous_refs;extern int warn_on_object_refname_ambiguity;extern char *apply_default_whitespace;
refs/files-backend.c +4 -1
@@ -1,6 +1,7 @@#define USE_THE_REPOSITORY_VARIABLE #include "../git-compat-util.h" +#include "../config.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h"
@@ -76,6 +77,7 @@ struct files_ref_store {char *gitcommondir;enum log_refs_config log_all_ref_updates; +int prefer_symlink_refs;struct ref_cache *loose;
@@ -109,6 +111,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->packed_ref_store =packed_ref_store_init (repo, refs->gitcommondir, flags); refs->log_all_ref_updates =repo_settings_get_log_all_ref_updates (repo); +repo_config_get_bool (repo,"core.prefersymlinkrefs" , &refs->prefer_symlink_refs);chdir_notify_reparent ("files-backend $GIT_DIR" , &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR",
@@ -2942,7 +2945,7 @@ static int files_transaction_finish(struct ref_store *ref_store,* We try creating a symlink, if that succeeds we continue to the * next update. If not, we try and create a regular symref. */ -if (update->new_target && prefer_symlink_refs) +if (update->new_target && refs->prefer_symlink_refs)if (!create_ref_symlink (lock, update->new_target))continue ;
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 20/21 environment: stop storing "core.warnAmbiguousRefs" globally
In reply to Patrick SteinhardtSame as the preceding commits, storing the "core.warnAmbiguousRefs" value globally is misdesigned as this setting may be set per repository.
Move the logic into the repo-settings subsystem. The usual pattern here is that users are expected to call prepare_repo_settings() before they access the settings themselves. This seems somewhat fragile though, as it is easy to miss and leads to somewhat ugly code patterns at the call sites.
Instead, introduce a new function that encapsulates this logic for us. This also allows us to change how exactly the lazy initialization works in the future, e.g. by only partially initializing values as requested by the caller.
--- builtin/rev-parse.c | 4 +++- config.c | 5 ----- environment.c | 1 - environment.h | 1 - object-name.c | 5 +++-- ref-filter.c | 3 ++- refs.c | 4 ++-- repo-settings.c | 9 +++++++++ repo-settings.h | 4 ++++ 9 files changed, 23 insertions(+), 13 deletions(-)
builtin/rev-parse.c +3 -1
@@ -19,6 +19,7 @@#include "path.h" #include "diff.h" #include "read-cache-ll.h" +#include "repo-settings.h" #include "repository.h" #include "revision.h" #include "setup.h"
@@ -899,7 +900,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) }if (opt_with_value (arg,"--abbrev-ref" , &arg)) { abbrev_ref =1 ; - abbrev_ref_strict = warn_ambiguous_refs; + abbrev_ref_strict = +repo_settings_get_warn_ambiguous_refs (the_repository);if (arg) {if (!strcmp (arg,"strict" )) abbrev_ref_strict =1 ;
config.c +0 -5
@@ -1447,11 +1447,6 @@ static int git_default_core_config(const char *var, const char *value,return 0 ; } -if (!strcmp (var,"core.warnambiguousrefs" )) { - warn_ambiguous_refs =git_config_bool (var, value); -return 0 ; - } -if (!strcmp (var,"core.abbrev" )) {if (!value)return config_error_nonbool (var);
environment.c +0 -1
@@ -35,7 +35,6 @@ int minimum_abbrev = 4, default_abbrev = -1;int ignore_case;int assume_unchanged;int is_bare_repository_cfg =-1 ;/* unspecified */ -int warn_ambiguous_refs =1 ;int warn_on_object_refname_ambiguity =1 ;int repository_format_precious_objects;char *git_commit_encoding;
environment.h +0 -1
@@ -156,7 +156,6 @@ extern int has_symlinks;extern int minimum_abbrev, default_abbrev;extern int ignore_case;extern int assume_unchanged; -extern int warn_ambiguous_refs;extern int warn_on_object_refname_ambiguity;extern char *apply_default_whitespace;extern char *apply_default_ignorewhitespace;
object-name.c +3 -2
@@ -20,6 +20,7 @@#include "pretty.h" #include "object-store-ll.h" #include "read-cache-ll.h" +#include "repo-settings.h" #include "repository.h" #include "setup.h" #include "midx.h"
@@ -959,7 +960,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,int fatal = !(flags &GET_OID_QUIETLY );if (len == r->hash_algo->hexsz && !get_oid_hex (str, oid)) { -if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) { +if (repo_settings_get_warn_ambiguous_refs (r) && warn_on_object_refname_ambiguity) { refs_found =repo_dwim_ref (r, str, len, &tmp_oid, &real_ref,0 );if (refs_found >0 ) {warning (warn_msg, len, str);
@@ -1020,7 +1021,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,if (!refs_found)return -1 ; -if (warn_ambiguous_refs && !(flags &GET_OID_QUIETLY ) && +if (repo_settings_get_warn_ambiguous_refs (r) && !(flags &GET_OID_QUIETLY ) && (refs_found >1 || !get_short_oid (r, str, len, &tmp_oid,GET_OID_QUIETLY )))warning (warn_msg, len, str);
ref-filter.c +2 -1
@@ -13,6 +13,7 @@#include "object-name.h" #include "object-store-ll.h" #include "oid-array.h" +#include "repo-settings.h" #include "repository.h" #include "commit.h" #include "mailmap.h"
@@ -2160,7 +2161,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname)if (atom->option ==R_SHORT )return refs_shorten_unambiguous_ref (get_main_ref_store (the_repository), refname, - warn_ambiguous_refs); +repo_settings_get_warn_ambiguous_refs (the_repository));else if (atom->option ==R_LSTRIP )return lstrip_ref_components (refname, atom->lstrip);else if (atom->option ==R_RSTRIP )
refs.c +2 -2
@@ -730,7 +730,7 @@ int expand_ref(struct repository *repo, const char *str, int len,if (r) {if (!refs_found++) *ref =xstrdup (r); -if (!warn_ambiguous_refs) +if (!repo_settings_get_warn_ambiguous_refs (repo))break ; }else if ((flag &REF_ISSYMREF ) &&strcmp (fullref.buf,"HEAD" )) {warning (_ ("ignoring dangling symref %s" ), fullref.buf);
@@ -775,7 +775,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len,if (oid)oidcpy (oid, &hash); } -if (!warn_ambiguous_refs) +if (!repo_settings_get_warn_ambiguous_refs (r))break ; }strbuf_release (&path);
repo-settings.c +9 -0
@@ -140,3 +140,12 @@ enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *rereturn LOG_REFS_UNSET ; } + +int repo_settings_get_warn_ambiguous_refs (struct repository *repo) +{ +prepare_repo_settings (repo); +if (repo->settings.warn_ambiguous_refs <0 ) +repo_cfg_bool (repo,"core.warnambiguousrefs" , + &repo->settings.warn_ambiguous_refs,1 ); +return repo->settings.warn_ambiguous_refs; +}
repo-settings.h +4 -0
@@ -56,16 +56,20 @@ struct repo_settings {enum fetch_negotiation_setting fetch_negotiation_algorithm;int core_multi_pack_index; + int warn_ambiguous_refs; /* lazily loaded via accessor */ };#define REPO_SETTINGS_INIT { \ .index_version = -1, \ .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ + .warn_ambiguous_refs = -1, \ }void prepare_repo_settings (struct repository *r);/* Read the value for "core.logAllRefUpdates". */ enum log_refs_config repo_settings_get_log_all_ref_updates (struct repository *repo); +/* Read the value for "core.warnAmbiguousRefs". */ +int repo_settings_get_warn_ambiguous_refs (struct repository *repo);#endif /* REPO_SETTINGS_H */
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
PATCH v2 21/21 environment: stop storing "core.notesRef" globally
In reply to Patrick SteinhardtStop storing the "core.notesRef" config value globally. Instead, retrieve the value in default_notes_ref(). The code is never called in a hot loop anyway, so doing this on every invocation should be perfectly fine.
--- builtin/notes.c | 22 ++++++++++++++-------- config.c | 8 -------- environment.c | 1 - environment.h | 2 -- notes.c | 21 +++++++++++++-------- notes.h | 3 ++- 6 files changed, 29 insertions(+), 28 deletions(-)
builtin/notes.c +14 -8
@@ -897,6 +897,7 @@ static int merge(int argc, const char **argv, const char *prefix) 1, PARSE_OPT_NONEG), OPT_END() }; +char *notes_ref; argc =parse_options (argc, argv, prefix, options, git_notes_merge_usage,0 );
@@ -924,7 +925,8 @@ static int merge(int argc, const char **argv, const char *prefix)if (do_commit)return merge_commit (&o); - o.local_ref =default_notes_ref (); + notes_ref =default_notes_ref (the_repository); + o.local_ref = notes_ref;strbuf_addstr (&remote_ref, argv[0 ]);expand_loose_notes_ref (&remote_ref); o.remote_ref = remote_ref.buf;
@@ -953,7 +955,7 @@ static int merge(int argc, const char **argv, const char *prefix) }strbuf_addf (&msg,"notes: Merged notes from %s into %s" , - remote_ref.buf,default_notes_ref ()); + remote_ref.buf, notes_ref);strbuf_add (&(o.commit_msg), msg.buf +7 , msg.len -7 );/* skip "notes: " */ result =notes_merge (&o, t, &result_oid);
@@ -961,7 +963,7 @@ static int merge(int argc, const char **argv, const char *prefix)if (result >=0 )/* Merge resulted (trivially) in result_oid */ /* Update default notes ref with new commit */ refs_update_ref (get_main_ref_store (the_repository), msg.buf, -default_notes_ref (), &result_oid,NULL ,0 , + notes_ref, &result_oid,NULL ,0 ,UPDATE_REFS_DIE_ON_ERR );else {/* Merge has unresolved conflicts */ struct worktree **worktrees;
@@ -973,14 +975,14 @@ static int merge(int argc, const char **argv, const char *prefix)/* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ worktrees =get_worktrees (); wt =find_shared_symref (worktrees,"NOTES_MERGE_REF" , -default_notes_ref ()); + notes_ref);if (wt)die (_ ("a notes merge into %s is already in-progress at %s" ), -default_notes_ref (), wt->path); + notes_ref, wt->path);free_worktrees (worktrees); -if (refs_update_symref (get_main_ref_store (the_repository),"NOTES_MERGE_REF" ,default_notes_ref (),NULL )) +if (refs_update_symref (get_main_ref_store (the_repository),"NOTES_MERGE_REF" , notes_ref,NULL ))die (_ ("failed to store link to current notes ref (%s)" ), -default_notes_ref ()); + notes_ref); fprintf(stderr, _("Automatic notes merge failed. Fix conflicts in %s " "and commit the result with 'git notes merge --commit', " "or abort the merge with 'git notes merge --abort'.\n"),
@@ -988,6 +990,7 @@ static int merge(int argc, const char **argv, const char *prefix) }free_notes (t); +free (notes_ref);strbuf_release (&remote_ref);strbuf_release (&msg);return result <0 ;/* return non-zero on conflicts */
@@ -1084,6 +1087,7 @@ static int prune(int argc, const char **argv, const char *prefix)static int get_ref (int argc,const char **argv,const char *prefix) {struct option options[] = {OPT_END () }; +char *notes_ref; argc =parse_options (argc, argv, prefix, options, git_notes_get_ref_usage,0 );
@@ -1092,7 +1096,9 @@ static int get_ref(int argc, const char **argv, const char *prefix)usage_with_options (git_notes_get_ref_usage, options); } -puts (default_notes_ref ()); + notes_ref =default_notes_ref (the_repository); +puts (notes_ref); +free (notes_ref);return 0 ; }
config.c +0 -8
@@ -1555,14 +1555,6 @@ static int git_default_core_config(const char *var, const char *value,return git_config_string (&check_roundtrip_encoding, var, value); } -if (!strcmp (var,"core.notesref" )) { -if (!value) -return config_error_nonbool (var); -free (notes_ref_name); - notes_ref_name =xstrdup (value); -return 0 ; - } -if (!strcmp (var,"core.editor" )) {FREE_AND_NULL (editor_program);return git_config_string (&editor_program, var, value);
environment.c +0 -1
@@ -67,7 +67,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS#endif enum object_creation_mode object_creation_mode =OBJECT_CREATION_MODE ; -char *notes_ref_name;int grafts_keep_true_parents;int core_apply_sparse_checkout;int core_sparse_checkout_cone;
environment.h +0 -2
@@ -203,8 +203,6 @@ enum object_creation_mode { };extern enum object_creation_mode object_creation_mode; -extern char *notes_ref_name; -extern int grafts_keep_true_parents;extern int repository_format_precious_objects;
notes.c +13 -8
@@ -992,15 +992,16 @@ static int notes_display_config(const char *k, const char *v,return 0 ; } -const char *default_notes_ref (void ) +char *default_notes_ref (struct repository *repo) { -const char *notes_ref =NULL ; +char *notes_ref =NULL ; +if (!notes_ref) - notes_ref =getenv (GIT_NOTES_REF_ENVIRONMENT ); + notes_ref =xstrdup_or_null (getenv (GIT_NOTES_REF_ENVIRONMENT ));if (!notes_ref) - notes_ref = notes_ref_name;/* value of core.notesRef config */ +repo_config_get_string (repo,"core.notesref" , ¬es_ref);if (!notes_ref) - notes_ref =GIT_NOTES_DEFAULT_REF ; + notes_ref =xstrdup (GIT_NOTES_DEFAULT_REF );return notes_ref; }
@@ -1010,13 +1011,14 @@ void init_notes(struct notes_tree *t, const char *notes_ref,struct object_id oid, object_oid;unsigned short mode;struct leaf_node root_tree; +char *to_free =NULL ;if (!t) t = &default_notes_tree;assert (!t->initialized);if (!notes_ref) - notes_ref =default_notes_ref (); + notes_ref = to_free =default_notes_ref (the_repository);update_ref_namespace (NAMESPACE_NOTES ,xstrdup (notes_ref));if (!combine_notes)
@@ -1033,7 +1035,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,if (flags &NOTES_INIT_EMPTY ||repo_get_oid_treeish (the_repository, notes_ref, &object_oid)) -return ; + goto out;if (flags &NOTES_INIT_WRITABLE &&refs_read_ref (get_main_ref_store (the_repository), notes_ref, &object_oid))die ("Cannot use notes ref %s" , notes_ref);if (get_tree_entry (the_repository, &object_oid,"" , &oid, &mode))
@@ -1043,6 +1045,9 @@ void init_notes(struct notes_tree *t, const char *notes_ref,oidclr (&root_tree.key_oid, the_repository->hash_algo);oidcpy (&root_tree.val_oid, &oid);load_subtree (t, &root_tree, t->root,0 ); + +out: +free (to_free); }struct notes_tree **load_notes_trees (struct string_list *refs,int flags)
@@ -1105,7 +1110,7 @@ void load_display_notes(struct display_notes_opt *opt)if (!opt || opt->use_default_notes >0 || (opt->use_default_notes ==-1 && !opt->extra_notes_refs.nr)) { -string_list_append (&display_notes_refs,default_notes_ref ()); +string_list_append_nodup (&display_notes_refs,default_notes_ref (the_repository)); display_ref_env =getenv (GIT_NOTES_DISPLAY_REF_ENVIRONMENT );if (display_ref_env) { string_list_add_refs_from_colon_sep(&display_notes_refs,
notes.h +2 -1
@@ -4,6 +4,7 @@#include "string-list.h" struct object_id ; +struct repository ;struct strbuf ;/*
@@ -70,7 +71,7 @@ extern struct notes_tree {* 3. The value of the core.notesRef config variable, if set * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits") */ -const char *default_notes_ref (void ); +char *default_notes_ref (struct repository *repo);/* * Flags controlling behaviour of notes tree initialization
Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
Quoted 9 lines · Patrick Steinhardt
Quoted 5 lines · Junio C Hamano
There may be more, but I know at least of these at the moment from
https://github.com/git/git/actions/runs/10619536685/job/29437358521Perhaps this can become [0.5/21] of the series, before globals are hidden behind the macro.
Thanks, I'll add these. I really need to spend some time to finally get Win32 builds set up in GitLab CI.
Windows builds we can get from GitHub Actions already. It would be nice if somebody had Cygwin, which might have avoided a need for <[email protected]>
Thanks.
Quoted 9 lines · Junio C Hamano
Quoted 7 lines · Patrick Steinhardt
Quoted 5 lines · Junio C Hamano
There may be more, but I know at least of these at the moment from
https://github.com/git/git/actions/runs/10619536685/job/29437358521Perhaps this can become [0.5/21] of the series, before globals are hidden behind the macro.
Quoted 6 lines
Quoted 2 lines
Thanks, I'll add these. I really need to spend some time to finally get Win32 builds set up in GitLab CI.
Windows builds we can get from GitHub Actions already. It would be nice if somebody had Cygwin, which might have avoided a need for <[email protected]>
We already have it, yeah. But as I typically only use GitLab CI, I tend to hit the failures on Windows systems when the series is already out there, which requires a roundtrip that would have otherwise been avoided.
In any case, having Cygwin added to the mix in addition certainly would be nice.
Patrick
Re: [PATCH v2 08/21] config: make dependency on repo in `read_early_config()` explicit
In reply to Patrick SteinhardtQuoted 25 lines · Patrick Steinhardt
config.c +1
-3@@ -6,8 +6,6 @@* */ -#define USE_THE_REPOSITORY_VARIABLE -#include "git-compat-util.h" #include "abspath.h" #include "advice.h" @@ -2204,7 +2202,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config (config_fn_t cb,void *data) +void read_early_config (struct repository *repo,config_fn_t cb,void *data) {struct config_options opts = {0 };struct strbuf commondir =STRBUF_INIT ;@@ -2212,9 +2210,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ;
config.c void read_early_config(config_fn_t cb, void *data) · line 2218
Quoted 10 lines
config.c +3
-3-if (have_git_dir ()) { - opts.commondir =repo_get_common_dir (the_repository); - opts.git_dir =repo_get_git_dir (the_repository); +if (repo && repo->gitdir) { + opts.commondir =repo_get_common_dir (repo); + opts.git_dir =repo_get_git_dir (repo);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
It doesn't really matter either way since we perform the same checks, but should we do
if (repo && repo_get_git_dir(repo))
instead of accessing the field directly?
Re: [PATCH v2 20/21] environment: stop storing "core.warnAmbiguousRefs" globally
In reply to Patrick SteinhardtQuoted 9 lines · Patrick Steinhardt
Same as the preceding commits, storing the "core.warnAmbiguousRefs" value globally is misdesigned as this setting may be set per repository.
Move the logic into the repo-settings subsystem. The usual pattern here is that users are expected to call
prepare_repo_settings()before they access the settings themselves. This seems somewhat fragile though, as it is easy to miss and leads to somewhat ugly code patterns at the call sites.
Quoted 4 lines
Instead, introduce a new function that encapsulates this logic for us. This also allows us to change how exactly the lazy initialization works in the future, e.g. by only partially initializing values as requested by the caller.
Cool! prepare_repo_settings() is safe (and seems also reasonably cheap) to execute multiple times.
Quoted 10 lines · Patrick Steinhardt
Hi,
this is the second version of my patch series which guards functions and variables in the environment subsystem that rely on
the_repositorywith theUSE_THE_REPOSITORY_VARIABLEdefine.Changes compared to v1:
- Clean up now-unnecessary and add newly-necessary includes.
Quoted 7 lines
- Stop reordering includes in "
setup.c".- Fix missing
USE_THE_REPOSITORY_VARIABLEdefines in Win32 code.Thanks!
Patrick
Thanks Patrick, this is a nice series of cleanups! I've left a few comments.
Apologies that I haven't been able to review these changes until now -- I've had to take some time off in the past week.
Cheers,
James
Re: [PATCH v2 08/21] config: make dependency on repo in `read_early_config()` explicit
In reply to James LiuQuoted 39 lines · James Liu
Quoted 25 lines · Patrick Steinhardt
config.c +1
-3@@ -6,8 +6,6 @@* */ -#define USE_THE_REPOSITORY_VARIABLE -#include "git-compat-util.h" #include "abspath.h" #include "advice.h" @@ -2204,7 +2202,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config (config_fn_t cb,void *data) +void read_early_config (struct repository *repo,config_fn_t cb,void *data) {struct config_options opts = {0 };struct strbuf commondir =STRBUF_INIT ;@@ -2212,9 +2210,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ;config.c void read_early_config(config_fn_t cb, void *data) · line 2218
Quoted 10 lines
config.c +3
-3-if (have_git_dir ()) { - opts.commondir =repo_get_common_dir (the_repository); - opts.git_dir =repo_get_git_dir (the_repository); +if (repo && repo->gitdir) { + opts.commondir =repo_get_common_dir (repo); + opts.git_dir =repo_get_git_dir (repo);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there It doesn't really matter either way since we perform the same checks, but should we do
Quoted 3 lines
if (repo && repo_get_git_dir(repo))instead of accessing the field directly?
We in fact can't. read_early_config() is typically invoked with the global the_repository. That variable is always set, but its git_dir may not be populated depending on when exactly we call this function and whether or not we are inside a repository. With repo_get_git_dir() we'd now die in scenarios where it's unset, which we do not want.
Patrick
Quoted 17 lines · James Liu
Quoted 16 lines · Patrick Steinhardt
Hi,
this is the second version of my patch series which guards functions and variables in the environment subsystem that rely on
the_repositorywith theUSE_THE_REPOSITORY_VARIABLEdefine.Changes compared to v1:
- Clean up now-unnecessary and add newly-necessary includes.
- Stop reordering includes in "
setup.c".- Fix missing
USE_THE_REPOSITORY_VARIABLEdefines in Win32 code.Thanks!
Quoted 7 lines
Quoted 1 line
Patrick
Thanks Patrick, this is a nice series of cleanups! I've left a few comments.
Apologies that I haven't been able to review these changes until now -- I've had to take some time off in the past week.
No worries, thanks for your review!
Patrick
Re: [PATCH v2 06/21] environment: make `get_git_work_tree()` accept a repository
In reply to Patrick SteinhardtQuoted 8 lines · Patrick Steinhardt
The
get_git_work_tree()function retrieves the path of the work tree ofthe_repository. Make it accept astruct repositorysuch that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance onthe_repositoryand clarifies scope.Signed-off-by Patrick Steinhardt <[email protected]>---
[snip]
repository.c const char *repo_get_graft_file(struct repository *repo) · line 133
Quoted 13 lines
repository.c +5
-0@@ -126,6 +126,11 @@ const char *repo_get_graft_file(struct repository *repo)return repo->graft_file; } +const char *repo_get_work_tree (struct repository *repo) +{ +return repo->worktree; +} +
Now that repo_get_work_tree() is accepting a struct repository, it's only functioning as a simple accessor and seems somewhat unneccesary. Is it preferrable to keep this?
-Justin
Re: [PATCH v2 07/21] config: document `read_early_config()` and `read_very_early_config()`
In reply to Patrick SteinhardtQuoted 31 lines · Patrick Steinhardt
It's not clear what
read_early_config()andread_very_early_config()do differently compared torepo_read_config()from just looking at their names. Document both of these in the header file to clarify their intent.Signed-off-by Patrick Steinhardt <[email protected]>--- config.c | 4 ---- config.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-)config.c +0
-4@@ -2234,10 +2234,6 @@ void read_early_config(config_fn_t cb, void *data)strbuf_release (&gitdir); } -/* -* Read config but only enumerate system and global settings. -* Omit any repo-local, worktree-local, or command-line settings. -*/ void read_very_early_config (config_fn_t cb,void *data) {struct config_options opts = {0 };config.h +0
-0
config.h int git_config_from_blob_oid(config_fn_t fn, const char *name, · line 201
Quoted 10 lines
config.h +6
-0@@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name,void git_config_push_parameter (const char *text);void git_config_push_env (const char *spec);int git_config_from_parameters (config_fn_t fn,void *data); + +/* +* Read config when the Git directory has not yet been set up. In case +* `the_repository` has not yet been set up, try to discover the Git +* directory to read the configuration from. +*/ void read_early_config (config_fn_t cb,void *data);
To restate in my own words, read_early_config() allows a config to be read before the_repository is setup by discovering the git dir itself. Out of curiousity, what prevents us from just ensuring the_repository is properly setup first?
config.h int git_config_from_blob_oid(config_fn_t fn, const char *name, · line 207
Quoted 6 lines
config.h +5
-0+ +/* +* Read config but only enumerate system and global settings. +* Omit any repo-local, worktree-local, or command-line settings. +*/ void read_very_early_config (config_fn_t cb,void *data);
Here read_very_early_config() looks like it only cares about system and global configuration so it doesn't require a git dir or the_repository to be set up. Makes sense.
Not really related to this change, but it would be nice if the name of the function itself was more descript. Something like config_read_system_and_global().
Overall, I find these new comments to be very helpful. Thanks! :)
Re: [PATCH v2 10/21] environment: make `get_git_namespace()` self-contained
In reply to Patrick SteinhardtQuoted 11 lines · Patrick Steinhardt
The logic to set up and retrieve
git_namespaceis distributed across different functions which communicate with each other via a global environment variable. This is rather pointless though, as the value is always derived from an environment variable, and this environment variable does not change after we have parsed global options.Convert the function to be fully self-contained such that it lazily populates once called.
Signed-off-by Patrick Steinhardt <[email protected]>---
[snip]
Quoted 5 lines
environment.c +0
-1@@ -229,9 +204,35 @@ int have_git_dir(void)const char *get_git_namespace (void ) { -if (!git_namespace)
environment.c int have_git_dir(void) · line 214
Quoted 10 lines
environment.c +8
-2-BUG ("git environment hasn't been setup" ); -return git_namespace; +static const char *namespace; + +struct strbuf buf =STRBUF_INIT ; +struct strbuf **components, **c; +const char *raw_namespace; + +if (namespace) +return namespace;
We only initialize namespace once and do it lazily when get_git_namespace() is invoked for the first time. This is nice because we can simplify and remove the git_namespace global.
Makes sense to me.
Quoted 27 lines
environment.c +21
-0+ + raw_namespace =getenv (GIT_NAMESPACE_ENVIRONMENT ); +if (!raw_namespace || !*raw_namespace) { + namespace ="" ; +return namespace; + } + +strbuf_addstr (&buf, raw_namespace); + components =strbuf_split (&buf,'/' ); +strbuf_reset (&buf); +for (c = components; *c; c++) +if (strcmp ((*c)->buf,"/" ) !=0 ) +strbuf_addf (&buf,"refs/namespaces/%s" , (*c)->buf); +strbuf_list_free (components); +if (check_refname_format (buf.buf,0 )) +die (_ ("bad git namespace path \"%s\"" ), raw_namespace); +strbuf_addch (&buf,'/' ); + + namespace =strbuf_detach (&buf,NULL ); + +return namespace; }const char *strip_namespace (const char *namespaced_ref)Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
Re: [PATCH v2 16/21] branch: stop modifying `log_all_ref_updates` variable
In reply to Patrick SteinhardtQuoted 26 lines · Patrick Steinhardt
In "
branch.c" we modify the globallog_all_ref_updatesvariable to force creation of a reflog entry. Modifying global state like this is discouraged, as it may have all kinds of consequences in other places of our codebase.Stop modifying the variable and pass the
REF_FORCE_CREATE_REFLOGflag, which has the same effect.Signed-off-by Patrick Steinhardt <[email protected]>--- branch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)branch.c +1
-0@@ -601,6 +601,7 @@ void create_branch(struct repository *r,int forcing =0 ;struct ref_transaction *transaction;struct strbuf err =STRBUF_INIT ; +int flags =0 ;char *msg;if (track ==BRANCH_TRACK_OVERRIDE )
branch.c void create_branch(struct repository *r, · line 623
Quoted 5 lines
branch.c +1
-1@@ -619,7 +620,7 @@ void create_branch(struct repository *r, goto cleanup;if (reflog) - log_all_ref_updates =LOG_REFS_NORMAL ; + flags |=REF_FORCE_CREATE_REFLOG ;
I'm trying to understand how setting the REF_FORCE_CREATE_REFLOG flag is ultimately equivalent to setting log_all_ref_updates = LOG_REFS_NORMAL.
From my understanding, when log_all_ref_updates is set to LOG_REFS_NORMAL, this is the equivalent to core.logAllRefUpdates=true. This means if a missing reflog file is created for a subset of references[1]. The REF_FORCE_CREATE_REFLOG flag seems more analogous to always value for core.logAllRefUpdates and would create reflogs for all references. Is this not the case? Or does it not really matter?
[1] https://git-scm.com/docs/git-config#Documentation/git-config.txt-corelogAllRefUpdates
Quoted 15 lines
branch.c +1
-1if (forcing) msg =xstrfmt ("branch: Reset to %s" , start_name);@@ -630,7 +631,7 @@ void create_branch(struct repository *r,if (!transaction ||ref_transaction_update (transaction, ref.buf, &oid, forcing ?NULL :null_oid (), -NULL ,NULL ,0 , msg, &err) || +NULL ,NULL , flags, msg, &err) ||ref_transaction_commit (transaction, &err))die ("%s" , err.buf);ref_transaction_free (transaction);Signature · 1 line
2.46.0.421.g159f2d50e7.dirty
Re: [PATCH v2 01/21] environment: make `get_git_dir()` accept a repository
In reply to Patrick SteinhardtPatrick Steinhardt <[email protected]> writes:
[snip]
repository.c static void expand_base_dir(char **out, const char *in, · line 97
Quoted 12 lines
repository.c +4
-0@@ -91,6 +91,13 @@ static void expand_base_dir(char **out, const char *in, *out =xstrfmt ("%s/%s" , base_dir, def_in); } +const char *repo_get_git_dir (struct repository *repo) +{ +if (!repo->gitdir) +BUG ("git environment hasn't been setup" );
Shouldn't this message be more generic now? Since this function can be used with any repository?
repository.c static void expand_base_dir(char **out, const char *in, · line 103
Quoted 6 lines
repository.c +3
-0+return repo->gitdir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
[snip]
Rest of the patch looks good. Thanks
Re: [PATCH v2 09/21] environment: move `odb_mkstemp()` into object layer
In reply to Patrick SteinhardtQuoted 5 lines · Patrick Steinhardt
The
odb_mkstemp()function is quite clearly tied to the object store, but regardless of that it is located in "environment.c". Move it over, which also helps to get rid of dependencies onthe_repositoryin the environment subsystem.
The commit talks only about odb_mkstemp() but the code also moves odb_pack_keep. We should add that here.
[snip]
Re: [PATCH v2 18/21] environment: stop storing "core.logAllRefUpdates" globally
In reply to Patrick SteinhardtPatrick Steinhardt <[email protected]> writes:
[snip]
refs/files-backend.c struct files_ref_store { · line 79
Quoted 10 lines
refs/files-backend.c +1
-0@@ -75,6 +75,7 @@ struct files_ref_store {unsigned int store_flags;char *gitcommondir; +enum log_refs_config log_all_ref_updates;
So we add it to the backend's store and set it when the backend is initiated. Makes sense
[snip]
Quoted 8 lines · Patrick Steinhardt
Hi,
this is the second version of my patch series which guards functions and variables in the environment subsystem that rely on
the_repositorywith theUSE_THE_REPOSITORY_VARIABLEdefine.Changes compared to v1:
Quoted 8 lines
- Clean up now-unnecessary and add newly-necessary includes.
- Stop reordering includes in "
setup.c".- Fix missing
USE_THE_REPOSITORY_VARIABLEdefines in Win32 code.Thanks!
I haven't read v1, but this version reads nicely. I left two comments, and I think the first one applies to the first few patches.
Thanks
[snip]
Re: [PATCH v2 06/21] environment: make `get_git_work_tree()` accept a repository
In reply to Justin ToblerQuoted 18 lines · Justin Tobler
Quoted 8 lines · Patrick Steinhardt
The
get_git_work_tree()function retrieves the path of the work tree ofthe_repository. Make it accept astruct repositorysuch that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance onthe_repositoryand clarifies scope.Signed-off-by Patrick Steinhardt <[email protected]>---
[snip]
Quoted 8 lines
repository.c +0
-0@@ -126,6 +126,11 @@ const char *repo_get_graft_file(struct repository *repo)return repo->graft_file; }
Quoted 9 lines
repository.c const char *repo_get_graft_file(struct repository *repo) · line 133
Quoted 5 lines
repository.c +5
-0+const char *repo_get_work_tree (struct repository *repo) +{ +return repo->worktree; +} +Now that
repo_get_work_tree()is accepting astruct repository, it's only functioning as a simple accessor and seems somewhat unneccesary. Is it preferrable to keep this?
I think it still makes sense to keep it, mostly because we also have accessor functions for the other paths, too. It would feel weirdly asymmetric to have repo_get_git_dir() but not repo_get_work_tree(), in my opinion.
Patrick
Re: [PATCH v2 07/21] config: document `read_early_config()` and `read_very_early_config()`
In reply to Justin ToblerQuoted 39 lines · Justin Tobler
Quoted 38 lines · Patrick Steinhardt
It's not clear what
read_early_config()andread_very_early_config()do differently compared torepo_read_config()from just looking at their names. Document both of these in the header file to clarify their intent.Signed-off-by Patrick Steinhardt <[email protected]>--- config.c | 4 ---- config.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-)config.c +0
-4@@ -2234,10 +2234,6 @@ void read_early_config(config_fn_t cb, void *data)strbuf_release (&gitdir); } -/* -* Read config but only enumerate system and global settings. -* Omit any repo-local, worktree-local, or command-line settings. -*/ void read_very_early_config (config_fn_t cb,void *data) {struct config_options opts = {0 };config.h +4
-0@@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name,void git_config_push_parameter (const char *text);void git_config_push_env (const char *spec);int git_config_from_parameters (config_fn_t fn,void *data); + +/* +* Read config when the Git directory has not yet been set up. In case +* `the_repository` has not yet been set up, try to discover the Git
Quoted 8 lines
config.h int git_config_from_blob_oid(config_fn_t fn, const char *name, · line 201
Quoted 3 lines
config.h +2
-0+* directory to read the configuration from. +*/ void read_early_config (config_fn_t cb,void *data);To restate in my own words,
read_early_config()allows a config to be read beforethe_repositoryis setup by discovering the git dir itself. Out of curiousity, what prevents us from just ensuringthe_repositoryis properly setup first?
This function is mostly called when we may or may not have a repository. This is for example important for alias handling: we want aliases to work when outside a repository, and they are not yet set up at the point in time where we need to resolve such an alias. If you happen to be in a repository, you also want to make its aliases available. If you aren't, you only want to make aliases in your global and system configuration available.
Quoted 11 lines
config.h int git_config_from_blob_oid(config_fn_t fn, const char *name, · line 207
Quoted 6 lines
config.h +5
-0+ +/* +* Read config but only enumerate system and global settings. +* Omit any repo-local, worktree-local, or command-line settings. +*/ void read_very_early_config (config_fn_t cb,void *data);Here
read_very_early_config()looks like it only cares about system and global configuration so it doesn't require a git dir orthe_repositoryto be set up. Makes sense.
Quoted 5 lines
Not really related to this change, but it would be nice if the name of the function itself was more descript. Something like
config_read_system_and_global().Overall, I find these new comments to be very helpful. Thanks! :)
Agreed, the names aren't great. But as you say, I'd rather not fix them as part of this patch series.
Patrick
Re: [PATCH v2 01/21] environment: make `get_git_dir()` accept a repository
In reply to karthik nayakQuoted 12 lines · karthik nayak
Patrick Steinhardt <[email protected]> writes:
[snip]
Quoted 8 lines
repository.c +0
-0@@ -91,6 +91,13 @@ static void expand_base_dir(char **out, const char *in, *out =xstrfmt ("%s/%s" , base_dir, def_in); }
Quoted 7 lines
repository.c static void expand_base_dir(char **out, const char *in, · line 97
Quoted 4 lines
repository.c +4
-0+const char *repo_get_git_dir (struct repository *repo) +{ +if (!repo->gitdir) +BUG ("git environment hasn't been setup" );Shouldn't this message be more generic now? Since this function can be used with any repository?
Good point indeed. I was initially worried that changing it may alter user-visible behaviour. But in theory, calls to BUG() should be unreachable and thus never be encountered in the wild.
Patrick
Re: [PATCH v2 09/21] environment: move `odb_mkstemp()` into object layer
In reply to karthik nayakQuoted 10 lines · karthik nayak
Quoted 5 lines · Patrick Steinhardt
The
odb_mkstemp()function is quite clearly tied to the object store, but regardless of that it is located in "environment.c". Move it over, which also helps to get rid of dependencies onthe_repositoryin the environment subsystem.The commit talks only about
odb_mkstemp()but the code also movesodb_pack_keep. We should add that here.
True, will fix.
Patrick
Re: [PATCH v2 16/21] branch: stop modifying `log_all_ref_updates` variable
In reply to Justin ToblerQuoted 45 lines · Justin Tobler
Quoted 26 lines · Patrick Steinhardt
In "
branch.c" we modify the globallog_all_ref_updatesvariable to force creation of a reflog entry. Modifying global state like this is discouraged, as it may have all kinds of consequences in other places of our codebase.Stop modifying the variable and pass the
REF_FORCE_CREATE_REFLOGflag, which has the same effect.Signed-off-by Patrick Steinhardt <[email protected]>--- branch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)branch.c +1
-0@@ -601,6 +601,7 @@ void create_branch(struct repository *r,int forcing =0 ;struct ref_transaction *transaction;struct strbuf err =STRBUF_INIT ; +int flags =0 ;char *msg;if (track ==BRANCH_TRACK_OVERRIDE )branch.c void create_branch(struct repository *r, · line 623
Quoted 5 lines
branch.c +1
-1@@ -619,7 +620,7 @@ void create_branch(struct repository *r, goto cleanup;if (reflog) - log_all_ref_updates =LOG_REFS_NORMAL ; + flags |=REF_FORCE_CREATE_REFLOG ;I'm trying to understand how setting the
REF_FORCE_CREATE_REFLOGflag is ultimately equivalent to settinglog_all_ref_updates = LOG_REFS_NORMAL.From my understanding, when
log_all_ref_updatesis set toLOG_REFS_NORMAL, this is the equivalent tocore.logAllRefUpdates=true. This means if a missing reflog file is created for a subset of references[1]. TheREF_FORCE_CREATE_REFLOGflag seems more analogous toalwaysvalue forcore.logAllRefUpdatesand would create reflogs for all references. Is this not the case? Or does it not really matter?
Quoted 1 line
[1] https://git-scm.com/docs/git-config#Documentation/git-config.txt-corelogAllRefUpdates
It's not equivalent in general, but in this case it is. Note that we are only talking about branches here, not about arbitrary references. Quoting "core.logAllRefUpdates":
If this configuration variable is set to true, missing "$GIT_DIR/logs/<ref>" file is automatically created for branch heads (i.e. under refs/heads/), remote refs (i.e. under refs/remotes/), note refs (i.e. under refs/notes/), and the symbolic ref HEAD. If it is set to always, then a missing reflog is automatically created for any ref under refs/.
So for branches, "true" and "always" have the same effect on the technical level.
And on the conceptual level, reflog is set whenever "--create-reflog" is passed to git-branch(1), and asks the command to cretae the reflog regardless of "core.logAllRefUpdates".
I'll add this information to the commit message.
Thanks for your review!
Patrick
Quoted 16 lines · karthik nayak
Quoted 14 lines · Patrick Steinhardt
Hi,
this is the second version of my patch series which guards functions and variables in the environment subsystem that rely on
the_repositorywith theUSE_THE_REPOSITORY_VARIABLEdefine.Changes compared to v1:
- Clean up now-unnecessary and add newly-necessary includes.
- Stop reordering includes in "
setup.c".- Fix missing
USE_THE_REPOSITORY_VARIABLEdefines in Win32 code.
Quoted 7 lines
Quoted 2 lines
Thanks!
I haven't read v1, but this version reads nicely. I left two comments, and I think the first one applies to the first few patches.
Thanks
Thanks for your review!
Patrick
v3 cover environment: guard reliance on `the_repository`
In reply to Patrick SteinhardtHi,
this is the third version of my patch series which guards functions and variables in the environment subsystem that rely on the_repository with the USE_THE_REPOSITORY_VARIABLE define.
Changes compared to v2:
- Adapt BUG messages in the first 5 commits to better match the new semantics of this function.
- Adapt commit message to mention that we don't only move over
`odb_mkstemp()`, but also `odb_pack_keep()`.
- Explain why setting REF_FORCE_CREATE_REFLOG is equivalent to setting LOG_REFS_NORMAL.
Thanks!
Patrick
Patrick Steinhardt (21):
environment: make get_git_dir() accept a repository
environment: make get_git_common_dir() accept a repository
environment: make get_object_directory() accept a repository
environment: make get_index_file() accept a repository
environment: make get_graft_file() accept a repository
environment: make get_git_work_tree() accept a repository
config: document read_early_config() and read_very_early_config()
config: make dependency on repo in read_early_config() explicit
environment: move object database functions into object layer
environment: make get_git_namespace() self-contained
environment: move set_git_dir() and related into setup layer
environment: reorder header to split out the_repository-free section
environment: guard state depending on a repository
repo-settings: split out declarations into a standalone header
repo-settings: track defaults close to struct repo_settings
branch: stop modifying log_all_ref_updates variable
refs: stop modifying global log_all_ref_updates variable
environment: stop storing "core.logAllRefUpdates" globally
environment: stop storing "core.preferSymlinkRefs" globally
environment: stop storing "core.warnAmbiguousRefs" globally
environment: stop storing "core.notesRef" globally
alias.c | 6 +- apply.c | 3 +- branch.c | 5 +- builtin/am.c | 13 +- builtin/blame.c | 2 +- builtin/checkout.c | 5 +- builtin/commit-graph.c | 5 +- builtin/commit.c | 13 +- builtin/config.c | 4 +- builtin/count-objects.c | 3 +- builtin/difftool.c | 9 +- builtin/fsmonitor--daemon.c | 7 +- builtin/gc.c | 2 +- builtin/init-db.c | 4 +- builtin/merge.c | 18 +-- builtin/multi-pack-index.c | 4 +- builtin/notes.c | 22 ++-- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 +- builtin/repack.c | 7 +- builtin/replace.c | 3 +- builtin/reset.c | 5 +- builtin/rev-parse.c | 11 +- builtin/stash.c | 17 +-- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 4 +- builtin/worktree.c | 4 +- builtin/write-tree.c | 4 +- bulk-checkin.c | 4 +- bundle-uri.c | 2 +- cache-tree.c | 5 +- commit.c | 4 +- compat/mingw.c | 2 + compat/win32/path-utils.c | 2 + config.c | 42 +------ config.h | 13 +- dir.c | 3 +- environment.c | 237 +++++------------------------------- environment.h | 142 ++++++++++----------- fetch-pack.c | 2 +- fsmonitor.c | 3 +- help.c | 2 +- http-backend.c | 2 +- name-hash.c | 3 + notes.c | 21 ++-- notes.h | 3 +- object-file.c | 37 +++++- object-name.c | 5 +- object-store-ll.h | 15 +++ pack-write.c | 3 +- packfile.c | 2 +- pager.c | 7 +- path.c | 2 + pathspec.c | 4 +- preload-index.c | 3 + prompt.c | 2 + prune-packed.c | 6 +- read-cache.c | 6 +- ref-filter.c | 3 +- refs.c | 9 +- refs.h | 4 +- refs/files-backend.c | 32 +++-- refs/reftable-backend.c | 22 ++-- repo-settings.c | 35 +++++- repo-settings.h | 75 ++++++++++++ repository.c | 40 ++++++ repository.h | 58 ++------- server-info.c | 4 +- setup.c | 140 ++++++++++++++++++--- setup.h | 5 +- sparse-index.c | 2 + statinfo.c | 2 + submodule.c | 2 +- t/helper/test-config.c | 3 +- t/helper/test-path-utils.c | 2 + tmp-objdir.c | 8 +- trace.c | 10 +- trace2/tr2_cfg.c | 4 +- transport-helper.c | 2 +- tree-diff.c | 3 + userdiff.c | 2 + worktree.c | 12 +- wt-status.c | 3 +- 83 files changed, 698 insertions(+), 560 deletions(-) create mode 100644 repo-settings.h
Range-diff against v2:
1: a1969c5b073 ! 1: adeaa5030b4 environment: make get_git_dir() accept a repository
@@ repository.c: static void expand_base_dir(char **out, const char *in,
+const char *repo_get_git_dir(struct repository *repo)
+{
+ if (!repo->gitdir)
-+ BUG("git environment hasn't been setup");
++ BUG("repository hasn't been set up");
+ return repo->gitdir;
+}
+
2: deebf2c5205 ! 2: 2964cfc7790 environment: make `get_git_common_dir()` accept a repository
@@ repository.c: const char *repo_get_git_dir(struct repository *repo)
+const char *repo_get_common_dir(struct repository *repo)
+{
+ if (!repo->commondir)
-+ BUG("git environment hasn't been setup");
++ BUG("repository hasn't been set up");
+ return repo->commondir;
+}
+
3: 43abfa7b139 ! 3: b2edc57163c environment: make `get_object_directory()` accept a repository
@@ repository.c: const char *repo_get_common_dir(struct repository *repo)
+const char *repo_get_object_directory(struct repository *repo)
+{
+ if (!repo->objects->odb)
-+ BUG("git environment hasn't been setup");
++ BUG("repository hasn't been set up");
+ return repo->objects->odb->path;
+}
+
4: d7554cb0fe0 ! 4: f82bee6d04f environment: make `get_index_file()` accept a repository
@@ repository.c: const char *repo_get_object_directory(struct repository *repo)
+const char *repo_get_index_file(struct repository *repo)
+{
+ if (!repo->index_file)
-+ BUG("git environment hasn't been setup");
++ BUG("repository hasn't been set up");
+ return repo->index_file;
+}
+
5: 1cc727e4763 ! 5: e3f3f6391da environment: make `get_graft_file()` accept a repository
@@ repository.c: const char *repo_get_index_file(struct repository *repo)
+const char *repo_get_graft_file(struct repository *repo)
+{
+ if (!repo->graft_file)
-+ BUG("git environment hasn't been setup");
++ BUG("repository hasn't been set up");
+ return repo->graft_file;
+}
+
6: 22e9dcb28a9 = 6: 00950932195 environment: make `get_git_work_tree()` accept a repository
7: ec4804a99bf = 7: 8c0010b4397 config: document `read_early_config()` and `read_very_early_config()`
8: b8aa5dcc0b6 = 8: 1ed3d3f1d71 config: make dependency on repo in `read_early_config()` explicit
9: ac2cc4e0371 ! 9: b164373d10b environment: move `odb_mkstemp()` into object layer @@ Metadata
Author: Patrick Steinhardt <[email protected]>
## Commit message ##
- environment: move odb_mkstemp() into object layer
+ environment: move object database functions into object layer
- The odb_mkstemp() function is quite clearly tied to the object store,
- but regardless of that it is located in "environment.c". Move it over,
- which also helps to get rid of dependencies on the_repository in the
- environment subsystem.
+ The odb_mkstemp() and odb_pack_keep() functions are quite clearly
+ tied to the object store, but regardless of that they are located in
+ "environment.c". Move them over, which also helps to get rid of
+ dependencies on the_repository in the environment subsystem.
10: f0d3794dfc4 = 10: 85c10fad522 environment: make `get_git_namespace()` self-contained 11: 9e0e2528b94 = 11: 437b6f1f30d environment: move `set_git_dir()` and related into setup layer 12: 78f77a006a0 = 12: 8de5b246dad environment: reorder header to split out `the_repository`-free section 13: 9a3f466b530 = 13: 417cca950bf environment: guard state depending on a repository 14: 0d7365c5190 = 14: a9d032b3ec7 repo-settings: split out declarations into a standalone header 15: 231c52ce82f = 15: 7a74c8d8a8d repo-settings: track defaults close to `struct repo_settings` 16: fc30365e1f1 ! 16: b5f3bf5cd25 branch: stop modifying `log_all_ref_updates` variable
@@ Commit message
discouraged, as it may have all kinds of consequences in other places of our codebase.
- Stop modifying the variable and pass the REF_FORCE_CREATE_REFLOG flag,
- which has the same effect.
+ Stop modifying the variable and pass the REF_FORCE_CREATE_REFLOG flag
+ instead. Setting this flag has a stronger meaning than setting the
+ config to LOG_REFS_NORMAL:
+
+ - LOG_REFS_NORMAL will ask us to only create reflog entries for
+ preexisting reflogs or branches, remote refs, note refs and HEAD.
+
+ - REF_FORCE_CREATE_REFLOG will unconditionally create a reflog and
+ is thus equivalent to LOG_REFS_ALWAYS.
+
+ But as we are in create_branch() and thus do not have to worry about
+ arbitrary references, but only about branches, LOG_REFS_NORMAL and
+ LOG_REFS_ALWAYS are indeed equivalent.
17: 9cc8518a02d = 17: 128fefd33a8 refs: stop modifying global `log_all_ref_updates` variable 18: b5ed6928070 = 18: df0f29cfec0 environment: stop storing "core.logAllRefUpdates" globally 19: 194d858877f = 19: e3527e7d73f environment: stop storing "core.preferSymlinkRefs" globally 20: fc6fcebf7f7 = 20: 3c4a9259fbb environment: stop storing "core.warnAmbiguousRefs" globally 21: a0b75c4bc99 = 21: 08672e8a073 environment: stop storing "core.notesRef" globally
base-commit: 17d4b10aea6bda2027047a0e3548a6f8ad667dde
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 1/21 environment: make `get_git_dir()` accept a repository
The get_git_dir() function retrieves the path to the Git directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- apply.c | 3 ++- builtin/am.c | 5 +++-- builtin/commit.c | 7 ++++--- builtin/config.c | 2 +- builtin/difftool.c | 5 +++-- builtin/fsmonitor--daemon.c | 3 ++- builtin/merge.c | 4 +++- builtin/stash.c | 3 ++- cache-tree.c | 5 +++-- config.c | 4 +++- environment.c | 10 ++-------- environment.h | 1 - pathspec.c | 2 +- read-cache.c | 6 ++++-- repository.c | 7 +++++++ repository.h | 2 ++ setup.c | 12 ++++++------ setup.h | 2 +- trace.c | 5 ++++- transport-helper.c | 2 +- worktree.c | 4 ++-- 21 files changed, 56 insertions(+), 38 deletions(-)
apply.c +2 -1
@@ -30,6 +30,7 @@#include "path.h" #include "quote.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "apply.h" #include "entry.h"
@@ -4111,7 +4112,7 @@ static int read_apply_cache(struct apply_state *state) {if (state->index_file)return read_index_from (state->repo->index, state->index_file, -get_git_dir ()); +repo_get_git_dir (the_repository));else return repo_read_index (state->repo); }
builtin/am.c +3 -2
@@ -1544,7 +1544,8 @@ static int run_apply(const struct am_state *state, const char *index_file)if (index_file) {/* Reload index as apply_all_patches() will have modified it. */ discard_index (the_repository->index); -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository)); }return 0 ;
@@ -1587,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pareturn error ("could not build fake ancestor" );discard_index (the_repository->index); -read_index_from (the_repository->index, index_path,get_git_dir ()); +read_index_from (the_repository->index, index_path,repo_get_git_dir (the_repository));if (write_index_as_tree (&bases[0 ], the_repository->index, index_path,0 ,NULL ))return error (_ ("Repository lacks necessary blobs to fall back on 3-way merge." ));
builtin/commit.c +4 -3
@@ -26,6 +26,7 @@#include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "string-list.h" #include "rerere.h" #include "unpack-trees.h"
@@ -407,7 +408,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index);read_index_from (the_repository->index,get_lock_file_path (&index_lock), -get_git_dir ()); +repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,WRITE_TREE_SILENT ) ==0 ) {if (reopen_lock_file (&index_lock) <0 )die (_ ("unable to write index file" ));
@@ -534,7 +535,7 @@ static const char *prepare_index(const char **argv, const char *prefix,discard_index (the_repository->index); ret =get_lock_file_path (&false_lock); -read_index_from (the_repository->index, ret,get_git_dir ()); +read_index_from (the_repository->index, ret,repo_get_git_dir (the_repository)); out:string_list_clear (&partial,0 );clear_pathspec (&pathspec);
@@ -1072,7 +1073,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,*/ discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file,repo_get_git_dir (the_repository));if (cache_tree_update (the_repository->index,0 )) {error (_ ("Error building trees" ));
builtin/config.c +1 -1
@@ -808,7 +808,7 @@ static void location_options_init(struct config_location_options *opts, opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { opts->options.commondir =get_git_common_dir (); - opts->options.git_dir =get_git_dir (); + opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/difftool.c +3 -2
@@ -22,6 +22,7 @@#include "hex.h" #include "parse-options.h" #include "read-cache-ll.h" +#include "repository.h" #include "sparse-index.h" #include "strvec.h" #include "strbuf.h"
@@ -214,7 +215,7 @@ static void changed_files(struct hashmap *result, const char *index_path,struct child_process update_index =CHILD_PROCESS_INIT ;struct child_process diff_files =CHILD_PROCESS_INIT ;struct strbuf buf =STRBUF_INIT ; -const char *git_dir =absolute_path (get_git_dir ()); +const char *git_dir =absolute_path (repo_get_git_dir (the_repository));FILE *fp; strvec_pushl(&update_index.args,
@@ -737,7 +738,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree (); -setenv (GIT_DIR_ENVIRONMENT ,absolute_path (get_git_dir ()),1 ); +setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 );setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -1
@@ -1311,7 +1311,8 @@ static int fsmonitor_run_daemon(void)strbuf_addstr (&state.path_gitdir_watch,"/.git" );if (!is_directory (state.path_gitdir_watch.buf)) {strbuf_reset (&state.path_gitdir_watch); -strbuf_addstr (&state.path_gitdir_watch,absolute_path (get_git_dir ())); +strbuf_addstr (&state.path_gitdir_watch, +absolute_path (repo_get_git_dir (the_repository))); state.nr_paths_watching =2 ; }
builtin/merge.c +3 -1
@@ -17,6 +17,7 @@#include "object-name.h" #include "parse-options.h" #include "lockfile.h" +#include "repository.h" #include "run-command.h" #include "hook.h" #include "diff.h"
@@ -855,7 +856,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)if (invoked_hook)discard_index (the_repository->index); } -read_index_from (the_repository->index, index_file,get_git_dir ()); +read_index_from (the_repository->index, index_file, +repo_get_git_dir (the_repository));strbuf_addbuf (&msg, &merge_msg);if (squash)BUG ("the control must not reach here under --squash" );
builtin/stash.c +2 -1
@@ -19,6 +19,7 @@#include "entry.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "revision.h" #include "setup.h"
@@ -642,7 +643,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" ,absolute_path (get_git_work_tree ()));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" , -absolute_path (get_git_dir ())); +absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );run_command (&cp); }
cache-tree.c +3 -2
@@ -1,7 +1,6 @@#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "environment.h" #include "hex.h" #include "lockfile.h" #include "tree.h"
@@ -12,6 +11,7 @@#include "object-store-ll.h" #include "read-cache-ll.h" #include "replace-object.h" +#include "repository.h" #include "promisor-remote.h" #include "trace.h" #include "trace2.h"
@@ -725,7 +725,8 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,hold_lock_file_for_update (&lock_file, index_path,LOCK_DIE_ON_ERROR ); - entries =read_index_from (index_state, index_path,get_git_dir ()); + entries =read_index_from (index_state, index_path, +repo_get_git_dir (the_repository));if (entries <0 ) { ret =WRITE_TREE_UNREADABLE_INDEX ; goto out;
config.c +3 -1
@@ -6,6 +6,8 @@* */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2212,7 +2214,7 @@ void read_early_config(config_fn_t cb, void *data)if (have_git_dir ()) { opts.commondir =get_git_common_dir (); - opts.git_dir =get_git_dir (); + opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
environment.c +2 -8
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_dir (void ) -{ -if (!the_repository->gitdir) -BUG ("git environment hasn't been setup" ); -return the_repository->gitdir; -} -const char *get_git_common_dir (void ) {if (!the_repository->commondir)
@@ -352,7 +345,8 @@ static void update_relative_gitdir(const char *name UNUSED,const char *new_cwd, void *data UNUSED) { - char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); + char *path = reparent_relative_path(old_cwd, new_cwd, +repo_get_git_dir (the_repository));struct tmp_objdir *tmp_objdir =tmp_objdir_unapply_primary_odb (); trace_printf_key(&trace_setup_key,
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_dir (void );const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );
pathspec.c +1 -1
@@ -497,7 +497,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, copyfrom); hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("%s: '%s' is outside repository at '%s'" ), elt, copyfrom,absolute_path (hint_path)); }
read-cache.c +4 -2
@@ -31,6 +31,7 @@#include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "resolve-undo.h" #include "revision.h" #include "strbuf.h"
@@ -3238,10 +3239,11 @@ static int should_delete_shared_index(const char *shared_index_path)static int clean_shared_index_files (const char *current_hex) {struct dirent *de; -DIR *dir =opendir (get_git_dir ()); +DIR *dir =opendir (repo_get_git_dir (the_repository));if (!dir) -return error_errno (_ ("unable to open git dir: %s" ),get_git_dir ()); +return error_errno (_ ("unable to open git dir: %s" ), +repo_get_git_dir (the_repository));while ((de =readdir (dir)) !=NULL ) {const char *sha1_hex;
repository.c +7 -0
@@ -91,6 +91,13 @@ static void expand_base_dir(char **out, const char *in, *out =xstrfmt ("%s/%s" , base_dir, def_in); } +const char *repo_get_git_dir (struct repository *repo) +{ +if (!repo->gitdir) +BUG ("repository hasn't been set up" ); +return repo->gitdir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +2 -0
@@ -206,6 +206,8 @@ struct repository {extern struct repository *the_repository;#endif +const char *repo_get_git_dir (struct repository *repo); +/* * Define a custom repository layout. Any field can be NULL, which * will default back to the path according to the default layout.
setup.c +6 -6
@@ -149,7 +149,7 @@ char *prefix_path(const char *prefix, int len, const char *path)if (!r) {const char *hint_path =get_git_work_tree ();if (!hint_path) - hint_path =get_git_dir (); + hint_path =repo_get_git_dir (the_repository);die (_ ("'%s' is outside repository at '%s'" ), path,absolute_path (hint_path)); }
@@ -468,7 +468,7 @@ int is_nonbare_repository_dir(struct strbuf *path)int is_inside_git_dir (void ) {if (inside_git_dir <0 ) - inside_git_dir =is_inside_dir (get_git_dir ()); + inside_git_dir =is_inside_dir (repo_get_git_dir (the_repository));return inside_git_dir; }
@@ -1836,7 +1836,7 @@ void check_repository_format(struct repository_format *fmt)struct repository_format repo_fmt =REPOSITORY_FORMAT_INIT ;if (!fmt) fmt = &repo_fmt; -check_repository_format_gently (get_git_dir (), fmt,NULL ); +check_repository_format_gently (repo_get_git_dir (the_repository), fmt,NULL ); startup_info->have_repository =1 ;repo_set_hash_algo (the_repository, fmt->hash_algo);repo_set_compat_hash_algo (the_repository, fmt->compat_hash_algo);
@@ -2224,7 +2224,7 @@ static int create_default_files(const char *template_path,* shared-repository settings, we would need to fix them up. */ if (get_shared_repository ()) { -adjust_shared_perm (get_git_dir ()); +adjust_shared_perm (repo_get_git_dir (the_repository)); }initialize_repository_version (fmt->hash_algo, fmt->ref_storage_format,0 );
@@ -2434,12 +2434,12 @@ int init_db(const char *git_dir, const char *real_git_dir,die (_ ("%s already exists" ), real_git_dir);set_git_dir (real_git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository);separate_git_dir (git_dir, original_git_dir); }else {set_git_dir (git_dir,1 ); - git_dir =get_git_dir (); + git_dir =repo_get_git_dir (the_repository); } startup_info->have_repository =1 ;
setup.h +1 -1
@@ -176,7 +176,7 @@ 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(), +* Check the repository format version in the path found in repo_get_git_dir(the_repository), * 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?".
trace.c +4 -1
@@ -21,9 +21,12 @@* along with this program; if not, see <https://www.gnu.org/licenses/>. */ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "abspath.h" #include "environment.h" +#include "repository.h" #include "quote.h" #include "setup.h" #include "trace.h"
@@ -311,7 +314,7 @@ void trace_repo_setup(void)if (!startup_info->prefix) prefix ="(null)" ; -trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (get_git_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ()));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));
transport-helper.c +1 -1
@@ -143,7 +143,7 @@ static struct child_process *get_helper(struct transport *transport)if (have_git_dir ())strvec_pushf (&helper->env,"%s=%s" , -GIT_DIR_ENVIRONMENT ,get_git_dir ()); +GIT_DIR_ENVIRONMENT ,repo_get_git_dir (the_repository)); helper->trace2_child_class = helper->args.v[0 ];/* "remote-<name>" */
worktree.c +2 -2
@@ -57,7 +57,7 @@ static void add_head_info(struct worktree *wt)static int is_current_worktree (struct worktree *wt) { -char *git_dir =absolute_pathdup (get_git_dir ()); +char *git_dir =absolute_pathdup (repo_get_git_dir (the_repository));const char *wt_git_dir =get_worktree_git_dir (wt);int is_current = !fspathcmp (git_dir,absolute_path (wt_git_dir));free (git_dir);
@@ -171,7 +171,7 @@ struct worktree **get_worktrees(void)const char *get_worktree_git_dir (const struct worktree *wt) {if (!wt) -return get_git_dir (); +return repo_get_git_dir (the_repository);else if (!wt->id)return get_git_common_dir ();else
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 2/21 environment: make `get_git_common_dir()` accept a repository
In reply to Patrick SteinhardtThe get_git_common_dir() function retrieves the path to the common directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/config.c | 2 +- builtin/gc.c | 2 +- builtin/rev-parse.c | 3 ++- builtin/worktree.c | 4 ++-- config.c | 2 +- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + setup.c | 2 +- submodule.c | 2 +- trace.c | 2 +- worktree.c | 8 ++++---- 13 files changed, 22 insertions(+), 21 deletions(-)
builtin/config.c +1 -1
@@ -807,7 +807,7 @@ static void location_options_init(struct config_location_options *opts,else opts->options.respect_includes = opts->respect_includes_opt;if (startup_info->have_repository) { - opts->options.commondir =get_git_common_dir (); + opts->options.commondir =repo_get_common_dir (the_repository); opts->options.git_dir =repo_get_git_dir (the_repository); } }
builtin/gc.c +1 -1
@@ -2132,7 +2132,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priorityget_schedule_cmd (&cmd,NULL );strbuf_addf (&tfilename,"%s/schedule_%s_XXXXXX" , -get_git_common_dir (), frequency); +repo_get_common_dir (the_repository), frequency); tfile =xmks_tempfile (tfilename.buf);strbuf_release (&tfilename);
builtin/rev-parse.c +2 -1
@@ -19,6 +19,7 @@#include "path.h" #include "diff.h" #include "read-cache-ll.h" +#include "repository.h" #include "revision.h" #include "setup.h" #include "split-index.h"
@@ -1042,7 +1043,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--git-common-dir" )) { -print_path (get_git_common_dir (), prefix, format,DEFAULT_RELATIVE_IF_SHARED ); +print_path (repo_get_common_dir (the_repository), prefix, format,DEFAULT_RELATIVE_IF_SHARED );continue ; }if (!strcmp (arg,"--is-inside-git-dir" )) {
builtin/worktree.c +2 -2
@@ -219,7 +219,7 @@ static void prune_worktrees(void) }closedir (dir); -strbuf_add_absolute_path (&main_path,get_git_common_dir ()); +strbuf_add_absolute_path (&main_path,repo_get_common_dir (the_repository));/* massage main worktree absolute path to match 'gitdir' content */ strbuf_strip_suffix (&main_path,"/." );string_list_append_nodup (&kept,strbuf_detach (&main_path,NULL ));
@@ -492,7 +492,7 @@ static int add_worktree(const char *path, const char *refname,strbuf_addf (&sb,"%s/gitdir" , sb_repo.buf);strbuf_realpath (&realpath, sb_git.buf,1 );write_file (sb.buf,"%s" , realpath.buf); -strbuf_realpath (&realpath,get_git_common_dir (),1 ); +strbuf_realpath (&realpath,repo_get_common_dir (the_repository),1 );write_file (sb_git.buf,"gitdir: %s/worktrees/%s" , realpath.buf, name);strbuf_reset (&sb);
config.c +1 -1
@@ -2213,7 +2213,7 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ;if (have_git_dir ()) { - opts.commondir =get_git_common_dir (); + opts.commondir =repo_get_common_dir (the_repository); opts.git_dir =repo_get_git_dir (the_repository);/* * When setup_git_directory() was not yet asked to discover the
environment.c +0 -7
@@ -228,13 +228,6 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_common_dir (void ) -{ -if (!the_repository->commondir) -BUG ("git environment hasn't been setup" ); -return the_repository->commondir; -} -const char *get_git_namespace (void ) {if (!git_namespace)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_git_common_dir (void );const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);
repository.c +7 -0
@@ -98,6 +98,13 @@ const char *repo_get_git_dir(struct repository *repo)return repo->gitdir; } +const char *repo_get_common_dir (struct repository *repo) +{ +if (!repo->commondir) +BUG ("repository hasn't been set up" ); +return repo->commondir; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -207,6 +207,7 @@ extern struct repository *the_repository;#endif const char *repo_get_git_dir (struct repository *repo); +const char *repo_get_common_dir (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +1 -1
@@ -2068,7 +2068,7 @@ static void copy_templates(const char *option_template) goto close_free_return; } -strbuf_addstr (&path,get_git_common_dir ()); +strbuf_addstr (&path,repo_get_common_dir (the_repository));strbuf_complete (&path,'/' );copy_templates_1 (&path, &template_path, dir); close_free_return:
submodule.c +1 -1
@@ -2462,7 +2462,7 @@ void absorb_git_dir_into_superproject(const char *path, }else {/* Is it already absorbed into the superprojects git dir? */ char *real_sub_git_dir =real_pathdup (sub_git_dir,1 ); -char *real_common_git_dir =real_pathdup (get_git_common_dir (),1 ); +char *real_common_git_dir =real_pathdup (repo_get_common_dir (the_repository),1 );if (!starts_with (real_sub_git_dir, real_common_git_dir))relocate_single_git_dir_into_superproject (path, super_prefix);
trace.c +1 -1
@@ -315,7 +315,7 @@ void trace_repo_setup(void) prefix ="(null)" ;trace_printf_key (&trace_setup_key,"setup: git_dir: %s\n" ,quote_crnl (repo_get_git_dir (the_repository))); -trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (get_git_common_dir ())); +trace_printf_key (&trace_setup_key,"setup: git_common_dir: %s\n" ,quote_crnl (repo_get_common_dir (the_repository)));trace_printf_key (&trace_setup_key,"setup: worktree: %s\n" ,quote_crnl (git_work_tree));trace_printf_key (&trace_setup_key,"setup: cwd: %s\n" ,quote_crnl (cwd));trace_printf_key (&trace_setup_key,"setup: prefix: %s\n" ,quote_crnl (prefix));
worktree.c +4 -4
@@ -72,7 +72,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)struct worktree *worktree =NULL ;struct strbuf worktree_path =STRBUF_INIT ; -strbuf_add_real_path (&worktree_path,get_git_common_dir ()); +strbuf_add_real_path (&worktree_path,repo_get_common_dir (the_repository));strbuf_strip_suffix (&worktree_path,"/.git" );CALLOC_ARRAY (worktree,1 );
@@ -143,7 +143,7 @@ static struct worktree **get_worktrees_internal(int skip_reading_head) list[counter++] =get_main_worktree (skip_reading_head); -strbuf_addf (&path,"%s/worktrees" ,get_git_common_dir ()); +strbuf_addf (&path,"%s/worktrees" ,repo_get_common_dir (the_repository)); dir =opendir (path.buf);strbuf_release (&path);if (dir) {
@@ -173,7 +173,7 @@ const char *get_worktree_git_dir(const struct worktree *wt)if (!wt)return repo_get_git_dir (the_repository);else if (!wt->id) -return get_git_common_dir (); +return repo_get_common_dir (the_repository);else return git_common_path ("worktrees/%s" , wt->id); }
@@ -626,7 +626,7 @@ static int is_main_worktree_path(const char *path)strbuf_add_real_path (&target, path);strbuf_strip_suffix (&target,"/.git" ); -strbuf_add_real_path (&maindir,get_git_common_dir ()); +strbuf_add_real_path (&maindir,repo_get_common_dir (the_repository));strbuf_strip_suffix (&maindir,"/.git" ); cmp =fspathcmp (maindir.buf, target.buf);
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 3/21 environment: make `get_object_directory()` accept a repository
In reply to Patrick SteinhardtThe get_object_directory() function retrieves the path to the object directory for the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/commit-graph.c | 5 ++--- builtin/count-objects.c | 3 +-- builtin/multi-pack-index.c | 4 ++-- builtin/pack-objects.c | 2 +- builtin/prune.c | 8 ++++---- builtin/repack.c | 7 ++++--- bulk-checkin.c | 4 ++-- environment.c | 7 ------- environment.h | 1 - fetch-pack.c | 2 +- http-backend.c | 2 +- object-file.c | 4 ++-- pack-write.c | 3 ++- packfile.c | 2 +- prune-packed.c | 6 ++++-- repository.c | 7 +++++++ repository.h | 1 + server-info.c | 4 ++-- setup.c | 2 +- tmp-objdir.c | 8 +++++--- 20 files changed, 43 insertions(+), 39 deletions(-)
builtin/commit-graph.c +2 -3
@@ -1,7 +1,6 @@#include "builtin.h" #include "commit.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h"
@@ -95,7 +94,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)usage_with_options (builtin_commit_graph_verify_usage, options);if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.shallow) flags |=COMMIT_GRAPH_VERIFY_SHALLOW ;if (opts.progress)
@@ -275,7 +274,7 @@ static int graph_write(int argc, const char **argv, const char *prefix)if (opts.reachable + opts.stdin_packs + opts.stdin_commits >1 )die (_ ("use at most one of --reachable, --stdin-commits, or --stdin-packs" ));if (!opts.obj_dir) - opts.obj_dir =get_object_directory (); + opts.obj_dir =repo_get_object_directory (the_repository);if (opts.append) flags |=COMMIT_GRAPH_WRITE_APPEND ;if (opts.split)
builtin/count-objects.c +1 -2
@@ -7,7 +7,6 @@#include "builtin.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "path.h" #include "repository.h"
@@ -116,7 +115,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)report_linked_checkout_garbage (the_repository); } -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), count_loose, count_cruft,NULL ,NULL );if (verbose) {
builtin/multi-pack-index.c +2 -2
@@ -1,7 +1,6 @@#include "builtin.h" #include "abspath.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h"
@@ -9,6 +8,7 @@#include "trace2.h" #include "object-store-ll.h" #include "replace-object.h" +#include "repository.h" #define BUILTIN_MIDX_WRITE_USAGE \ N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \
@@ -63,7 +63,7 @@ static int parse_object_dir(const struct option *opt, const char *arg,char **value = opt->value;free (*value);if (unset) - *value =xstrdup (get_object_directory ()); + *value =xstrdup (repo_get_object_directory (the_repository));else *value =real_pathdup (arg,1 );return 0 ;
builtin/pack-objects.c +1 -1
@@ -3940,7 +3940,7 @@ static int add_loose_object(const struct object_id *oid, const char *path,*/ static void add_unreachable_loose_objects (void ) { -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), add_loose_object,NULL ,NULL ,NULL ); }
builtin/prune.c +4 -4
@@ -193,12 +193,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix) revs.exclude_promisor_objects =1 ; } -for_each_loose_file_in_objdir (get_object_directory (), prune_object, - prune_cruft, prune_subdir, &revs); +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), + prune_object, prune_cruft, prune_subdir, &revs);prune_packed_objects (show_only ?PRUNE_PACKED_DRY_RUN :0 ); -remove_temporary_files (get_object_directory ()); - s =mkpathdup ("%s/pack" ,get_object_directory ()); +remove_temporary_files (repo_get_object_directory (the_repository)); + s =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository));remove_temporary_files (s);free (s);
builtin/repack.c +4 -3
@@ -1240,7 +1240,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)if (write_midx && write_bitmaps) {struct strbuf path =STRBUF_INIT ; -strbuf_addf (&path,"%s/%s_XXXXXX" ,get_object_directory (), +strbuf_addf (&path,"%s/%s_XXXXXX" ,repo_get_object_directory (the_repository),"bitmap-ref-tips" ); refs_snapshot =xmks_tempfile (path.buf);
@@ -1249,7 +1249,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)strbuf_release (&path); } - packdir =mkpathdup ("%s/pack" ,get_object_directory ()); + packdir =mkpathdup ("%s/pack" ,repo_get_object_directory (the_repository)); packtmp_name =xstrfmt (".tmp-%d-pack" , (int )getpid ()); packtmp =mkpathdup ("%s/%s" , packdir, packtmp_name);
@@ -1519,7 +1519,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)unsigned flags =0 ;if (git_env_bool (GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL ,0 )) flags |=MIDX_WRITE_INCREMENTAL ; -write_midx_file (get_object_directory (),NULL ,NULL , flags); +write_midx_file (repo_get_object_directory (the_repository), +NULL ,NULL , flags); } cleanup:
bulk-checkin.c +2 -2
@@ -75,7 +75,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)close (fd); } -strbuf_addf (&packname,"%s/pack/pack-%s." ,get_object_directory (), +strbuf_addf (&packname,"%s/pack/pack-%s." ,repo_get_object_directory (the_repository),hash_to_hex (hash)); finish_tmp_packfile(&packname, state->pack_tmp_name, state->written, state->nr_written,
@@ -113,7 +113,7 @@ static void flush_batch_fsync(void)* to ensure that the data in each new object file is durable before * the final name is visible. */ -strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,get_object_directory ()); +strbuf_addf (&temp_path,"%s/bulk_fsync_XXXXXX" ,repo_get_object_directory (the_repository)); temp =xmks_tempfile (temp_path.buf);fsync_or_die (get_tempfile_fd (temp),get_tempfile_path (temp));delete_tempfile (&temp);
environment.c +0 -7
@@ -273,13 +273,6 @@ const char *get_git_work_tree(void)return the_repository->worktree; } -const char *get_object_directory (void ) -{ -if (!the_repository->objects->odb) -BUG ("git environment hasn't been setup" ); -return the_repository->objects->odb->path; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -const char *get_object_directory (void );char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);
fetch-pack.c +1 -1
@@ -1839,7 +1839,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,string_list_append_nodup (pack_lockfiles,xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), +repo_get_object_directory (the_repository), packname)); }string_list_clear (&packfile_uris,0 );
http-backend.c +1 -1
@@ -601,7 +601,7 @@ static void get_head(struct strbuf *hdr, char *arg UNUSED) static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { -size_t objdirlen =strlen (get_object_directory ()); +size_t objdirlen =strlen (repo_get_object_directory (the_repository));struct strbuf buf =STRBUF_INIT ;struct packed_git *p;size_t cnt =0 ;
object-file.c +2 -2
@@ -2053,7 +2053,7 @@ static int start_loose_object_common(struct strbuf *tmp_file,else if (errno ==EACCES )return error (_ ("insufficient permission for adding " "an object to repository database %s" ), -get_object_directory ()); +repo_get_object_directory (the_repository));else return error_errno (_ ("unable to create temporary file" ));
@@ -2228,7 +2228,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,prepare_loose_object_bulk_checkin ();/* Since oid is not determined, save tmp file to odb path. */ -strbuf_addf (&filename,"%s/" ,get_object_directory ()); +strbuf_addf (&filename,"%s/" ,repo_get_object_directory (the_repository)); hdrlen =format_object_header (hdr,sizeof (hdr),OBJ_BLOB , len);/*
pack-write.c +2 -1
@@ -12,6 +12,7 @@#include "pack-objects.h" #include "pack-revindex.h" #include "path.h" +#include "repository.h" #include "strbuf.h" void reset_pack_idx_option (struct pack_idx_option *opts)
@@ -473,7 +474,7 @@ char *index_pack_lockfile(int ip_out, int *is_well_formed) packname[len-1 ] =0 ;if (skip_prefix (packname,"keep\t" , &name))return xstrfmt ("%s/pack/pack-%s.keep" , -get_object_directory (), name); +repo_get_object_directory (the_repository), name);return NULL ; }if (is_well_formed)
packfile.c +1 -1
@@ -30,7 +30,7 @@ char *odb_pack_name(struct strbuf *buf, const char *ext) {strbuf_reset (buf); -strbuf_addf (buf,"%s/pack/pack-%s.%s" ,get_object_directory (), +strbuf_addf (buf,"%s/pack/pack-%s.%s" ,repo_get_object_directory (the_repository),hash_to_hex (hash), ext);return buf->buf; }
prune-packed.c +4 -2
@@ -1,10 +1,12 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" -#include "environment.h" #include "gettext.h" #include "object-store-ll.h" #include "packfile.h" #include "progress.h" #include "prune-packed.h" +#include "repository.h" static struct progress *progress;
@@ -37,7 +39,7 @@ void prune_packed_objects(int opts)if (opts &PRUNE_PACKED_VERBOSE ) progress =start_delayed_progress (_ ("Removing duplicate objects" ),256 ); -for_each_loose_file_in_objdir (get_object_directory (), +for_each_loose_file_in_objdir (repo_get_object_directory (the_repository), prune_object,NULL , prune_subdir, &opts);/* Ensure we show 100% before finishing progress */
repository.c +7 -0
@@ -105,6 +105,13 @@ const char *repo_get_common_dir(struct repository *repo)return repo->commondir; } +const char *repo_get_object_directory (struct repository *repo) +{ +if (!repo->objects->odb) +BUG ("repository hasn't been set up" ); +return repo->objects->odb->path; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -208,6 +208,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo); +const char *repo_get_object_directory (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
server-info.c +2 -2
@@ -2,7 +2,6 @@#include "git-compat-util.h" #include "dir.h" -#include "environment.h" #include "hex.h" #include "repository.h" #include "refs.h"
@@ -342,7 +341,8 @@ static int write_pack_info_file(struct update_info_ctx *uic)static int update_info_packs (int force) { -char *infofile =mkpathdup ("%s/info/packs" ,get_object_directory ()); +char *infofile =mkpathdup ("%s/info/packs" , +repo_get_object_directory (the_repository));int ret;init_pack_info (infofile, force);
setup.c +1 -1
@@ -2282,7 +2282,7 @@ static void create_object_directory(void)struct strbuf path =STRBUF_INIT ;size_t baselen; -strbuf_addstr (&path,get_object_directory ()); +strbuf_addstr (&path,repo_get_object_directory (the_repository)); baselen = path.len;safe_create_dir (path.buf,1 );
tmp-objdir.c +5 -3
@@ -13,6 +13,7 @@#include "strvec.h" #include "quote.h" #include "object-store-ll.h" +#include "repository.h" struct tmp_objdir {struct strbuf path;
@@ -132,7 +133,8 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix)* can recognize any stale objdirs left behind by a crash and delete * them. */ -strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" ,get_object_directory (), prefix); +strbuf_addf (&t->path,"%s/tmp_objdir-%s-XXXXXX" , +repo_get_object_directory (the_repository), prefix);if (!mkdtemp (t->path.buf)) {/* free, not destroy, as we never touched the filesystem */
@@ -152,7 +154,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) }env_append (&t->env,ALTERNATE_DB_ENVIRONMENT , -absolute_path (get_object_directory ())); +absolute_path (repo_get_object_directory (the_repository)));env_replace (&t->env,DB_ENVIRONMENT ,absolute_path (t->path.buf));env_replace (&t->env,GIT_QUARANTINE_ENVIRONMENT ,absolute_path (t->path.buf));
@@ -267,7 +269,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t) }strbuf_addbuf (&src, &t->path); -strbuf_addstr (&dst,get_object_directory ()); +strbuf_addstr (&dst,repo_get_object_directory (the_repository)); ret =migrate_paths (&src, &dst);
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 4/21 environment: make `get_index_file()` accept a repository
In reply to Patrick SteinhardtThe get_index_file() function retrieves the path to the index file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/am.c | 8 ++++++-- builtin/commit.c | 6 +++--- builtin/merge.c | 14 ++++++++------ builtin/stash.c | 12 ++++++------ builtin/update-index.c | 2 +- builtin/write-tree.c | 4 ++-- environment.c | 7 ------- environment.h | 1 - repository.c | 7 +++++++ repository.h | 1 + wt-status.c | 3 ++- 11 files changed, 36 insertions(+), 29 deletions(-)
builtin/am.c +6 -2
@@ -1668,7 +1668,9 @@ static void do_commit(const struct am_state *state)if (!state->no_verify &&run_hooks (the_repository,"pre-applypatch" ))exit (1 ); -if (write_index_as_tree (&tree, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&tree, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" ));if (!repo_get_oid_commit (the_repository,"HEAD" , &parent)) {
@@ -2078,7 +2080,9 @@ static int clean_index(const struct object_id *head, const struct object_id *remif (fast_forward_to (head_tree, head_tree,1 ))return -1 ; -if (write_index_as_tree (&index, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (&index, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))return -1 ; index_tree =parse_tree_indirect (&index);
builtin/commit.c +3 -3
@@ -473,7 +473,7 @@ static const char *prepare_index(const char **argv, const char *prefix, COMMIT_LOCK | SKIP_IF_UNCHANGED))die (_ ("unable to write new index file" )); commit_style =COMMIT_AS_IS ; - ret =get_index_file (); + ret =repo_get_index_file (the_repository); goto out; }
@@ -1874,8 +1874,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)repo_rerere (the_repository,0 );run_auto_maintenance (quiet); -run_commit_hook (use_editor,get_index_file (),NULL ,"post-commit" , -NULL ); +run_commit_hook (use_editor,repo_get_index_file (the_repository), +NULL ,"post-commit" ,NULL );if (amend && !no_post_rewrite) {commit_post_rewrite (the_repository, current_head, &oid); }
builtin/merge.c +8 -6
@@ -696,7 +696,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,static void write_tree_trivial (struct object_id *oid) { -if (write_index_as_tree (oid, the_repository->index,get_index_file (),0 ,NULL )) +if (write_index_as_tree (oid, the_repository->index, +repo_get_index_file (the_repository), +0 ,NULL ))die (_ ("git write-tree failed to write a tree" )); }
@@ -758,7 +760,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, }if (write_locked_index (the_repository->index, &lock,COMMIT_LOCK |SKIP_IF_UNCHANGED )) -die (_ ("unable to write %s" ),get_index_file ()); +die (_ ("unable to write %s" ),repo_get_index_file (the_repository));return clean ?0 :1 ; }else { return try_merge_command(the_repository,
@@ -840,7 +842,7 @@ static void write_merge_heads(struct commit_list *);static void prepare_to_commit (struct commit_list *remoteheads) {struct strbuf msg =STRBUF_INIT ; -const char *index_file =get_index_file (); +const char *index_file =repo_get_index_file (the_repository);if (!no_verify) {int invoked_hook;
@@ -880,8 +882,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)append_signoff (&msg,ignored_log_message_bytes (msg.buf, msg.len),0 );write_merge_heads (remoteheads);write_file_buf (git_path_merge_msg (the_repository), msg.buf, msg.len); -if (run_commit_hook (0 < option_edit,get_index_file (),NULL , -"prepare-commit-msg" , +if (run_commit_hook (0 < option_edit,repo_get_index_file (the_repository), +NULL ,"prepare-commit-msg" ,git_path_merge_msg (the_repository),"merge" ,NULL ))abort_commit (remoteheads,NULL );if (0 < option_edit) {
@@ -889,7 +891,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)abort_commit (remoteheads,NULL ); } -if (!no_verify &&run_commit_hook (0 < option_edit,get_index_file (), +if (!no_verify &&run_commit_hook (0 < option_edit,repo_get_index_file (the_repository),NULL ,"commit-msg" ,git_path_merge_msg (the_repository),NULL ))abort_commit (remoteheads,NULL );
builtin/stash.c +6 -6
@@ -540,8 +540,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, NULL, NULL, NULL))return error (_ ("could not write index" )); -if (write_index_as_tree (&c_tree, the_repository->index,get_index_file (),0 , -NULL )) +if (write_index_as_tree (&c_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("cannot apply a stash in the middle of a merge" ));if (index) {
@@ -566,7 +566,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,discard_index (the_repository->index);repo_read_index (the_repository);if (write_index_as_tree (&index_tree, the_repository->index, -get_index_file (),0 ,NULL )) +repo_get_index_file (the_repository),0 ,NULL ))return error (_ ("could not save index tree" ));reset_head ();
@@ -1406,8 +1406,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_bstrbuf_addf (&commit_tree_label,"index on %s\n" , msg.buf);commit_list_insert (head_commit, &parents); -if (write_index_as_tree (&info->i_tree, the_repository->index,get_index_file (),0 , -NULL ) || +if (write_index_as_tree (&info->i_tree, the_repository->index, +repo_get_index_file (the_repository),0 ,NULL ) ||commit_tree (commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit,NULL ,NULL )) {if (!quiet)
@@ -1905,7 +1905,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - index_file =get_index_file (); + index_file =repo_get_index_file (the_repository);strbuf_addf (&stash_index_path,"%s.stash.%" PRIuMAX, index_file, (uintmax_t )pid);
builtin/update-index.c +1 -1
@@ -1239,7 +1239,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)if (newfd <0 ) {if (refresh_args.flags &REFRESH_QUIET )exit (128 ); -unable_to_lock_die (get_index_file (), lock_error); +unable_to_lock_die (repo_get_index_file (the_repository), lock_error); }if (write_locked_index (the_repository->index, &lock_file,COMMIT_LOCK ))die ("Unable to write new index file" );
builtin/write-tree.c +2 -2
@@ -6,7 +6,6 @@#include "builtin.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h"
@@ -44,7 +43,8 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix)prepare_repo_settings (the_repository); the_repository->settings.command_requires_full_index =0 ; - ret =write_index_as_tree (&oid, the_repository->index,get_index_file (), + ret =write_index_as_tree (&oid, the_repository->index, +repo_get_index_file (the_repository), flags, tree_prefix);switch (ret) {case 0 :
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_index_file (void ) -{ -if (!the_repository->index_file) -BUG ("git environment hasn't been setup" ); -return the_repository->index_file; -} -char *get_graft_file (struct repository *r) {if (!r->graft_file)
environment.h +0 -1
@@ -106,7 +106,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_index_file (void );char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );
repository.c +7 -0
@@ -112,6 +112,13 @@ const char *repo_get_object_directory(struct repository *repo)return repo->objects->odb->path; } +const char *repo_get_index_file (struct repository *repo) +{ +if (!repo->index_file) +BUG ("repository hasn't been set up" ); +return repo->index_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -209,6 +209,7 @@ extern struct repository *the_repository;const char *repo_get_git_dir (struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo); +const char *repo_get_index_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
wt-status.c +2 -1
@@ -16,6 +16,7 @@#include "revision.h" #include "diffcore.h" #include "quote.h" +#include "repository.h" #include "run-command.h" #include "strvec.h" #include "remote.h"
@@ -152,7 +153,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) "HEAD", 0, NULL, NULL); s->reference ="HEAD" ; s->fp = stdout; - s->index_file =get_index_file (); + s->index_file =repo_get_index_file (the_repository); s->change.strdup_strings =1 ; s->untracked.strdup_strings =1 ; s->ignored.strdup_strings =1 ;
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 5/21 environment: make `get_graft_file()` accept a repository
In reply to Patrick SteinhardtThe get_graft_file() function retrieves the path to the graft file of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/replace.c | 3 +-- commit.c | 4 ++-- environment.c | 7 ------- environment.h | 2 -- repository.c | 7 +++++++ repository.h | 1 + 6 files changed, 11 insertions(+), 13 deletions(-)
builtin/replace.c +1 -2
@@ -11,7 +11,6 @@#include "builtin.h" #include "config.h" #include "editor.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h"
@@ -514,7 +513,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)static int convert_graft_file (int force) { -const char *graft_file =get_graft_file (the_repository); +const char *graft_file =repo_get_graft_file (the_repository);FILE *fp =fopen_or_warn (graft_file,"r" );struct strbuf buf =STRBUF_INIT , err =STRBUF_INIT ;struct strvec args =STRVEC_INIT ;
commit.c +2 -2
@@ -292,14 +292,14 @@ static int read_graft_file(struct repository *r, const char *graft_file)void prepare_commit_graft (struct repository *r) { -char *graft_file; +const char *graft_file;if (r->parsed_objects->commit_graft_prepared)return ;if (!startup_info->have_repository)return ; - graft_file =get_graft_file (r); + graft_file =repo_get_graft_file (r);read_graft_file (r, graft_file);/* make sure shallows are read */ is_repository_shallow (r);
environment.c +0 -7
@@ -306,13 +306,6 @@ int odb_pack_keep(const char *name)return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); } -char *get_graft_file (struct repository *r) -{ -if (!r->graft_file) -BUG ("git environment hasn't been setup" ); -return r->graft_file; -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -2
@@ -1,7 +1,6 @@#ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct repository ;struct strvec ;/*
@@ -106,7 +105,6 @@ int have_git_dir(void);extern int is_bare_repository_cfg;int is_bare_repository (void );extern char *git_work_tree_cfg; -char *get_graft_file (struct repository *r);void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref);
repository.c +7 -0
@@ -119,6 +119,13 @@ const char *repo_get_index_file(struct repository *repo)return repo->index_file; } +const char *repo_get_graft_file (struct repository *repo) +{ +if (!repo->graft_file) +BUG ("repository hasn't been set up" ); +return repo->graft_file; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -210,6 +210,7 @@ const char *repo_get_git_dir(struct repository *repo);const char *repo_get_common_dir (struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo); +const char *repo_get_graft_file (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 6/21 environment: make `get_git_work_tree()` accept a repository
In reply to Patrick SteinhardtThe get_git_work_tree() function retrieves the path of the work tree of the_repository. Make it accept a struct repository such that it can work on arbitrary repositories and make it part of the repository subsystem. This reduces our reliance on the_repository and clarifies scope.
--- builtin/blame.c | 2 +- builtin/difftool.c | 4 ++-- builtin/fsmonitor--daemon.c | 4 ++-- builtin/init-db.c | 4 ++-- builtin/reset.c | 5 +++-- builtin/rev-parse.c | 4 ++-- builtin/stash.c | 2 +- builtin/submodule--helper.c | 2 +- builtin/update-index.c | 2 +- dir.c | 3 ++- environment.c | 7 +------ environment.h | 1 - fsmonitor.c | 3 ++- pathspec.c | 2 +- repository.c | 5 +++++ repository.h | 1 + setup.c | 16 ++++++++-------- trace.c | 3 +-- 18 files changed, 36 insertions(+), 34 deletions(-)
builtin/blame.c +1 -1
@@ -1081,7 +1081,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) path =add_prefix (prefix, argv[1 ]); argv[1 ] = argv[2 ]; }else {/* (2a) */ -if (argc ==2 &&is_a_rev (argv[1 ]) && !get_git_work_tree ()) +if (argc ==2 &&is_a_rev (argv[1 ]) && !repo_get_work_tree (the_repository))die ("missing <path> to blame" ); path =add_prefix (prefix, argv[argc -1 ]); }
builtin/difftool.c +2 -2
@@ -378,7 +378,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,struct hashmap wt_modified, tmp_modified;int indices_loaded =0 ; - workdir =get_git_work_tree (); + workdir =repo_get_work_tree (the_repository);/* Setup temp directories */ tmp =getenv ("TMPDIR" );
@@ -739,7 +739,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)if (!no_index){setup_work_tree ();setenv (GIT_DIR_ENVIRONMENT ,absolute_path (repo_get_git_dir (the_repository)),1 ); -setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (get_git_work_tree ()),1 ); +setenv (GIT_WORK_TREE_ENVIRONMENT ,absolute_path (repo_get_work_tree (the_repository)),1 ); }else if (dir_diff)die (_ ("options '%s' and '%s' cannot be used together" ),"--dir-diff" ,"--no-index" );
builtin/fsmonitor--daemon.c +2 -2
@@ -2,7 +2,6 @@#include "abspath.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h"
@@ -1291,7 +1290,8 @@ static int fsmonitor_run_daemon(void)/* Prepare to (recursively) watch the <worktree-root> directory. */ strbuf_init (&state.path_worktree_watch,0 ); -strbuf_addstr (&state.path_worktree_watch,absolute_path (get_git_work_tree ())); +strbuf_addstr (&state.path_worktree_watch, +absolute_path (repo_get_work_tree (the_repository))); state.nr_paths_watching =1 ;strbuf_init (&state.alias.alias,0 );
builtin/init-db.c +2 -2
@@ -231,9 +231,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)set_git_work_tree (work_tree); elseset_git_work_tree (git_work_tree_cfg ); -if (access (get_git_work_tree (),X_OK )) +if (access (repo_get_work_tree (the_repository),X_OK ))die_errno (_ ("Cannot access work tree '%s'" ), -get_git_work_tree ()); +repo_get_work_tree (the_repository)); }else {if (real_git_dir)
builtin/reset.c +3 -2
@@ -26,6 +26,7 @@#include "object-name.h" #include "parse-options.h" #include "path.h" +#include "repository.h" #include "unpack-trees.h" #include "cache-tree.h" #include "setup.h"
@@ -441,7 +442,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)else trace2_cmd_mode (reset_type_names[reset_type]); -if (reset_type !=SOFT && (reset_type !=MIXED ||get_git_work_tree ())) +if (reset_type !=SOFT && (reset_type !=MIXED ||repo_get_work_tree (the_repository)))setup_work_tree ();if (reset_type ==MIXED &&is_bare_repository ())
@@ -474,7 +475,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) goto cleanup; } the_repository->index->updated_skipworktree =1 ; -if (!no_refresh &&get_git_work_tree ()) { +if (!no_refresh &&repo_get_work_tree (the_repository)) {uint64_t t_begin, t_delta_in_ms; t_begin =getnanotime ();
builtin/rev-parse.c +2 -2
@@ -967,7 +967,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--show-toplevel" )) { -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);if (work_tree)print_path (work_tree, prefix, format,DEFAULT_UNMODIFIED );else
@@ -992,7 +992,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)const char *pfx = prefix;if (!is_inside_work_tree ()) {const char *work_tree = -get_git_work_tree (); +repo_get_work_tree (the_repository);if (work_tree)printf ("%s\n" , work_tree);continue ;
builtin/stash.c +1 -1
@@ -641,7 +641,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, cp.git_cmd =1 ; cp.dir = prefix;strvec_pushf (&cp.env,GIT_WORK_TREE_ENVIRONMENT "=%s" , -absolute_path (get_git_work_tree ())); +absolute_path (repo_get_work_tree (the_repository)));strvec_pushf (&cp.env,GIT_DIR_ENVIRONMENT "=%s" ,absolute_path (repo_get_git_dir (the_repository)));strvec_push (&cp.args,"status" );
builtin/submodule--helper.c +1 -1
@@ -1709,7 +1709,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,exit (128 );if (!is_absolute_path (clone_data->path)) - clone_data_path = to_free =xstrfmt ("%s/%s" ,get_git_work_tree (), + clone_data_path = to_free =xstrfmt ("%s/%s" ,repo_get_work_tree (the_repository), clone_data->path);if (validate_submodule_git_dir (sm_gitdir, clone_data->name) <0 )
builtin/update-index.c +1 -1
@@ -1194,7 +1194,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)"remove or change it, if you really want to " "enable the untracked cache"));add_untracked_cache (the_repository->index); -report (_ ("Untracked cache enabled for '%s'" ),get_git_work_tree ()); +report (_ ("Untracked cache enabled for '%s'" ),repo_get_work_tree (the_repository));break ;default :BUG ("bad untracked_cache value: %d" , untracked_cache);
dir.c +2 -1
@@ -20,6 +20,7 @@#include "object-store-ll.h" #include "path.h" #include "refs.h" +#include "repository.h" #include "wildmatch.h" #include "pathspec.h" #include "utf8.h"
@@ -2838,7 +2839,7 @@ static const char *get_ident_string(void)return sb.buf;if (uname (&uts) <0 )die_errno (_ ("failed to get kernel name and information" )); -strbuf_addf (&sb,"Location %s, system %s" ,get_git_work_tree (), +strbuf_addf (&sb,"Location %s, system %s" ,repo_get_work_tree (the_repository), uts.sysname);return sb.buf; }
environment.c +1 -6
@@ -219,7 +219,7 @@ void setup_git_env(const char *git_dir)int is_bare_repository (void ) {/* if core.bare is not 'false', let's see if there is a work tree */ -return is_bare_repository_cfg && !get_git_work_tree (); +return is_bare_repository_cfg && !repo_get_work_tree (the_repository); }int have_git_dir (void )
@@ -268,11 +268,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -const char *get_git_work_tree (void ) -{ -return the_repository->worktree; -} -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) {int fd;
environment.h +0 -1
@@ -108,7 +108,6 @@ extern char *git_work_tree_cfg;void set_git_dir (const char *path,int make_realpath);const char *get_git_namespace (void );const char *strip_namespace (const char *namespaced_ref); -const char *get_git_work_tree (void );void set_git_work_tree (const char *tree);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
fsmonitor.c +2 -1
@@ -8,6 +8,7 @@#include "fsmonitor.h" #include "fsmonitor-ipc.h" #include "name-hash.h" +#include "repository.h" #include "run-command.h" #include "strbuf.h" #include "trace2.h"
@@ -169,7 +170,7 @@ static int query_fsmonitor_hook(struct repository *r,strvec_pushf (&cp.args,"%d" , version);strvec_pushf (&cp.args,"%s" , last_update); cp.use_shell =1 ; - cp.dir =get_git_work_tree (); + cp.dir =repo_get_work_tree (the_repository);trace2_region_enter ("fsm_hook" ,"query" ,NULL );
pathspec.c +1 -1
@@ -495,7 +495,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,if (!have_git_dir ())die (_ ("'%s' is outside the directory tree" ), copyfrom); - hint_path =get_git_work_tree (); + hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("%s: '%s' is outside repository at '%s'"), elt,
repository.c +5 -0
@@ -126,6 +126,11 @@ const char *repo_get_graft_file(struct repository *repo)return repo->graft_file; } +const char *repo_get_work_tree (struct repository *repo) +{ +return repo->worktree; +} +static void repo_set_commondir (struct repository *repo,const char *commondir) {
repository.h +1 -0
@@ -211,6 +211,7 @@ const char *repo_get_common_dir(struct repository *repo);const char *repo_get_object_directory (struct repository *repo);const char *repo_get_index_file (struct repository *repo);const char *repo_get_graft_file (struct repository *repo); +const char *repo_get_work_tree (struct repository *repo);/* * Define a custom repository layout. Any field can be NULL, which
setup.c +8 -8
@@ -51,7 +51,7 @@ static int abspath_part_inside_repo(char *path)size_t wtlen;char *path0;int off; -const char *work_tree =precompose_string_if_needed (get_git_work_tree ()); +const char *work_tree =precompose_string_if_needed (repo_get_work_tree (the_repository));struct strbuf realpath =STRBUF_INIT ;if (!work_tree)
@@ -147,7 +147,7 @@ char *prefix_path(const char *prefix, int len, const char *path) {char *r =prefix_path_gently (prefix, len,NULL , path);if (!r) { -const char *hint_path =get_git_work_tree (); +const char *hint_path =repo_get_work_tree (the_repository);if (!hint_path) hint_path =repo_get_git_dir (the_repository); die(_("'%s' is outside repository at '%s'"), path,
@@ -475,7 +475,7 @@ int is_inside_git_dir(void)int is_inside_work_tree (void ) {if (inside_work_tree <0 ) - inside_work_tree =is_inside_dir (get_git_work_tree ()); + inside_work_tree =is_inside_dir (repo_get_work_tree (the_repository));return inside_work_tree; }
@@ -490,7 +490,7 @@ void setup_work_tree(void)if (work_tree_config_is_bogus)die (_ ("unable to set up work tree using invalid config" )); - work_tree =get_git_work_tree (); + work_tree =repo_get_work_tree (the_repository);if (!work_tree ||chdir_notify (work_tree))die (_ ("this operation must be run in a work tree" ));
@@ -547,7 +547,7 @@ static void setup_original_cwd(void)* Get our worktree; we only protect the current working directory * if it's in the worktree. */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository);if (!worktree) goto no_prevention_needed;
@@ -1062,9 +1062,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,set_git_work_tree ("." );/* set_git_work_tree() must have been called by now */ - worktree =get_git_work_tree (); + worktree =repo_get_work_tree (the_repository); -/* both get_git_work_tree() and cwd are already normalized */ +/* both repo_get_work_tree() and cwd are already normalized */ if (!strcmp (cwd->buf, worktree)) {/* cwd == worktree */ set_git_dir (gitdirenv,0 );free (gitfile);
@@ -2192,7 +2192,7 @@ static int create_default_files(const char *template_path,char *path;int reinit;int filemode; -const char *work_tree =get_git_work_tree (); +const char *work_tree =repo_get_work_tree (the_repository);/* * First copy the templates -- we might have the default
trace.c +1 -2
@@ -25,7 +25,6 @@#include "git-compat-util.h" #include "abspath.h" -#include "environment.h" #include "repository.h" #include "quote.h" #include "setup.h"
@@ -308,7 +307,7 @@ void trace_repo_setup(void) cwd =xgetcwd (); -if (!(git_work_tree =get_git_work_tree ())) +if (!(git_work_tree =repo_get_work_tree (the_repository))) git_work_tree ="(null)" ;if (!startup_info->prefix)
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 7/21 config: document `read_early_config()` and `read_very_early_config()`
In reply to Patrick SteinhardtIt's not clear what read_early_config() and read_very_early_config() do differently compared to repo_read_config() from just looking at their names. Document both of these in the header file to clarify their intent.
--- config.c | 4 ---- config.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-)
config.c +0 -4
@@ -2234,10 +2234,6 @@ void read_early_config(config_fn_t cb, void *data)strbuf_release (&gitdir); } -/* -* Read config but only enumerate system and global settings. -* Omit any repo-local, worktree-local, or command-line settings. -*/ void read_very_early_config (config_fn_t cb,void *data) {struct config_options opts = {0 };
config.h +11 -0
@@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name,void git_config_push_parameter (const char *text);void git_config_push_env (const char *spec);int git_config_from_parameters (config_fn_t fn,void *data); + +/* +* Read config when the Git directory has not yet been set up. In case +* `the_repository` has not yet been set up, try to discover the Git +* directory to read the configuration from. +*/ void read_early_config (config_fn_t cb,void *data); + +/* +* Read config but only enumerate system and global settings. +* Omit any repo-local, worktree-local, or command-line settings. +*/ void read_very_early_config (config_fn_t cb,void *data);/**
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 8/21 config: make dependency on repo in `read_early_config()` explicit
In reply to Patrick SteinhardtThe read_early_config() function can be used to read configuration where a repository has not yet been set up. As such, it is optional whether or not the_repository has already been initialized. If it was initialized we use its commondir and gitdir. If not, the function will try to detect the Git directories by itself and, if found, also parse their config files.
This means that we implicitly rely on the_repository. Make this dependency explicit by passing a struct repository. This allows us to again drop the USE_THE_REPOSITORY_VARIABLE define in "config.c".
--- alias.c | 6 ++++-- config.c | 10 ++++------ config.h | 2 +- help.c | 2 +- pager.c | 7 +++++-- t/helper/test-config.c | 3 ++- trace2/tr2_cfg.c | 4 +++- 7 files changed, 20 insertions(+), 14 deletions(-)
alias.c +4 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "alias.h" #include "config.h"
@@ -37,7 +39,7 @@ char *alias_lookup(const char *alias) {struct config_alias_data data = { alias,NULL }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data);return data.v; }
@@ -46,7 +48,7 @@ void list_aliases(struct string_list *list) {struct config_alias_data data = {NULL ,NULL , list }; -read_early_config (config_alias_cb, &data); +read_early_config (the_repository, config_alias_cb, &data); }void quote_cmdline (struct strbuf *buf,const char **argv)
config.c +4 -6
@@ -6,8 +6,6 @@* */ -#define USE_THE_REPOSITORY_VARIABLE -#include "git-compat-util.h" #include "abspath.h" #include "advice.h"
@@ -2204,7 +2202,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config (config_fn_t cb,void *data) +void read_early_config (struct repository *repo,config_fn_t cb,void *data) {struct config_options opts = {0 };struct strbuf commondir =STRBUF_INIT ;
@@ -2212,9 +2210,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes =1 ; -if (have_git_dir ()) { - opts.commondir =repo_get_common_dir (the_repository); - opts.git_dir =repo_get_git_dir (the_repository); +if (repo && repo->gitdir) { + opts.commondir =repo_get_common_dir (repo); + opts.git_dir =repo_get_git_dir (repo);/* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there
config.h +1 -1
@@ -198,7 +198,7 @@ int git_config_from_parameters(config_fn_t fn, void *data);* `the_repository` has not yet been set up, try to discover the Git * directory to read the configuration from. */ -void read_early_config (config_fn_t cb,void *data); +void read_early_config (struct repository *repo,config_fn_t cb,void *data);/* * Read config but only enumerate system and global settings.
help.c +1 -1
@@ -618,7 +618,7 @@ const char *help_unknown_cmd(const char *cmd)memset (&other_cmds,0 ,sizeof (other_cmds));memset (&aliases,0 ,sizeof (aliases)); -read_early_config (git_unknown_cmd_config,NULL ); +read_early_config (the_repository, git_unknown_cmd_config,NULL );/* * Disable autocorrection prompt in a non-interactive session
pager.c +5 -2
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "editor.h"
@@ -92,7 +94,8 @@ const char *git_pager(int stdout_is_tty) pager =getenv ("GIT_PAGER" );if (!pager) {if (!pager_program) -read_early_config (core_pager_config,NULL ); +read_early_config (the_repository, + core_pager_config,NULL ); pager = pager_program; }if (!pager)
@@ -298,7 +301,7 @@ int check_pager_config(const char *cmd) data.want =-1 ; data.value =NULL ; -read_early_config (pager_command_config, &data); +read_early_config (the_repository, pager_command_config, &data);if (data.value) pager_program = data.value;
t/helper/test-config.c +2 -1
@@ -96,7 +96,8 @@ int cmd__config(int argc, const char **argv)struct config_set cs;if (argc ==3 && !strcmp (argv[1 ],"read_early_config" )) { -read_early_config (early_config_cb, (void *)argv[2 ]); +read_early_config (the_repository, early_config_cb, + (void *)argv[2 ]);return 0 ; }
trace2/tr2_cfg.c +3 -1
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE +#include "git-compat-util.h" #include "config.h" #include "strbuf.h"
@@ -124,7 +126,7 @@ void tr2_cfg_list_config_fl(const char *file, int line)struct tr2_cfg_data data = { file, line };if (tr2_cfg_load_patterns () >0 ) -read_early_config (tr2_cfg_cb, &data); +read_early_config (the_repository, tr2_cfg_cb, &data); }void tr2_list_env_vars_fl (const char *file,int line)
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty
PATCH v3 9/21 environment: move object database functions into object layer
In reply to Patrick SteinhardtThe odb_mkstemp() and odb_pack_keep() functions are quite clearly tied to the object store, but regardless of that they are located in "environment.c". Move them over, which also helps to get rid of dependencies on the_repository in the environment subsystem.
--- bundle-uri.c | 2 +- environment.c | 34 ---------------------------------- environment.h | 15 --------------- object-file.c | 33 +++++++++++++++++++++++++++++++++ object-store-ll.h | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 50 deletions(-)
bundle-uri.c +1 -1
@@ -4,7 +4,6 @@#include "bundle-uri.h" #include "bundle.h" #include "copy.h" -#include "environment.h" #include "gettext.h" #include "refs.h" #include "run-command.h"
@@ -13,6 +12,7 @@#include "config.h" #include "fetch-pack.h" #include "remote.h" +#include "object-store-ll.h" static struct { enum bundle_list_heuristic heuristic;
environment.c +0 -34
@@ -23,7 +23,6 @@#include "commit.h" #include "strvec.h" #include "object-file.h" -#include "object-store-ll.h" #include "path.h" #include "replace-object.h" #include "tmp-objdir.h"
@@ -268,39 +267,6 @@ void set_git_work_tree(const char *new_work_tree)repo_set_worktree (the_repository, new_work_tree); } -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) -{ -int fd; -/* -* we let the umask do its job, don't try to be more -* restrictive except to remove write permission. -*/ -int mode =0444 ; -git_path_buf (temp_filename,"objects/%s" , pattern); - fd =git_mkstemp_mode (temp_filename->buf, mode); -if (0 <= fd) -return fd; - -/* slow path */ -/* some mkstemp implementations erase temp_filename on failure */ -git_path_buf (temp_filename,"objects/%s" , pattern); -safe_create_leading_directories (temp_filename->buf); -return xmkstemp_mode (temp_filename->buf, mode); -} - -int odb_pack_keep (const char *name) -{ -int fd; - - fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -if (0 <= fd) -return fd; - -/* slow path */ -safe_create_leading_directories_const (name); -return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); -} -static void set_git_dir_1 (const char *path) {xsetenv (GIT_DIR_ENVIRONMENT , path,1 );
environment.h +0 -15
@@ -200,21 +200,6 @@ extern int grafts_keep_true_parents;extern int repository_format_precious_objects; -/* -* Create a temporary file rooted in the object database directory, or -* die on failure. The filename is taken from "pattern", which should have the -* usual "XXXXXX" trailer, and the resulting filename is written into the -* "template" buffer. Returns the open descriptor. -*/ -int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); - -/* -* Create a pack .keep file named "name" (which should generally be the output -* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on -* error. -*/ -int odb_pack_keep (const char *name); -const char *get_log_output_encoding (void );const char *get_commit_output_encoding (void );
object-file.c +33 -0
@@ -419,6 +419,39 @@ enum scld_error safe_create_leading_directories_const(const char *path)return result; } +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern) +{ +int fd; +/* +* we let the umask do its job, don't try to be more +* restrictive except to remove write permission. +*/ +int mode =0444 ; +git_path_buf (temp_filename,"objects/%s" , pattern); + fd =git_mkstemp_mode (temp_filename->buf, mode); +if (0 <= fd) +return fd; + +/* slow path */ +/* some mkstemp implementations erase temp_filename on failure */ +git_path_buf (temp_filename,"objects/%s" , pattern); +safe_create_leading_directories (temp_filename->buf); +return xmkstemp_mode (temp_filename->buf, mode); +} + +int odb_pack_keep (const char *name) +{ +int fd; + + fd =open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +if (0 <= fd) +return fd; + +/* slow path */ +safe_create_leading_directories_const (name); +return open (name,O_RDWR |O_CREAT |O_EXCL ,0600 ); +} +static void fill_loose_path (struct strbuf *buf,const struct object_id *oid) {int i;
object-store-ll.h +15 -0
@@ -231,6 +231,21 @@ struct raw_object_store {struct raw_object_store *raw_object_store_new (void );void raw_object_store_clear (struct raw_object_store *o); +/* +* Create a temporary file rooted in the object database directory, or +* die on failure. The filename is taken from "pattern", which should have the +* usual "XXXXXX" trailer, and the resulting filename is written into the +* "template" buffer. Returns the open descriptor. +*/ +int odb_mkstemp (struct strbuf *temp_filename,const char *pattern); + +/* +* Create a pack .keep file named "name" (which should generally be the output +* of odb_pack_name). Returns a file descriptor opened for writing, or -1 on +* error. +*/ +int odb_pack_keep (const char *name); +/* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid.
Signature · 1 line
2.46.0.551.gc5ee8f2d1c.dirty