Skip to content

Commit e226ad8

Browse files
tiennouethomson
authored andcommitted
refs: add support for core.logAllRefUpdates=always
Since we were not expecting this config entry to contain a string, we would fail as soon as its (cached) value would be accessed. Hence, provide some constants for the 4 states we use, and account for "always" when we decide to reflog changes.
1 parent 7321cff commit e226ad8

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

src/config_cache.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ static git_cvar_map _cvar_map_safecrlf[] = {
5858
{GIT_CVAR_STRING, "warn", GIT_SAFE_CRLF_WARN}
5959
};
6060

61+
static git_cvar_map _cvar_map_logallrefupdates[] = {
62+
{GIT_CVAR_FALSE, NULL, GIT_LOGALLREFUPDATES_FALSE},
63+
{GIT_CVAR_TRUE, NULL, GIT_LOGALLREFUPDATES_TRUE},
64+
{GIT_CVAR_STRING, "always", GIT_LOGALLREFUPDATES_ALWAYS},
65+
};
66+
6167
/*
6268
* Generic map for integer values
6369
*/
@@ -76,7 +82,7 @@ static struct map_data _cvar_maps[] = {
7682
{"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT },
7783
{"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
7884
{"core.safecrlf", _cvar_map_safecrlf, ARRAY_SIZE(_cvar_map_safecrlf), GIT_SAFE_CRLF_DEFAULT},
79-
{"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
85+
{"core.logallrefupdates", _cvar_map_logallrefupdates, ARRAY_SIZE(_cvar_map_logallrefupdates), GIT_LOGALLREFUPDATES_DEFAULT},
8086
{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
8187
{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
8288
{"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },

src/refdb_fs.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,6 @@ static int packed_write(refdb_fs_backend *backend)
10901090
static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_oid *old, const git_oid *new, const git_signature *author, const char *message);
10911091
static int has_reflog(git_repository *repo, const char *name);
10921092

1093-
/* We only write if it's under heads/, remotes/ or notes/ or if it already has a log */
10941093
static int should_write_reflog(int *write, git_repository *repo, const char *name)
10951094
{
10961095
int error, logall;
@@ -1103,17 +1102,26 @@ static int should_write_reflog(int *write, git_repository *repo, const char *nam
11031102
if (logall == GIT_LOGALLREFUPDATES_UNSET)
11041103
logall = !git_repository_is_bare(repo);
11051104

1106-
if (!logall) {
1105+
*write = 0;
1106+
switch (logall) {
1107+
case GIT_LOGALLREFUPDATES_FALSE:
11071108
*write = 0;
1108-
} else if (has_reflog(repo, name)) {
1109-
*write = 1;
1110-
} else if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR) ||
1111-
!git__strcmp(name, GIT_HEAD_FILE) ||
1112-
!git__prefixcmp(name, GIT_REFS_REMOTES_DIR) ||
1113-
!git__prefixcmp(name, GIT_REFS_NOTES_DIR)) {
1109+
break;
1110+
1111+
case GIT_LOGALLREFUPDATES_TRUE:
1112+
/* Only write if it already has a log,
1113+
* or if it's under heads/, remotes/ or notes/
1114+
*/
1115+
*write = has_reflog(repo, name) ||
1116+
!git__prefixcmp(name, GIT_REFS_HEADS_DIR) ||
1117+
!git__strcmp(name, GIT_HEAD_FILE) ||
1118+
!git__prefixcmp(name, GIT_REFS_REMOTES_DIR) ||
1119+
!git__prefixcmp(name, GIT_REFS_NOTES_DIR);
1120+
break;
1121+
1122+
case GIT_LOGALLREFUPDATES_ALWAYS:
11141123
*write = 1;
1115-
} else {
1116-
*write = 0;
1124+
break;
11171125
}
11181126

11191127
return 0;
@@ -1713,7 +1721,7 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend,
17131721
if ((error == GIT_ENOTFOUND) &&
17141722
((error = create_new_reflog_file(git_buf_cstr(&log_path))) < 0))
17151723
goto cleanup;
1716-
1724+
17171725
if ((error = reflog_parse(log,
17181726
git_buf_cstr(&log_file), git_buf_len(&log_file))) < 0)
17191727
goto cleanup;
@@ -1973,7 +1981,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_
19731981
goto cleanup;
19741982
}
19751983

1976-
if (git_path_isdir(git_buf_cstr(&new_path)) &&
1984+
if (git_path_isdir(git_buf_cstr(&new_path)) &&
19771985
(git_futils_rmdir_r(git_buf_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) {
19781986
error = -1;
19791987
goto cleanup;

src/repository.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ typedef enum {
105105
/* core.safecrlf */
106106
GIT_SAFE_CRLF_DEFAULT = GIT_CVAR_FALSE,
107107
/* core.logallrefupdates */
108+
GIT_LOGALLREFUPDATES_FALSE = GIT_CVAR_FALSE,
109+
GIT_LOGALLREFUPDATES_TRUE = GIT_CVAR_TRUE,
108110
GIT_LOGALLREFUPDATES_UNSET = 2,
111+
GIT_LOGALLREFUPDATES_ALWAYS = 3,
109112
GIT_LOGALLREFUPDATES_DEFAULT = GIT_LOGALLREFUPDATES_UNSET,
110113
/* core.protectHFS */
111114
GIT_PROTECTHFS_DEFAULT = GIT_CVAR_FALSE,

tests/refs/reflog/reflog.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,28 @@ void test_refs_reflog_reflog__logallrefupdates_bare_set_false(void)
422422
assert_no_reflog_update();
423423
}
424424

425+
void test_refs_reflog_reflog__logallrefupdates_bare_set_always(void)
426+
{
427+
git_config *config;
428+
git_reference *ref;
429+
git_reflog *log;
430+
git_oid id;
431+
432+
cl_git_pass(git_repository_config(&config, g_repo));
433+
cl_git_pass(git_config_set_string(config, "core.logallrefupdates", "always"));
434+
git_config_free(config);
435+
436+
git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
437+
cl_git_pass(git_reference_create(&ref, g_repo, "refs/bork", &id, 1, "message"));
438+
439+
cl_git_pass(git_reflog_read(&log, g_repo, "refs/bork"));
440+
cl_assert_equal_i(1, git_reflog_entrycount(log));
441+
cl_assert_equal_s("message", git_reflog_entry_byindex(log, 0)->msg);
442+
443+
git_reflog_free(log);
444+
git_reference_free(ref);
445+
}
446+
425447
void test_refs_reflog_reflog__logallrefupdates_bare_unset(void)
426448
{
427449
git_config *config;

0 commit comments

Comments
 (0)