Skip to content

Commit 49672f2

Browse files
peffgitster
authored andcommitted
refs: introduce a "ref paranoia" flag
Most operations that iterate over refs are happy to ignore broken cruft. However, some operations should be performed with knowledge of these broken refs, because it is better for the operation to choke on a missing object than it is to silently pretend that the ref did not exist (e.g., if we are computing the set of reachable tips in order to prune objects). These processes could just call for_each_rawref, except that ref iteration is often hidden behind other interfaces. For instance, for a destructive "repack -ad", we would have to inform "pack-objects" that we are destructive, and then it would in turn have to tell the revision code that our "--all" should include broken refs. It's much simpler to just set a global for "dangerous" operations that includes broken refs in all iterations. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8b43fb1 commit 49672f2

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

Documentation/git.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,17 @@ GIT_ICASE_PATHSPECS::
10261026
variable when it is invoked as the top level command by the
10271027
end user, to be recorded in the body of the reflog.
10281028

1029+
`GIT_REF_PARANOIA`::
1030+
If set to `1`, include broken or badly named refs when iterating
1031+
over lists of refs. In a normal, non-corrupted repository, this
1032+
does nothing. However, enabling it may help git to detect and
1033+
abort some operations in the presence of broken refs. Git sets
1034+
this variable automatically when performing destructive
1035+
operations like linkgit:git-prune[1]. You should not need to set
1036+
it yourself unless you want to be paranoid about making sure
1037+
an operation has touched every ref (e.g., because you are
1038+
cloning a repository to make a backup).
1039+
10291040

10301041
Discussion[[Discussion]]
10311042
------------------------

cache.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,14 @@ extern int precomposed_unicode;
613613
extern int protect_hfs;
614614
extern int protect_ntfs;
615615

616+
/*
617+
* Include broken refs in all ref iterations, which will
618+
* generally choke dangerous operations rather than letting
619+
* them silently proceed without taking the broken ref into
620+
* account.
621+
*/
622+
extern int ref_paranoia;
623+
616624
/*
617625
* The character that begins a commented line in user-editable file
618626
* that is subject to stripspace.

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ int is_bare_repository_cfg = -1; /* unspecified */
2424
int log_all_ref_updates = -1; /* unspecified */
2525
int warn_ambiguous_refs = 1;
2626
int warn_on_object_refname_ambiguity = 1;
27+
int ref_paranoia = -1;
2728
int repository_format_version;
2829
const char *git_commit_encoding;
2930
const char *git_log_output_encoding;

refs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,11 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base,
19071907
data.fn = fn;
19081908
data.cb_data = cb_data;
19091909

1910+
if (ref_paranoia < 0)
1911+
ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1912+
if (ref_paranoia)
1913+
data.flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1914+
19101915
return do_for_each_entry(refs, base, do_one_ref, &data);
19111916
}
19121917

0 commit comments

Comments
 (0)