reflog expire: use "switch" over enum values

Change code added in 03cb91b18cc (reflog --expire-unreachable: special case entries in "HEAD" reflog, 2010-04-09) to use a "switch" statement with an exhaustive list of "case" statements instead of doing numeric comparisons against the enum labels. Now we won't assume that "x != UE_ALWAYS" means "(x == UE_HEAD || x || UE_NORMAL)". That assumption is true now, but we'd introduce subtle bugs here if that were to change, now the compiler will notice and error out on such errors. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Dec 22, 2021 at 05:06 UTC 20d6b6868c1446d548094a0a8aa4393a9c58447c
1 file changed +33 -24
builtin/reflog.c
+33 -24
@@ -303,10 +303,15 @@ static int should_expire_reflog_ent(struct object_id *ooid, struct object_id *no
303 return 1;
304
305 if (timestamp < cb->cmd.expire_unreachable) {
306 - if (cb->unreachable_expire_kind == UE_ALWAYS)
307 - return 1;
308 - if (unreachable(cb, old_commit, ooid) || unreachable(cb, new_commit, noid))
306 + switch (cb->unreachable_expire_kind) {
307 + case UE_ALWAYS:
308 return 1;
309 + case UE_NORMAL:
310 + case UE_HEAD:
311 + if (unreachable(cb, old_commit, ooid) || unreachable(cb, new_commit, noid))
312 + return 1;
313 + break;
314 + }
315 }
316
317 if (cb->cmd.recno && --(cb->cmd.recno) == 0)
@@ -348,6 +353,7 @@ static void reflog_expiry_prepare(const char *refname,
353 void *cb_data)
354 {
355 struct expire_reflog_policy_cb *cb = cb_data;
356 + struct commit_list *elem;
357
358 if (!cb->cmd.expire_unreachable || is_head(refname)) {
359 cb->unreachable_expire_kind = UE_HEAD;
@@ -363,34 +369,37 @@ static void reflog_expiry_prepare(const char *refname,
369 if (cb->cmd.expire_unreachable <= cb->cmd.expire_total)
370 cb->unreachable_expire_kind = UE_ALWAYS;
371
366 - if (cb->unreachable_expire_kind != UE_ALWAYS) {
367 - if (cb->unreachable_expire_kind == UE_HEAD) {
368 - struct commit_list *elem;
369 -
370 - for_each_ref(push_tip_to_list, &cb->tips);
371 - for (elem = cb->tips; elem; elem = elem->next)
372 - commit_list_insert(elem->item, &cb->mark_list);
373 - } else {
374 - commit_list_insert(cb->tip_commit, &cb->mark_list);
375 - }
376 - cb->mark_limit = cb->cmd.expire_total;
377 - mark_reachable(cb);
372 + switch (cb->unreachable_expire_kind) {
373 + case UE_ALWAYS:
374 + return;
375 + case UE_HEAD:
376 + for_each_ref(push_tip_to_list, &cb->tips);
377 + for (elem = cb->tips; elem; elem = elem->next)
378 + commit_list_insert(elem->item, &cb->mark_list);
379 + break;
380 + case UE_NORMAL:
381 + commit_list_insert(cb->tip_commit, &cb->mark_list);
382 }
383 + cb->mark_limit = cb->cmd.expire_total;
384 + mark_reachable(cb);
385 }
386
387 static void reflog_expiry_cleanup(void *cb_data)
388 {
389 struct expire_reflog_policy_cb *cb = cb_data;
390 + struct commit_list *elem;
391
385 - if (cb->unreachable_expire_kind != UE_ALWAYS) {
386 - if (cb->unreachable_expire_kind == UE_HEAD) {
387 - struct commit_list *elem;
388 - for (elem = cb->tips; elem; elem = elem->next)
389 - clear_commit_marks(elem->item, REACHABLE);
390 - free_commit_list(cb->tips);
391 - } else {
392 - clear_commit_marks(cb->tip_commit, REACHABLE);
393 - }
392 + switch (cb->unreachable_expire_kind) {
393 + case UE_ALWAYS:
394 + return;
395 + case UE_HEAD:
396 + for (elem = cb->tips; elem; elem = elem->next)
397 + clear_commit_marks(elem->item, REACHABLE);
398 + free_commit_list(cb->tips);
399 + break;
400 + case UE_NORMAL:
401 + clear_commit_marks(cb->tip_commit, REACHABLE);
402 + break;
403 }
404 }
405