From 72470aa38ad786697118157e69174ba7ff85bfa3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 18 Jul 2018 16:44:49 -0400 Subject: [PATCH 1/3] check_replace_refs: fix outdated comment Commit afc711b8e1 (rename read_replace_refs to check_replace_refs, 2014-02-18) added a comment mentioning that check_replace_refs is set in two ways: - from user intent via --no-replace-objects, etc - after seeing there are no replace refs to respect Since c3c36d7de2 (replace-object: check_replace_refs is safe in multi repo environment, 2018-04-11) the second is no longer true. Let's drop that part of the comment. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cache.h b/cache.h index 8b447652a7..7b09b09cb0 100644 --- a/cache.h +++ b/cache.h @@ -804,9 +804,7 @@ void reset_shared_repository(void); * Do replace refs need to be checked this run? This variable is * initialized to true unless --no-replace-object is used or * $GIT_NO_REPLACE_OBJECTS is set, but is set to false by some - * commands that do not want replace references to be active. As an - * optimization it is also set to false if replace references have - * been sought but there were none. + * commands that do not want replace references to be active. */ extern int check_replace_refs; extern char *git_replace_ref_base; From 6ebd1cafe2bb1dee34e106a8da3ee173b36259d3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 18 Jul 2018 16:45:20 -0400 Subject: [PATCH 2/3] check_replace_refs: rename to read_replace_refs This was added as a NEEDSWORK in c3c36d7de2 (replace-object: check_replace_refs is safe in multi repo environment, 2018-04-11), waiting for a calmer period. Since doing so now doesn't conflict with anything in 'pu', it seems as good a time as any. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/fsck.c | 2 +- builtin/index-pack.c | 2 +- builtin/pack-objects.c | 2 +- builtin/prune.c | 2 +- builtin/replace.c | 2 +- builtin/unpack-objects.c | 2 +- builtin/upload-pack.c | 2 +- cache.h | 2 +- environment.c | 4 ++-- git.c | 2 +- log-tree.c | 2 +- replace-object.c | 2 +- replace-object.h | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 3ad4f160f9..0c3cbb86fc 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -689,7 +689,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) fetch_if_missing = 0; errors_found = 0; - check_replace_refs = 0; + read_replace_refs = 0; argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 74fe2973e1..a24faa0e51 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1679,7 +1679,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage(index_pack_usage); - check_replace_refs = 0; + read_replace_refs = 0; fsck_options.walk = mark_link; reset_pack_idx_option(&opts); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index ebc8cefb53..14235b0ac2 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3188,7 +3188,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (DFS_NUM_STATES > (1 << OE_DFS_STATE_BITS)) BUG("too many dfs states, increase OE_DFS_STATE_BITS"); - check_replace_refs = 0; + read_replace_refs = 0; reset_pack_idx_option(&pack_idx_opts); git_config(git_pack_config, NULL); diff --git a/builtin/prune.c b/builtin/prune.c index 70ec35aa05..89f9d8155a 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -118,7 +118,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix) expire = TIME_MAX; save_commit_buffer = 0; - check_replace_refs = 0; + read_replace_refs = 0; ref_paranoia = 1; init_revisions(&revs, prefix); diff --git a/builtin/replace.c b/builtin/replace.c index deabda2101..18609c6a8d 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -544,7 +544,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix) OPT_END() }; - check_replace_refs = 0; + read_replace_refs = 0; git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index cf585fcc5e..665fa899f4 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -513,7 +513,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix) int i; struct object_id oid; - check_replace_refs = 0; + read_replace_refs = 0; git_config(git_default_config, NULL); diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c index decde5a3b1..42dc4da5a1 100644 --- a/builtin/upload-pack.c +++ b/builtin/upload-pack.c @@ -31,7 +31,7 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix) }; packet_trace_identity("upload-pack"); - check_replace_refs = 0; + read_replace_refs = 0; argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0); diff --git a/cache.h b/cache.h index 7b09b09cb0..3880b6a98b 100644 --- a/cache.h +++ b/cache.h @@ -806,7 +806,7 @@ void reset_shared_repository(void); * $GIT_NO_REPLACE_OBJECTS is set, but is set to false by some * commands that do not want replace references to be active. */ -extern int check_replace_refs; +extern int read_replace_refs; extern char *git_replace_ref_base; extern int fsync_object_files; diff --git a/environment.c b/environment.c index 013e845235..3042e5f40f 100644 --- a/environment.c +++ b/environment.c @@ -51,7 +51,7 @@ const char *editor_program; const char *askpass_program; const char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; -int check_replace_refs = 1; /* NEEDSWORK: rename to read_replace_refs */ +int read_replace_refs = 1; char *git_replace_ref_base; enum eol core_eol = EOL_UNSET; int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; @@ -183,7 +183,7 @@ void setup_git_env(const char *git_dir) argv_array_clear(&to_free); if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) - check_replace_refs = 0; + read_replace_refs = 0; replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); free(git_replace_ref_base); git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base diff --git a/git.c b/git.c index 3fded74519..f4e04a82c9 100644 --- a/git.c +++ b/git.c @@ -164,7 +164,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (envchanged) *envchanged = 1; } else if (!strcmp(cmd, "--no-replace-objects")) { - check_replace_refs = 0; + read_replace_refs = 0; setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; diff --git a/log-tree.c b/log-tree.c index 4a3907fea0..ec3a689c6a 100644 --- a/log-tree.c +++ b/log-tree.c @@ -91,7 +91,7 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid, if (starts_with(refname, git_replace_ref_base)) { struct object_id original_oid; - if (!check_replace_refs) + if (!read_replace_refs) return 0; if (get_oid_hex(refname + strlen(git_replace_ref_base), &original_oid)) { diff --git a/replace-object.c b/replace-object.c index 801b5c1678..4162df6324 100644 --- a/replace-object.c +++ b/replace-object.c @@ -51,7 +51,7 @@ static void prepare_replace_object(struct repository *r) * replacement object's name (replaced recursively, if necessary). * The return value is either oid or a pointer to a * permanently-allocated value. This function always respects replace - * references, regardless of the value of check_replace_refs. + * references, regardless of the value of read_replace_refs. */ const struct object_id *do_lookup_replace_object(struct repository *r, const struct object_id *oid) diff --git a/replace-object.h b/replace-object.h index f996de3d62..9345e105dd 100644 --- a/replace-object.h +++ b/replace-object.h @@ -26,7 +26,7 @@ extern const struct object_id *do_lookup_replace_object(struct repository *r, static inline const struct object_id *lookup_replace_object(struct repository *r, const struct object_id *oid) { - if (!check_replace_refs || + if (!read_replace_refs || (r->objects->replace_map && r->objects->replace_map->map.tablesize == 0)) return oid; From da4398d6a03eb2cf857aa63190e9bf60305befd2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 18 Jul 2018 16:45:25 -0400 Subject: [PATCH 3/3] add core.usereplacerefs config option We can already disable replace refs using a command line option or environment variable, but those are awkward to apply universally. Let's add a config option to do the same thing. That raises the question of why one might want to do so universally. The answer is that replace refs violate the immutability of objects. For instance, if you wanted to cache the diff between commit XYZ and its parent, then in theory that never changes; the hash XYZ represents the total state. But replace refs violate that; pushing up a new ref may create a completely new diff. The obvious "if it hurts, don't do it" answer is not to create replace refs if you're doing this kind of caching. But for a site hosting arbitrary repositories, they may want to allow users to share replace refs with each other, but not actually respect them on the site (because the caching is more important than the replace feature). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/config.txt | 5 +++++ config.c | 5 +++++ t/t6050-replace.sh | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index a32172a43c..bcf3d21ecb 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -911,6 +911,11 @@ core.commitGraph:: Enable git commit graph feature. Allows reading from the commit-graph file. +core.useReplaceRefs:: + If set to `false`, behave as if the `--no-replace-objects` + option was given on the command line. See linkgit:git[1] and + linkgit:git-replace[1] for more information. + core.sparseCheckout:: Enable "sparse checkout" feature. See section "Sparse checkout" in linkgit:git-read-tree[1] for more information. diff --git a/config.c b/config.c index 7968ef7566..5c6d8d17dd 100644 --- a/config.c +++ b/config.c @@ -1347,6 +1347,11 @@ static int git_default_core_config(const char *var, const char *value) var, value); } + if (!strcmp(var, "core.usereplacerefs")) { + read_replace_refs = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index aa3e249639..86374a9c52 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -113,6 +113,12 @@ test_expect_success 'test GIT_NO_REPLACE_OBJECTS env variable' ' GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor" ' +test_expect_success 'test core.usereplacerefs config option' ' + test_config core.usereplacerefs false && + git cat-file commit $HASH2 | grep "author A U Thor" && + git show $HASH2 | grep "A U Thor" +' + cat >tag.sig <