Skip to content

Commit

Permalink
refs: introduce a "ref paranoia" flag
Browse files Browse the repository at this point in the history
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Mar 20, 2015
1 parent 8b43fb1 commit 49672f2
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,17 @@ GIT_ICASE_PATHSPECS::
variable when it is invoked as the top level command by the
end user, to be recorded in the body of the reflog.

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


Discussion[[Discussion]]
------------------------
Expand Down
8 changes: 8 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,14 @@ extern int precomposed_unicode;
extern int protect_hfs;
extern int protect_ntfs;

/*
* Include broken refs in all ref iterations, which will
* generally choke dangerous operations rather than letting
* them silently proceed without taking the broken ref into
* account.
*/
extern int ref_paranoia;

/*
* The character that begins a commented line in user-editable file
* that is subject to stripspace.
Expand Down
1 change: 1 addition & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int is_bare_repository_cfg = -1; /* unspecified */
int log_all_ref_updates = -1; /* unspecified */
int warn_ambiguous_refs = 1;
int warn_on_object_refname_ambiguity = 1;
int ref_paranoia = -1;
int repository_format_version;
const char *git_commit_encoding;
const char *git_log_output_encoding;
Expand Down
5 changes: 5 additions & 0 deletions refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,11 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base,
data.fn = fn;
data.cb_data = cb_data;

if (ref_paranoia < 0)
ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
if (ref_paranoia)
data.flags |= DO_FOR_EACH_INCLUDE_BROKEN;

return do_for_each_entry(refs, base, do_one_ref, &data);
}

Expand Down

0 comments on commit 49672f2

Please sign in to comment.