Skip to content

Commit 341fb28

Browse files
Cornelius Weiggitster
authored andcommitted
refs: add option core.logAllRefUpdates = always
When core.logallrefupdates is true, we only create a new reflog for refs that are under certain well-known hierarchies. The reason is that we know that some hierarchies (like refs/tags) are not meant to change, and that unknown hierarchies might not want reflogs at all (e.g., a hypothetical refs/foo might be meant to change often and drop old history immediately). However, sometimes it is useful to override this decision and simply log for all refs, because the safety and audit trail is more important than the performance implications of keeping the log around. This patch introduces a new "always" mode for the core.logallrefupdates option which will log updates to everything under refs/, regardless where in the hierarchy it is (we still will not log things like ORIG_HEAD and FETCH_HEAD, which are known to be transient). Based-on-patch-by: Jeff King <[email protected]> Signed-off-by: Cornelius Weig <[email protected]> Reviewed-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d0c9319 commit 341fb28

File tree

14 files changed

+88
-20
lines changed

14 files changed

+88
-20
lines changed

Documentation/config.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,8 @@ core.logAllRefUpdates::
521521
file is automatically created for branch heads (i.e. under
522522
`refs/heads/`), remote refs (i.e. under `refs/remotes/`),
523523
note refs (i.e. under `refs/notes/`), and the symbolic ref `HEAD`.
524+
If it is set to `always`, then a missing reflog is automatically
525+
created for any ref under `refs/`.
524526
+
525527
This information can be used to determine what commit
526528
was the tip of a branch "2 days ago".

Documentation/git-tag.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ This option is only applicable when listing tags without annotation lines.
150150
'strip' removes both whitespace and commentary.
151151

152152
--create-reflog::
153-
Create a reflog for the tag.
153+
Create a reflog for the tag. To globally enable reflogs for tags, see
154+
`core.logAllRefUpdates` in linkgit:git-config[1].
154155

155156
<tagname>::
156157
The name of the tag to create, delete, or describe.

branch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ void create_branch(const char *name, const char *start_name,
298298
start_name);
299299

300300
if (reflog)
301-
log_all_ref_updates = 1;
301+
log_all_ref_updates = LOG_REFS_NORMAL;
302302

303303
if (!dont_change_ref) {
304304
struct ref_transaction *transaction;

builtin/checkout.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -612,22 +612,25 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
612612
const char *old_desc, *reflog_msg;
613613
if (opts->new_branch) {
614614
if (opts->new_orphan_branch) {
615-
if (opts->new_branch_log && !log_all_ref_updates) {
615+
char *refname;
616+
617+
refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
618+
if (opts->new_branch_log &&
619+
!should_autocreate_reflog(refname)) {
616620
int ret;
617-
char *refname;
618621
struct strbuf err = STRBUF_INIT;
619622

620-
refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
621623
ret = safe_create_reflog(refname, 1, &err);
622-
free(refname);
623624
if (ret) {
624625
fprintf(stderr, _("Can not do reflog for '%s': %s\n"),
625626
opts->new_orphan_branch, err.buf);
626627
strbuf_release(&err);
628+
free(refname);
627629
return;
628630
}
629631
strbuf_release(&err);
630632
}
633+
free(refname);
631634
}
632635
else
633636
create_branch(opts->new_branch, new->name,

builtin/init-db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ static int create_default_files(const char *template_path,
262262
const char *work_tree = get_git_work_tree();
263263
git_config_set("core.bare", "false");
264264
/* allow template config file to override the default */
265-
if (log_all_ref_updates == -1)
265+
if (log_all_ref_updates == LOG_REFS_UNSET)
266266
git_config_set("core.logallrefupdates", "true");
267267
if (needs_work_tree_config(original_git_dir, work_tree))
268268
git_config_set("core.worktree", work_tree);

cache.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,6 @@ extern int minimum_abbrev, default_abbrev;
660660
extern int ignore_case;
661661
extern int assume_unchanged;
662662
extern int prefer_symlink_refs;
663-
extern int log_all_ref_updates;
664663
extern int warn_ambiguous_refs;
665664
extern int warn_on_object_refname_ambiguity;
666665
extern const char *apply_default_whitespace;
@@ -728,6 +727,14 @@ enum hide_dotfiles_type {
728727
};
729728
extern enum hide_dotfiles_type hide_dotfiles;
730729

730+
enum log_refs_config {
731+
LOG_REFS_UNSET = -1,
732+
LOG_REFS_NONE = 0,
733+
LOG_REFS_NORMAL,
734+
LOG_REFS_ALWAYS
735+
};
736+
extern enum log_refs_config log_all_ref_updates;
737+
731738
enum branch_track {
732739
BRANCH_TRACK_UNSPECIFIED = -1,
733740
BRANCH_TRACK_NEVER = 0,

config.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,12 @@ static int git_default_core_config(const char *var, const char *value)
826826
}
827827

828828
if (!strcmp(var, "core.logallrefupdates")) {
829-
log_all_ref_updates = git_config_bool(var, value);
829+
if (value && !strcasecmp(value, "always"))
830+
log_all_ref_updates = LOG_REFS_ALWAYS;
831+
else if (git_config_bool(var, value))
832+
log_all_ref_updates = LOG_REFS_NORMAL;
833+
else
834+
log_all_ref_updates = LOG_REFS_NONE;
830835
return 0;
831836
}
832837

environment.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ int ignore_case;
2121
int assume_unchanged;
2222
int prefer_symlink_refs;
2323
int is_bare_repository_cfg = -1; /* unspecified */
24-
int log_all_ref_updates = -1; /* unspecified */
2524
int warn_ambiguous_refs = 1;
2625
int warn_on_object_refname_ambiguity = 1;
2726
int ref_paranoia = -1;
@@ -64,6 +63,7 @@ int merge_log_config = -1;
6463
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
6564
unsigned long pack_size_limit_cfg;
6665
enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
66+
enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET;
6767

6868
#ifndef PROTECT_HFS_DEFAULT
6969
#define PROTECT_HFS_DEFAULT 0

refs.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -638,12 +638,17 @@ int copy_reflog_msg(char *buf, const char *msg)
638638

639639
int should_autocreate_reflog(const char *refname)
640640
{
641-
if (!log_all_ref_updates)
641+
switch (log_all_ref_updates) {
642+
case LOG_REFS_ALWAYS:
643+
return 1;
644+
case LOG_REFS_NORMAL:
645+
return starts_with(refname, "refs/heads/") ||
646+
starts_with(refname, "refs/remotes/") ||
647+
starts_with(refname, "refs/notes/") ||
648+
!strcmp(refname, "HEAD");
649+
default:
642650
return 0;
643-
return starts_with(refname, "refs/heads/") ||
644-
starts_with(refname, "refs/remotes/") ||
645-
starts_with(refname, "refs/notes/") ||
646-
!strcmp(refname, "HEAD");
651+
}
647652
}
648653

649654
int is_branch(const char *refname)

refs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ int read_ref(const char *refname, unsigned char *sha1);
6464

6565
int ref_exists(const char *refname);
6666

67+
int should_autocreate_reflog(const char *refname);
68+
6769
int is_branch(const char *refname);
6870

6971
extern int refs_init_db(struct strbuf *err);

0 commit comments

Comments
 (0)