git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG()
@ 2018-04-29 22:17 Johannes Schindelin
  2018-04-29 22:17 ` [PATCH 1/6] test_must_fail: support ok=sigabrt Johannes Schindelin
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:17 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

The BUG() macro was introduced in this patch series:
https://public-inbox.org/git/20170513032414.mfrwabt4hovujde2@sigill.intra.peff.net

The second patch in that series converted one caller from die("BUG: ")
to use the BUG() macro.

It seems that there was no concrete plan to address the same issue in
the rest of the code base.

This patch series tries to do that.

Note: I separated out 4/6 ("refs/*: report bugs using the BUG() macro")
from 5/6 ("Replace all die("BUG: ...") to keep it cuddled with the patch
2/6 that prepares t1406 for this change of refs/' behavior.

Note also: I would be very surprised if the monster commit 5/6 ("Replace
all die("BUG: ...") calls by BUG() ones") would apply cleanly on `pu` (I
develop this on top of `master`).

For that reason, the commit message contains the precise Unix shell
invocation (GNU sed semantics, not BSD sed ones, because I know that the
Git maintainer as well as the author of the patch introducing BUG() both
use Linux and not macOS or any other platform that would offer a BSD
sed). It should be straight-forward to handle merge
conflicts/non-applying patches by simply re-running that command.


Johannes Schindelin (6):
  test_must_fail: support ok=sigabrt
  t1406: prepare for the refs code to fail with BUG()
  refs/*: report bugs using the BUG() macro
  run-command: use BUG() to report bugs, not die()
  Replace all die("BUG: ...") calls by BUG() ones
  Convert remaining die*(BUG) messages

 apply.c                          |  4 ++--
 archive-tar.c                    |  2 +-
 attr.c                           | 10 +++++-----
 blame.c                          |  2 +-
 builtin/am.c                     | 20 +++++++++----------
 builtin/branch.c                 |  2 +-
 builtin/cat-file.c               |  4 ++--
 builtin/clone.c                  |  2 +-
 builtin/commit.c                 |  2 +-
 builtin/config.c                 |  2 +-
 builtin/fast-export.c            |  2 +-
 builtin/fsck.c                   |  2 +-
 builtin/index-pack.c             |  4 ++--
 builtin/init-db.c                |  2 +-
 builtin/ls-files.c               |  2 +-
 builtin/notes.c                  |  8 ++++----
 builtin/pack-objects.c           |  4 ++--
 builtin/pull.c                   |  2 +-
 builtin/receive-pack.c           |  2 +-
 builtin/replace.c                |  2 +-
 builtin/update-index.c           |  2 +-
 bulk-checkin.c                   |  2 +-
 color.c                          |  4 ++--
 column.c                         |  2 +-
 config.c                         | 12 +++++------
 date.c                           |  2 +-
 diff.c                           | 12 +++++------
 dir-iterator.c                   |  2 +-
 git-compat-util.h                |  2 +-
 grep.c                           | 16 +++++++--------
 http.c                           |  8 ++++----
 imap-send.c                      |  2 +-
 lockfile.c                       |  2 +-
 mailinfo.c                       |  2 +-
 merge-recursive.c                | 12 +++++------
 notes-merge.c                    |  4 ++--
 pack-bitmap-write.c              |  2 +-
 pack-bitmap.c                    |  6 +++---
 pack-objects.c                   |  2 +-
 packfile.c                       |  6 +++---
 pathspec.c                       | 12 +++++------
 pkt-line.c                       |  2 +-
 prio-queue.c                     |  2 +-
 ref-filter.c                     |  4 ++--
 refs.c                           | 34 ++++++++++++++++----------------
 refs/files-backend.c             | 20 +++++++++----------
 refs/iterator.c                  |  6 +++---
 refs/packed-backend.c            | 16 +++++++--------
 refs/ref-cache.c                 |  2 +-
 remote.c                         |  2 +-
 revision.c                       |  4 ++--
 run-command.c                    | 33 ++++++++++++++-----------------
 setup.c                          |  4 ++--
 sha1-lookup.c                    |  2 +-
 sha1-name.c                      |  4 ++--
 shallow.c                        |  6 +++---
 sigchain.c                       |  2 +-
 strbuf.c                         |  4 ++--
 submodule.c                      |  8 ++++----
 t/helper/test-example-decorate.c | 16 +++++++--------
 t/t1406-submodule-ref-store.sh   | 15 ++++++++------
 t/test-lib-functions.sh          |  5 ++++-
 tmp-objdir.c                     |  2 +-
 trailer.c                        |  6 +++---
 transport.c                      |  4 ++--
 unpack-trees.c                   |  2 +-
 vcs-svn/fast_export.c            |  6 ++++--
 worktree.c                       |  2 +-
 wrapper.c                        |  4 ++--
 wt-status.c                      | 20 +++++++++----------
 zlib.c                           |  4 ++--
 71 files changed, 220 insertions(+), 215 deletions(-)


base-commit: 1f1cddd558b54bb0ce19c8ace353fd07b758510d
Published-As: https://github.com/dscho/git/releases/tag/use-bug-macro-v1
Fetch-It-Via: git fetch https://github.com/dscho/git use-bug-macro-v1
-- 
2.17.0.windows.1.36.gdf4ca5fb72a


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/6] test_must_fail: support ok=sigabrt
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
@ 2018-04-29 22:17 ` Johannes Schindelin
  2018-04-29 22:17 ` [PATCH 2/6] t1406: prepare for the refs code to fail with BUG() Johannes Schindelin
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:17 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

In the upcoming patch, we will prepare t1406 to handle the conversion of
refs/files-backend.c to call BUG() instead of die("BUG: ..."). This will
require handling SIGABRT as valid failure case.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 t/test-lib-functions.sh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 7d620bf2a9a..926aefd1551 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -616,7 +616,7 @@ list_contains () {
 #   ok=<signal-name>[,<...>]:
 #     Don't treat an exit caused by the given signal as error.
 #     Multiple signals can be specified as a comma separated list.
-#     Currently recognized signal names are: sigpipe, success.
+#     Currently recognized signal names are: sigabrt, sigpipe, success.
 #     (Don't use 'success', use 'test_might_fail' instead.)
 
 test_must_fail () {
@@ -636,6 +636,9 @@ test_must_fail () {
 		echo >&4 "test_must_fail: command succeeded: $*"
 		return 1
 	elif test_match_signal 13 $exit_code && list_contains "$_test_ok" sigpipe
+	then
+		return 0
+	elif test_match_signal 6 $exit_code && list_contains "$_test_ok" sigabrt
 	then
 		return 0
 	elif test $exit_code -gt 129 && test $exit_code -le 192
-- 
2.17.0.windows.1.36.gdf4ca5fb72a



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
  2018-04-29 22:17 ` [PATCH 1/6] test_must_fail: support ok=sigabrt Johannes Schindelin
@ 2018-04-29 22:17 ` Johannes Schindelin
  2018-04-30 19:32   ` Johannes Sixt
  2018-05-01 11:26   ` Duy Nguyen
  2018-04-29 22:18 ` [PATCH 3/6] refs/*: report bugs using the BUG() macro Johannes Schindelin
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:17 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

t1406 specifically verifies that certain code paths fail with a BUG: ...
message.

In the upcoming commit, we will convert that message to be generated via
BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
regular exit code.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 t/t1406-submodule-ref-store.sh | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh
index e093782cc37..0ea3457cae3 100755
--- a/t/t1406-submodule-ref-store.sh
+++ b/t/t1406-submodule-ref-store.sh
@@ -16,7 +16,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'pack_refs() not allowed' '
-	test_must_fail $RUN pack-refs 3
+	test_must_fail ok=sigabrt $RUN pack-refs 3
 '
 
 test_expect_success 'peel_ref(new-tag)' '
@@ -27,15 +27,18 @@ test_expect_success 'peel_ref(new-tag)' '
 '
 
 test_expect_success 'create_symref() not allowed' '
-	test_must_fail $RUN create-symref FOO refs/heads/master nothing
+	test_must_fail ok=sigabrt \
+		$RUN create-symref FOO refs/heads/master nothing
 '
 
 test_expect_success 'delete_refs() not allowed' '
-	test_must_fail $RUN delete-refs 0 nothing FOO refs/tags/new-tag
+	test_must_fail ok=sigabrt \
+		$RUN delete-refs 0 nothing FOO refs/tags/new-tag
 '
 
 test_expect_success 'rename_refs() not allowed' '
-	test_must_fail $RUN rename-ref refs/heads/master refs/heads/new-master
+	test_must_fail ok=sigabrt \
+		$RUN rename-ref refs/heads/master refs/heads/new-master
 '
 
 test_expect_success 'for_each_ref(refs/heads/)' '
@@ -91,11 +94,11 @@ test_expect_success 'reflog_exists(HEAD)' '
 '
 
 test_expect_success 'delete_reflog() not allowed' '
-	test_must_fail $RUN delete-reflog HEAD
+	test_must_fail ok=sigabrt $RUN delete-reflog HEAD
 '
 
 test_expect_success 'create-reflog() not allowed' '
-	test_must_fail $RUN create-reflog HEAD 1
+	test_must_fail ok=sigabrt $RUN create-reflog HEAD 1
 '
 
 test_done
-- 
2.17.0.windows.1.36.gdf4ca5fb72a



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/6] refs/*: report bugs using the BUG() macro
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
  2018-04-29 22:17 ` [PATCH 1/6] test_must_fail: support ok=sigabrt Johannes Schindelin
  2018-04-29 22:17 ` [PATCH 2/6] t1406: prepare for the refs code to fail with BUG() Johannes Schindelin
@ 2018-04-29 22:18 ` Johannes Schindelin
  2018-04-29 22:18 ` [PATCH 4/6] run-command: use BUG() to report bugs, not die() Johannes Schindelin
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:18 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

We just prepared t1406 to be okay with BUG reports resulting in SIGABRT
instead of a regular exit code indicating failure. This commit now makes
it so: by calling BUG() (which eventually calls `abort()`), we no longer
exit with code 128 but instead throw that signal.

This trick was performed by this invocation:

	sed -i 's/die("BUG: /BUG("/' $(git grep -l 'die("BUG' refs/\*.c)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 refs/files-backend.c  | 20 ++++++++++----------
 refs/iterator.c       |  6 +++---
 refs/packed-backend.c | 16 ++++++++--------
 refs/ref-cache.c      |  2 +-
 4 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index a92a2aa8213..332da47edd9 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -125,7 +125,7 @@ static void files_assert_main_repository(struct files_ref_store *refs,
 	if (refs->store_flags & REF_STORE_MAIN)
 		return;
 
-	die("BUG: operation %s only allowed for main ref store", caller);
+	BUG("operation %s only allowed for main ref store", caller);
 }
 
 /*
@@ -141,13 +141,13 @@ static struct files_ref_store *files_downcast(struct ref_store *ref_store,
 	struct files_ref_store *refs;
 
 	if (ref_store->be != &refs_be_files)
-		die("BUG: ref_store is type \"%s\" not \"files\" in %s",
+		BUG("ref_store is type \"%s\" not \"files\" in %s",
 		    ref_store->be->name, caller);
 
 	refs = (struct files_ref_store *)ref_store;
 
 	if ((refs->store_flags & required_flags) != required_flags)
-		die("BUG: operation %s requires abilities 0x%x, but only have 0x%x",
+		BUG("operation %s requires abilities 0x%x, but only have 0x%x",
 		    caller, required_flags, refs->store_flags);
 
 	return refs;
@@ -166,7 +166,7 @@ static void files_reflog_path(struct files_ref_store *refs,
 		strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
 		break;
 	default:
-		die("BUG: unknown ref type %d of ref %s",
+		BUG("unknown ref type %d of ref %s",
 		    ref_type(refname), refname);
 	}
 }
@@ -184,7 +184,7 @@ static void files_ref_path(struct files_ref_store *refs,
 		strbuf_addf(sb, "%s/%s", refs->gitcommondir, refname);
 		break;
 	default:
-		die("BUG: unknown ref type %d of ref %s",
+		BUG("unknown ref type %d of ref %s",
 		    ref_type(refname), refname);
 	}
 }
@@ -2010,7 +2010,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
 
 	}
 	if (!ret && sb.len)
-		die("BUG: reverse reflog parser had leftover data");
+		BUG("reverse reflog parser had leftover data");
 
 	fclose(logfp);
 	strbuf_release(&sb);
@@ -2088,7 +2088,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
 static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator,
 				   struct object_id *peeled)
 {
-	die("BUG: ref_iterator_peel() called for reflog_iterator");
+	BUG("ref_iterator_peel() called for reflog_iterator");
 }
 
 static int files_reflog_iterator_abort(struct ref_iterator *ref_iterator)
@@ -2873,7 +2873,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
 	assert(err);
 
 	if (transaction->state != REF_TRANSACTION_OPEN)
-		die("BUG: commit called for transaction that is not open");
+		BUG("commit called for transaction that is not open");
 
 	/* Fail if a refname appears more than once in the transaction: */
 	for (i = 0; i < transaction->nr; i++)
@@ -2899,7 +2899,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
 	 */
 	if (refs_for_each_rawref(&refs->base, ref_present,
 				 &affected_refnames))
-		die("BUG: initial ref transaction called with existing refs");
+		BUG("initial ref transaction called with existing refs");
 
 	packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, err);
 	if (!packed_transaction) {
@@ -2912,7 +2912,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
 
 		if ((update->flags & REF_HAVE_OLD) &&
 		    !is_null_oid(&update->old_oid))
-			die("BUG: initial ref transaction with old_sha1 set");
+			BUG("initial ref transaction with old_sha1 set");
 		if (refs_verify_refname_available(&refs->base, update->refname,
 						  &affected_refnames, NULL,
 						  err)) {
diff --git a/refs/iterator.c b/refs/iterator.c
index bd35da4e622..2ac91ac3401 100644
--- a/refs/iterator.c
+++ b/refs/iterator.c
@@ -54,7 +54,7 @@ static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
 static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
 				   struct object_id *peeled)
 {
-	die("BUG: peel called for empty iterator");
+	BUG("peel called for empty iterator");
 }
 
 static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -177,7 +177,7 @@ static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
 		(struct merge_ref_iterator *)ref_iterator;
 
 	if (!iter->current) {
-		die("BUG: peel called before advance for merge iterator");
+		BUG("peel called before advance for merge iterator");
 	}
 	return ref_iterator_peel(*iter->current, peeled);
 }
@@ -338,7 +338,7 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
 			 * trimming, report it as a bug:
 			 */
 			if (strlen(iter->iter0->refname) <= iter->trim)
-				die("BUG: attempt to trim too many characters");
+				BUG("attempt to trim too many characters");
 			iter->base.refname = iter->iter0->refname + iter->trim;
 		} else {
 			iter->base.refname = iter->iter0->refname;
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 369c34f886f..cec3fb9e00f 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -221,13 +221,13 @@ static struct packed_ref_store *packed_downcast(struct ref_store *ref_store,
 	struct packed_ref_store *refs;
 
 	if (ref_store->be != &refs_be_packed)
-		die("BUG: ref_store is type \"%s\" not \"packed\" in %s",
+		BUG("ref_store is type \"%s\" not \"packed\" in %s",
 		    ref_store->be->name, caller);
 
 	refs = (struct packed_ref_store *)ref_store;
 
 	if ((refs->store_flags & required_flags) != required_flags)
-		die("BUG: unallowed operation (%s), requires %x, has %x\n",
+		BUG("unallowed operation (%s), requires %x, has %x\n",
 		    caller, required_flags, refs->store_flags);
 
 	return refs;
@@ -1036,7 +1036,7 @@ void packed_refs_unlock(struct ref_store *ref_store)
 			"packed_refs_unlock");
 
 	if (!is_lock_file_locked(&refs->lock))
-		die("BUG: packed_refs_unlock() called when not locked");
+		BUG("packed_refs_unlock() called when not locked");
 	rollback_lock_file(&refs->lock);
 }
 
@@ -1089,7 +1089,7 @@ static int write_with_updates(struct packed_ref_store *refs,
 	char *packed_refs_path;
 
 	if (!is_lock_file_locked(&refs->lock))
-		die("BUG: write_with_updates() called while unlocked");
+		BUG("write_with_updates() called while unlocked");
 
 	/*
 	 * If packed-refs is a symlink, we want to overwrite the
@@ -1563,21 +1563,21 @@ static int packed_create_symref(struct ref_store *ref_store,
 			       const char *refname, const char *target,
 			       const char *logmsg)
 {
-	die("BUG: packed reference store does not support symrefs");
+	BUG("packed reference store does not support symrefs");
 }
 
 static int packed_rename_ref(struct ref_store *ref_store,
 			    const char *oldrefname, const char *newrefname,
 			    const char *logmsg)
 {
-	die("BUG: packed reference store does not support renaming references");
+	BUG("packed reference store does not support renaming references");
 }
 
 static int packed_copy_ref(struct ref_store *ref_store,
 			   const char *oldrefname, const char *newrefname,
 			   const char *logmsg)
 {
-	die("BUG: packed reference store does not support copying references");
+	BUG("packed reference store does not support copying references");
 }
 
 static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)
@@ -1610,7 +1610,7 @@ static int packed_create_reflog(struct ref_store *ref_store,
 			       const char *refname, int force_create,
 			       struct strbuf *err)
 {
-	die("BUG: packed reference store does not support reflogs");
+	BUG("packed reference store does not support reflogs");
 }
 
 static int packed_delete_reflog(struct ref_store *ref_store,
diff --git a/refs/ref-cache.c b/refs/ref-cache.c
index e90bd3e727f..9b110c8494f 100644
--- a/refs/ref-cache.c
+++ b/refs/ref-cache.c
@@ -23,7 +23,7 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry)
 	dir = &entry->u.subdir;
 	if (entry->flag & REF_INCOMPLETE) {
 		if (!dir->cache->fill_ref_dir)
-			die("BUG: incomplete ref_store without fill_ref_dir function");
+			BUG("incomplete ref_store without fill_ref_dir function");
 
 		dir->cache->fill_ref_dir(dir->cache->ref_store, dir, entry->name);
 		entry->flag &= ~REF_INCOMPLETE;
-- 
2.17.0.windows.1.36.gdf4ca5fb72a



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/6] run-command: use BUG() to report bugs, not die()
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
                   ` (2 preceding siblings ...)
  2018-04-29 22:18 ` [PATCH 3/6] refs/*: report bugs using the BUG() macro Johannes Schindelin
@ 2018-04-29 22:18 ` Johannes Schindelin
  2018-04-29 22:19 ` [PATCH 5/6] Replace all die("BUG: ...") calls by BUG() ones Johannes Schindelin
  2018-04-29 22:19 ` [PATCH 6/6] Convert remaining die*(BUG) messages Johannes Schindelin
  5 siblings, 0 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:18 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

The slightly misleading name die_bug() of the function intended to
report a bug is actually called always, and only reports a bug if the
passed-in parameter `err` is non-zero.

It uses die_errno() to report the bug, to helpfully include the error
message corresponding to `err`.

However, as these messages indicate bugs, we really should use BUG().
And as BUG() is a macro to be able to report the exact file and line
number, we need to convert die_bug() to a macro instead of only
replacing the die_errno() by a call to BUG().

While at it, use a name more indicative of the purpose: CHECK_BUG().

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 run-command.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/run-command.c b/run-command.c
index 12c94c1dbe5..0ad6f135d5a 100644
--- a/run-command.c
+++ b/run-command.c
@@ -471,15 +471,12 @@ struct atfork_state {
 	sigset_t old;
 };
 
-#ifndef NO_PTHREADS
-static void bug_die(int err, const char *msg)
-{
-	if (err) {
-		errno = err;
-		die_errno("BUG: %s", msg);
-	}
-}
-#endif
+#define CHECK_BUG(err, msg) \
+	do { \
+		int e = (err); \
+		if (e) \
+			BUG("%s: %s", msg, strerror(e)); \
+	} while(0)
 
 static void atfork_prepare(struct atfork_state *as)
 {
@@ -491,9 +488,9 @@ static void atfork_prepare(struct atfork_state *as)
 	if (sigprocmask(SIG_SETMASK, &all, &as->old))
 		die_errno("sigprocmask");
 #else
-	bug_die(pthread_sigmask(SIG_SETMASK, &all, &as->old),
+	CHECK_BUG(pthread_sigmask(SIG_SETMASK, &all, &as->old),
 		"blocking all signals");
-	bug_die(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &as->cs),
+	CHECK_BUG(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &as->cs),
 		"disabling cancellation");
 #endif
 }
@@ -504,9 +501,9 @@ static void atfork_parent(struct atfork_state *as)
 	if (sigprocmask(SIG_SETMASK, &as->old, NULL))
 		die_errno("sigprocmask");
 #else
-	bug_die(pthread_setcancelstate(as->cs, NULL),
+	CHECK_BUG(pthread_setcancelstate(as->cs, NULL),
 		"re-enabling cancellation");
-	bug_die(pthread_sigmask(SIG_SETMASK, &as->old, NULL),
+	CHECK_BUG(pthread_sigmask(SIG_SETMASK, &as->old, NULL),
 		"restoring signal mask");
 #endif
 }
-- 
2.17.0.windows.1.36.gdf4ca5fb72a



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/6] Replace all die("BUG: ...") calls by BUG() ones
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
                   ` (3 preceding siblings ...)
  2018-04-29 22:18 ` [PATCH 4/6] run-command: use BUG() to report bugs, not die() Johannes Schindelin
@ 2018-04-29 22:19 ` Johannes Schindelin
  2018-04-29 22:19 ` [PATCH 6/6] Convert remaining die*(BUG) messages Johannes Schindelin
  5 siblings, 0 replies; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:19 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

In d8193743e08 (usage.c: add BUG() function, 2017-05-12), a new macro
was introduced to use for reporting bugs instead of die(). It was then
subsequently used to convert one single caller in 588a538ae55
(setup_git_env: convert die("BUG") to BUG(), 2017-05-12).

The cover letter of the patch series containing this patch
(cf 20170513032414.mfrwabt4hovujde2@sigill.intra.peff.net) is not
terribly clear why only one call site was converted, or what the plan
is for other, similar calls to die() to report bugs.

Let's just convert all remaining ones in one fell swoop.

This trick was performed by this invocation:

	sed -i 's/die("BUG: /BUG("/g' $(git grep -l 'die("BUG' \*.c)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 apply.c                          |  4 ++--
 archive-tar.c                    |  2 +-
 attr.c                           | 10 +++++-----
 blame.c                          |  2 +-
 builtin/am.c                     | 20 +++++++++----------
 builtin/branch.c                 |  2 +-
 builtin/cat-file.c               |  4 ++--
 builtin/clone.c                  |  2 +-
 builtin/commit.c                 |  2 +-
 builtin/config.c                 |  2 +-
 builtin/fast-export.c            |  2 +-
 builtin/fsck.c                   |  2 +-
 builtin/index-pack.c             |  4 ++--
 builtin/init-db.c                |  2 +-
 builtin/ls-files.c               |  2 +-
 builtin/notes.c                  |  8 ++++----
 builtin/pack-objects.c           |  4 ++--
 builtin/pull.c                   |  2 +-
 builtin/receive-pack.c           |  2 +-
 builtin/replace.c                |  2 +-
 builtin/update-index.c           |  2 +-
 bulk-checkin.c                   |  2 +-
 color.c                          |  4 ++--
 column.c                         |  2 +-
 config.c                         | 12 +++++------
 date.c                           |  2 +-
 diff.c                           | 12 +++++------
 dir-iterator.c                   |  2 +-
 grep.c                           | 16 +++++++--------
 http.c                           |  8 ++++----
 imap-send.c                      |  2 +-
 lockfile.c                       |  2 +-
 mailinfo.c                       |  2 +-
 merge-recursive.c                | 12 +++++------
 notes-merge.c                    |  4 ++--
 pack-bitmap-write.c              |  2 +-
 pack-bitmap.c                    |  6 +++---
 pack-objects.c                   |  2 +-
 packfile.c                       |  6 +++---
 pathspec.c                       | 10 +++++-----
 pkt-line.c                       |  2 +-
 prio-queue.c                     |  2 +-
 ref-filter.c                     |  4 ++--
 refs.c                           | 34 ++++++++++++++++----------------
 remote.c                         |  2 +-
 revision.c                       |  4 ++--
 run-command.c                    | 10 +++++-----
 setup.c                          |  4 ++--
 sha1-lookup.c                    |  2 +-
 sha1-name.c                      |  4 ++--
 shallow.c                        |  6 +++---
 sigchain.c                       |  2 +-
 strbuf.c                         |  4 ++--
 submodule.c                      |  6 +++---
 t/helper/test-example-decorate.c | 16 +++++++--------
 tmp-objdir.c                     |  2 +-
 trailer.c                        |  6 +++---
 transport.c                      |  4 ++--
 unpack-trees.c                   |  2 +-
 worktree.c                       |  2 +-
 wrapper.c                        |  4 ++--
 wt-status.c                      | 20 +++++++++----------
 zlib.c                           |  4 ++--
 63 files changed, 168 insertions(+), 168 deletions(-)

diff --git a/apply.c b/apply.c
index 7e5792c996f..3866adbc97f 100644
--- a/apply.c
+++ b/apply.c
@@ -2375,7 +2375,7 @@ static void update_pre_post_images(struct image *preimage,
 	if (postlen
 	    ? postlen < new_buf - postimage->buf
 	    : postimage->len < new_buf - postimage->buf)
-		die("BUG: caller miscounted postlen: asked %d, orig = %d, used = %d",
+		BUG("caller miscounted postlen: asked %d, orig = %d, used = %d",
 		    (int)postlen, (int) postimage->len, (int)(new_buf - postimage->buf));
 
 	/* Fix the length of the whole thing */
@@ -3509,7 +3509,7 @@ static int load_current(struct apply_state *state,
 	unsigned mode = patch->new_mode;
 
 	if (!patch->is_new)
-		die("BUG: patch to %s is not a creation", patch->old_name);
+		BUG("patch to %s is not a creation", patch->old_name);
 
 	pos = cache_name_pos(name, strlen(name));
 	if (pos < 0)
diff --git a/archive-tar.c b/archive-tar.c
index 3563bcb9f26..61a1a2547cc 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -441,7 +441,7 @@ static int write_tar_filter_archive(const struct archiver *ar,
 	int r;
 
 	if (!ar->data)
-		die("BUG: tar-filter archiver called with no filter defined");
+		BUG("tar-filter archiver called with no filter defined");
 
 	strbuf_addstr(&cmd, ar->data);
 	if (args->compression_level >= 0)
diff --git a/attr.c b/attr.c
index 03a678fa9be..067fb9e0c08 100644
--- a/attr.c
+++ b/attr.c
@@ -157,7 +157,7 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check)
 
 	size = hashmap_get_size(&map->map);
 	if (size < check->all_attrs_nr)
-		die("BUG: interned attributes shouldn't be deleted");
+		BUG("interned attributes shouldn't be deleted");
 
 	/*
 	 * If the number of attributes in the global dictionary has increased
@@ -541,7 +541,7 @@ static void check_vector_remove(struct attr_check *check)
 			break;
 
 	if (i >= check_vector.nr)
-		die("BUG: no entry found");
+		BUG("no entry found");
 
 	/* shift entries over */
 	for (; i < check_vector.nr - 1; i++)
@@ -599,11 +599,11 @@ struct attr_check *attr_check_initl(const char *one, ...)
 		const struct git_attr *attr;
 		param = va_arg(params, const char *);
 		if (!param)
-			die("BUG: counted %d != ended at %d",
+			BUG("counted %d != ended at %d",
 			    check->nr, cnt);
 		attr = git_attr(param);
 		if (!attr)
-			die("BUG: %s: not a valid attribute name", param);
+			BUG("%s: not a valid attribute name", param);
 		check->items[cnt].attr = attr;
 	}
 	va_end(params);
@@ -714,7 +714,7 @@ void git_attr_set_direction(enum git_attr_direction new_direction,
 			    struct index_state *istate)
 {
 	if (is_bare_repository() && new_direction != GIT_ATTR_INDEX)
-		die("BUG: non-INDEX attr direction in a bare repo");
+		BUG("non-INDEX attr direction in a bare repo");
 
 	if (new_direction != direction)
 		drop_all_attr_stacks();
diff --git a/blame.c b/blame.c
index 78c9808bd1a..89a1b11e922 100644
--- a/blame.c
+++ b/blame.c
@@ -1806,7 +1806,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
 			l->item = c;
 			if (add_decoration(&sb->revs->children,
 					   &c->parents->item->object, l))
-				die("BUG: not unique item in first-parent chain");
+				BUG("not unique item in first-parent chain");
 			c = c->parents->item;
 		}
 
diff --git a/builtin/am.c b/builtin/am.c
index d834f9e62b6..3dc2ef4259a 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -403,11 +403,11 @@ static void am_load(struct am_state *state)
 	struct strbuf sb = STRBUF_INIT;
 
 	if (read_state_file(&sb, state, "next", 1) < 0)
-		die("BUG: state file 'next' does not exist");
+		BUG("state file 'next' does not exist");
 	state->cur = strtol(sb.buf, NULL, 10);
 
 	if (read_state_file(&sb, state, "last", 1) < 0)
-		die("BUG: state file 'last' does not exist");
+		BUG("state file 'last' does not exist");
 	state->last = strtol(sb.buf, NULL, 10);
 
 	if (read_author_script(state) < 0)
@@ -986,7 +986,7 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
 	case PATCH_FORMAT_MBOXRD:
 		return split_mail_mbox(state, paths, keep_cr, 1);
 	default:
-		die("BUG: invalid patch_format");
+		BUG("invalid patch_format");
 	}
 	return -1;
 }
@@ -1041,7 +1041,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
 		str = "b";
 		break;
 	default:
-		die("BUG: invalid value for state->keep");
+		BUG("invalid value for state->keep");
 	}
 
 	write_state_text(state, "keep", str);
@@ -1058,7 +1058,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
 		str = "t";
 		break;
 	default:
-		die("BUG: invalid value for state->scissors");
+		BUG("invalid value for state->scissors");
 	}
 	write_state_text(state, "scissors", str);
 
@@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail)
 		mi.keep_non_patch_brackets_in_subject = 1;
 		break;
 	default:
-		die("BUG: invalid value for state->keep");
+		BUG("invalid value for state->keep");
 	}
 
 	if (state->message_id)
@@ -1232,7 +1232,7 @@ static int parse_mail(struct am_state *state, const char *mail)
 		mi.use_scissors = 1;
 		break;
 	default:
-		die("BUG: invalid value for state->scissors");
+		BUG("invalid value for state->scissors");
 	}
 
 	mi.input = xfopen(mail, "r");
@@ -1463,7 +1463,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
 	int options = 0;
 
 	if (init_apply_state(&apply_state, NULL))
-		die("BUG: init_apply_state() failed");
+		BUG("init_apply_state() failed");
 
 	argv_array_push(&apply_opts, "apply");
 	argv_array_pushv(&apply_opts, state->git_apply_opts.argv);
@@ -1489,7 +1489,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
 		apply_state.apply_verbosity = verbosity_silent;
 
 	if (check_apply_state(&apply_state, force_apply))
-		die("BUG: check_apply_state() failed");
+		BUG("check_apply_state() failed");
 
 	argv_array_push(&apply_paths, am_path(state, "patch"));
 
@@ -2407,7 +2407,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 		ret = show_patch(&state);
 		break;
 	default:
-		die("BUG: invalid resume value");
+		BUG("invalid resume value");
 	}
 
 	am_state_release(&state);
diff --git a/builtin/branch.c b/builtin/branch.c
index 5bd2a0dd489..1d4b3ce3d79 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -497,7 +497,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 
 	if (!skip_prefix(oldref.buf, "refs/heads/", &interpreted_oldname) ||
 	    !skip_prefix(newref.buf, "refs/heads/", &interpreted_newname)) {
-		die("BUG: expected prefix missing for refs");
+		BUG("expected prefix missing for refs");
 	}
 
 	if (copy)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 2c46d257cd9..1cc3ccc4515 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -312,7 +312,7 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
 					die("could not convert '%s' %s",
 					    oid_to_hex(oid), data->rest);
 			} else
-				die("BUG: invalid cmdmode: %c", opt->cmdmode);
+				BUG("invalid cmdmode: %c", opt->cmdmode);
 			batch_write(opt, contents, size);
 			free(contents);
 		} else if (stream_blob_to_fd(1, oid, NULL, 0) < 0)
@@ -387,7 +387,7 @@ static void batch_one_object(const char *obj_name, struct batch_options *opt,
 			       (uintmax_t)strlen(obj_name), obj_name);
 			break;
 		default:
-			die("BUG: unknown get_sha1_with_context result %d\n",
+			BUG("unknown get_sha1_with_context result %d\n",
 			       result);
 			break;
 		}
diff --git a/builtin/clone.c b/builtin/clone.c
index 7df5932b855..918820c539c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -823,7 +823,7 @@ static void write_refspec_config(const char *src_ref_prefix,
 			} else if (remote_head_points_at) {
 				const char *head = remote_head_points_at->name;
 				if (!skip_prefix(head, "refs/heads/", &head))
-					die("BUG: remote HEAD points at non-head?");
+					BUG("remote HEAD points at non-head?");
 
 				strbuf_addf(&value, "+%s:%s%s", remote_head_points_at->name,
 						branch_top->buf, head);
diff --git a/builtin/commit.c b/builtin/commit.c
index 5571d4a3e2b..7b47d1b7fb3 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -495,7 +495,7 @@ static int is_a_merge(const struct commit *current_head)
 static void assert_split_ident(struct ident_split *id, const struct strbuf *buf)
 {
 	if (split_ident_line(id, buf->buf, buf->len) || !id->date_begin)
-		die("BUG: unable to parse our own ident: %s", buf->buf);
+		BUG("unable to parse our own ident: %s", buf->buf);
 }
 
 static void export_one(const char *var, const char *s, const char *e, int hack)
diff --git a/builtin/config.c b/builtin/config.c
index 01169dd628b..c4f20332d74 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -309,7 +309,7 @@ static char *normalize_value(const char *key, const char *value)
 			return xstrdup(v ? "true" : "false");
 	}
 
-	die("BUG: cannot normalize type %d", types);
+	BUG("cannot normalize type %d", types);
 }
 
 static int get_color_found;
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index a15898d6417..116363f685c 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -517,7 +517,7 @@ static void anonymize_ident_line(const char **beg, const char **end)
 	/* skip "committer", "author", "tagger", etc */
 	end_of_header = strchr(*beg, ' ');
 	if (!end_of_header)
-		die("BUG: malformed line fed to anonymize_ident_line: %.*s",
+		BUG("malformed line fed to anonymize_ident_line: %.*s",
 		    (int)(*end - *beg), *beg);
 	end_of_header++;
 	strbuf_add(out, *beg, end_of_header - *beg);
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 087360a6757..1ea414480a4 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -519,7 +519,7 @@ static struct object *parse_loose_object(const struct object_id *oid,
 		return NULL;
 
 	if (!contents && type != OBJ_BLOB)
-		die("BUG: read_loose_object streamed a non-blob");
+		BUG("read_loose_object streamed a non-blob");
 
 	obj = parse_object_buffer(oid, type, size, contents, &eaten);
 
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 78e66b99866..21f22e34952 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -866,7 +866,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
 			if (obj->type == OBJ_COMMIT) {
 				struct commit *commit = (struct commit *) obj;
 				if (detach_commit_buffer(commit, NULL) != data)
-					die("BUG: parse_object_buffer transmogrified our buffer");
+					BUG("parse_object_buffer transmogrified our buffer");
 			}
 			obj->flags |= FLAG_CHECKED;
 		}
@@ -1015,7 +1015,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
 
 		if (!compare_and_swap_type(&child->real_type, OBJ_REF_DELTA,
 					   base->obj->real_type))
-			die("BUG: child->real_type != OBJ_REF_DELTA");
+			BUG("child->real_type != OBJ_REF_DELTA");
 
 		resolve_delta(child, base, result);
 		if (base->ref_first == base->ref_last && base->ofs_last == -1)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 2542c5244e9..5a5844c1538 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -391,7 +391,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
 		else if (get_shared_repository() == PERM_EVERYBODY)
 			xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY);
 		else
-			die("BUG: invalid value for shared_repository");
+			BUG("invalid value for shared_repository");
 		git_config_set("core.sharedrepository", buf);
 		git_config_set("receive.denyNonFastforwards", "true");
 	}
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index a71f6bd088a..967b2b3380d 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -166,7 +166,7 @@ static void show_killed_files(const struct index_state *istate,
 				 */
 				pos = index_name_pos(istate, ent->name, ent->len);
 				if (0 <= pos)
-					die("BUG: killed-file %.*s not found",
+					BUG("killed-file %.*s not found",
 						ent->len, ent->name);
 				pos = -pos - 1;
 				while (pos < istate->cache_nr &&
diff --git a/builtin/notes.c b/builtin/notes.c
index e5bf80eef1d..da279cdd349 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -461,7 +461,7 @@ static int add(int argc, const char **argv, const char *prefix)
 	if (d.buf.len || allow_empty) {
 		write_note_data(&d, &new_note);
 		if (add_note(t, &object, &new_note, combine_notes_overwrite))
-			die("BUG: combine_notes_overwrite failed");
+			BUG("combine_notes_overwrite failed");
 		commit_notes(t, "Notes added by 'git notes add'");
 	} else {
 		fprintf(stderr, _("Removing note for object %s\n"),
@@ -544,7 +544,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 	}
 
 	if (add_note(t, &object, from_note, combine_notes_overwrite))
-		die("BUG: combine_notes_overwrite failed");
+		BUG("combine_notes_overwrite failed");
 	commit_notes(t, "Notes added by 'git notes copy'");
 out:
 	free_notes(t);
@@ -621,7 +621,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
 	if (d.buf.len || allow_empty) {
 		write_note_data(&d, &new_note);
 		if (add_note(t, &object, &new_note, combine_notes_overwrite))
-			die("BUG: combine_notes_overwrite failed");
+			BUG("combine_notes_overwrite failed");
 		logmsg = xstrfmt("Notes added by 'git notes %s'", argv[0]);
 	} else {
 		fprintf(stderr, _("Removing note for object %s\n"),
@@ -831,7 +831,7 @@ static int merge(int argc, const char **argv, const char *prefix)
 		const char *short_ref = NULL;
 
 		if (!skip_prefix(o.local_ref, "refs/notes/", &short_ref))
-			die("BUG: local ref %s is outside of refs/notes/",
+			BUG("local ref %s is outside of refs/notes/",
 			    o.local_ref);
 
 		strbuf_addf(&merge_key, "notes.%s.mergeStrategy", short_ref);
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 4bdae5a1d8f..68de9134e1c 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1620,7 +1620,7 @@ static void break_delta_chains(struct object_entry *entry)
 		 * is a bug.
 		 */
 		if (cur->dfs_state != DFS_NONE)
-			die("BUG: confusing delta dfs state in first pass: %d",
+			BUG("confusing delta dfs state in first pass: %d",
 			    cur->dfs_state);
 
 		/*
@@ -1677,7 +1677,7 @@ static void break_delta_chains(struct object_entry *entry)
 		if (cur->dfs_state == DFS_DONE)
 			break;
 		else if (cur->dfs_state != DFS_ACTIVE)
-			die("BUG: confusing delta dfs state in second pass: %d",
+			BUG("confusing delta dfs state in second pass: %d",
 			    cur->dfs_state);
 
 		/*
diff --git a/builtin/pull.c b/builtin/pull.c
index 71aac5005e0..a886fa8ad4f 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -539,7 +539,7 @@ static int run_fetch(const char *repo, const char **refspecs)
 		argv_array_push(&args, repo);
 		argv_array_pushv(&args, refspecs);
 	} else if (*refspecs)
-		die("BUG: refspecs without repo?");
+		BUG("refspecs without repo?");
 	ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
 	argv_array_clear(&args);
 	return ret;
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 4b68a28e92e..2d719fa5117 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1378,7 +1378,7 @@ static void warn_if_skipped_connectivity_check(struct command *commands,
 		}
 	}
 	if (!checked_connectivity)
-		die("BUG: connectivity check skipped???");
+		BUG("connectivity check skipped???");
 }
 
 static void execute_commands_non_atomic(struct command *commands,
diff --git a/builtin/replace.c b/builtin/replace.c
index 935647be6bd..91a25394c00 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -501,6 +501,6 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
 		return list_replace_refs(argv[0], format);
 
 	default:
-		die("BUG: invalid cmdmode %d", (int)cmdmode);
+		BUG("invalid cmdmode %d", (int)cmdmode);
 	}
 }
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 10d070a76fb..ac19bbbb150 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -1164,7 +1164,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 		report(_("Untracked cache enabled for '%s'"), get_git_work_tree());
 		break;
 	default:
-		die("BUG: bad untracked_cache value: %d", untracked_cache);
+		BUG("bad untracked_cache value: %d", untracked_cache);
 	}
 
 	if (fsmonitor > 0) {
diff --git a/bulk-checkin.c b/bulk-checkin.c
index de1f4040c78..f8a549dd7a4 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -230,7 +230,7 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
 		 * pack, and write into it.
 		 */
 		if (!idx)
-			die("BUG: should not happen");
+			BUG("should not happen");
 		hashfile_truncate(state->f, &checkpoint);
 		state->offset = checkpoint.offset;
 		finish_bulk_checkin(state);
diff --git a/color.c b/color.c
index f277e72e4ce..be1040005b4 100644
--- a/color.c
+++ b/color.c
@@ -174,7 +174,7 @@ static char *color_output(char *out, int len, const struct color *c, char type)
 		break;
 	case COLOR_ANSI:
 		if (len < 2)
-			die("BUG: color parsing ran out of space");
+			BUG("color parsing ran out of space");
 		*out++ = type;
 		*out++ = '0' + c->value;
 		break;
@@ -256,7 +256,7 @@ int color_parse_mem(const char *value, int value_len, char *dst)
 #undef OUT
 #define OUT(x) do { \
 	if (dst == end) \
-		die("BUG: color parsing ran out of space"); \
+		BUG("color parsing ran out of space"); \
 	*dst++ = (x); \
 } while(0)
 
diff --git a/column.c b/column.c
index 49ab85b7691..2165297608e 100644
--- a/column.c
+++ b/column.c
@@ -214,7 +214,7 @@ void print_columns(const struct string_list *list, unsigned int colopts,
 		display_table(list, colopts, &nopts);
 		break;
 	default:
-		die("BUG: invalid layout mode %d", COL_LAYOUT(colopts));
+		BUG("invalid layout mode %d", COL_LAYOUT(colopts));
 	}
 }
 
diff --git a/config.c b/config.c
index 62c56099bf8..cface6ab8aa 100644
--- a/config.c
+++ b/config.c
@@ -102,7 +102,7 @@ static int config_buf_ungetc(int c, struct config_source *conf)
 	if (conf->u.buf.pos > 0) {
 		conf->u.buf.pos--;
 		if (conf->u.buf.buf[conf->u.buf.pos] != c)
-			die("BUG: config_buf can only ungetc the same character");
+			BUG("config_buf can only ungetc the same character");
 		return c;
 	}
 
@@ -189,7 +189,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
 		strbuf_realpath(&path, cf->path, 1);
 		slash = find_last_dir_sep(path.buf);
 		if (!slash)
-			die("BUG: how is this possible?");
+			BUG("how is this possible?");
 		strbuf_splice(pat, 0, 1, path.buf, slash - path.buf);
 		prefix = slash - path.buf + 1 /* slash */;
 	} else if (!is_absolute_path(pat->buf))
@@ -1717,7 +1717,7 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
 	l_item->value_index = e->value_list.nr - 1;
 
 	if (!cf)
-		die("BUG: configset_add_value has no source");
+		BUG("configset_add_value has no source");
 	if (cf->name) {
 		kv_info->filename = strintern(cf->name);
 		kv_info->linenr = cf->linenr;
@@ -3006,7 +3006,7 @@ const char *current_config_origin_type(void)
 	else if(cf)
 		type = cf->origin_type;
 	else
-		die("BUG: current_config_origin_type called outside config callback");
+		BUG("current_config_origin_type called outside config callback");
 
 	switch (type) {
 	case CONFIG_ORIGIN_BLOB:
@@ -3020,7 +3020,7 @@ const char *current_config_origin_type(void)
 	case CONFIG_ORIGIN_CMDLINE:
 		return "command line";
 	default:
-		die("BUG: unknown config origin type");
+		BUG("unknown config origin type");
 	}
 }
 
@@ -3032,7 +3032,7 @@ const char *current_config_name(void)
 	else if (cf)
 		name = cf->name;
 	else
-		die("BUG: current_config_name called outside config callback");
+		BUG("current_config_name called outside config callback");
 	return name ? name : "";
 }
 
diff --git a/date.c b/date.c
index c3e673fd042..49f943e25b5 100644
--- a/date.c
+++ b/date.c
@@ -185,7 +185,7 @@ struct date_mode *date_mode_from_type(enum date_mode_type type)
 {
 	static struct date_mode mode;
 	if (type == DATE_STRFTIME)
-		die("BUG: cannot create anonymous strftime date_mode struct");
+		BUG("cannot create anonymous strftime date_mode struct");
 	mode.type = type;
 	mode.local = 0;
 	return &mode;
diff --git a/diff.c b/diff.c
index 1289df4b1f9..9d8c7f60472 100644
--- a/diff.c
+++ b/diff.c
@@ -1184,7 +1184,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
 		fputs(o->stat_sep, o->file);
 		break;
 	default:
-		die("BUG: unknown diff symbol");
+		BUG("unknown diff symbol");
 	}
 	strbuf_release(&sb);
 }
@@ -1343,7 +1343,7 @@ static struct diff_tempfile *claim_diff_tempfile(void) {
 	for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
 		if (!diff_temp[i].name)
 			return diff_temp + i;
-	die("BUG: diff is failing to clean up its tempfiles");
+	BUG("diff is failing to clean up its tempfiles");
 }
 
 static void remove_tempfile(void)
@@ -3840,7 +3840,7 @@ static const char *diff_abbrev_oid(const struct object_id *oid, int abbrev)
 		if (abbrev < 0)
 			abbrev = FALLBACK_DEFAULT_ABBREV;
 		if (abbrev > GIT_SHA1_HEXSZ)
-			die("BUG: oid abbreviation out of range: %d", abbrev);
+			BUG("oid abbreviation out of range: %d", abbrev);
 		if (abbrev)
 			hex[abbrev] = '\0';
 		return hex;
@@ -4334,7 +4334,7 @@ static int stat_opt(struct diff_options *options, const char **av)
 	int argcount = 1;
 
 	if (!skip_prefix(arg, "--stat", &arg))
-		die("BUG: stat option does not begin with --stat: %s", arg);
+		BUG("stat option does not begin with --stat: %s", arg);
 	end = (char *)arg;
 
 	switch (*arg) {
@@ -5519,7 +5519,7 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
 	struct diff_queue_struct *q = &diff_queued_diff;
 
 	if (WSEH_NEW & WS_RULE_MASK)
-		die("BUG: WS rules bit mask overlaps with diff symbol flags");
+		BUG("WS rules bit mask overlaps with diff symbol flags");
 
 	if (o->color_moved)
 		o->emitted_symbols = &esm;
@@ -6053,7 +6053,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
 	}
 
 	if (!driver->textconv)
-		die("BUG: fill_textconv called with non-textconv driver");
+		BUG("fill_textconv called with non-textconv driver");
 
 	if (driver->textconv_cache && df->oid_valid) {
 		*outbuf = notes_cache_get(driver->textconv_cache,
diff --git a/dir-iterator.c b/dir-iterator.c
index 34182a9a1c1..f2dcd82fde9 100644
--- a/dir-iterator.c
+++ b/dir-iterator.c
@@ -188,7 +188,7 @@ struct dir_iterator *dir_iterator_begin(const char *path)
 	struct dir_iterator *dir_iterator = &iter->base;
 
 	if (!path || !*path)
-		die("BUG: empty path passed to dir_iterator_begin()");
+		BUG("empty path passed to dir_iterator_begin()");
 
 	strbuf_init(&iter->base.path, PATH_MAX);
 	strbuf_addstr(&iter->base.path, path);
diff --git a/grep.c b/grep.c
index 65b90c10a38..84f8054a3fd 100644
--- a/grep.c
+++ b/grep.c
@@ -404,7 +404,7 @@ static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)
 			die("Couldn't allocate PCRE JIT stack");
 		pcre_assign_jit_stack(p->pcre1_extra_info, NULL, p->pcre1_jit_stack);
 	} else if (p->pcre1_jit_on != 0) {
-		die("BUG: The pcre1_jit_on variable should be 0 or 1, not %d",
+		BUG("The pcre1_jit_on variable should be 0 or 1, not %d",
 		    p->pcre1_jit_on);
 	}
 #endif
@@ -550,7 +550,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 			die("Couldn't allocate PCRE2 match context");
 		pcre2_jit_stack_assign(p->pcre2_match_context, NULL, p->pcre2_jit_stack);
 	} else if (p->pcre2_jit_on != 0) {
-		die("BUG: The pcre2_jit_on variable should be 0 or 1, not %d",
+		BUG("The pcre2_jit_on variable should be 0 or 1, not %d",
 		    p->pcre1_jit_on);
 	}
 }
@@ -917,10 +917,10 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 
 	for (p = opt->header_list; p; p = p->next) {
 		if (p->token != GREP_PATTERN_HEAD)
-			die("BUG: a non-header pattern in grep header list.");
+			BUG("a non-header pattern in grep header list.");
 		if (p->field < GREP_HEADER_FIELD_MIN ||
 		    GREP_HEADER_FIELD_MAX <= p->field)
-			die("BUG: unknown header field %d", p->field);
+			BUG("unknown header field %d", p->field);
 		compile_regexp(p, opt);
 	}
 
@@ -933,7 +933,7 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 
 		h = compile_pattern_atom(&pp);
 		if (!h || pp != p->next)
-			die("BUG: malformed header expr");
+			BUG("malformed header expr");
 		if (!header_group[p->field]) {
 			header_group[p->field] = h;
 			continue;
@@ -1652,7 +1652,7 @@ static int fill_textconv_grep(struct userdiff_driver *driver,
 		fill_filespec(df, &null_oid, 0, 0100644);
 		break;
 	default:
-		die("BUG: attempt to textconv something without a path?");
+		BUG("attempt to textconv something without a path?");
 	}
 
 	/*
@@ -1748,7 +1748,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
 		case GREP_BINARY_TEXT:
 			break;
 		default:
-			die("BUG: unknown binary handling mode");
+			BUG("unknown binary handling mode");
 		}
 	}
 
@@ -2072,7 +2072,7 @@ static int grep_source_load(struct grep_source *gs)
 	case GREP_SOURCE_BUF:
 		return gs->buf ? 0 : -1;
 	}
-	die("BUG: invalid grep_source type to load");
+	BUG("invalid grep_source type to load");
 }
 
 void grep_source_load_driver(struct grep_source *gs)
diff --git a/http.c b/http.c
index 3034d10b680..ff60936bb0a 100644
--- a/http.c
+++ b/http.c
@@ -1855,7 +1855,7 @@ static int update_url_from_redirect(struct strbuf *base,
 		return 0;
 
 	if (!skip_prefix(asked, base->buf, &tail))
-		die("BUG: update_url_from_redirect: %s is not a superset of %s",
+		BUG("update_url_from_redirect: %s is not a superset of %s",
 		    asked, base->buf);
 
 	new_len = got->len;
@@ -1903,7 +1903,7 @@ static int http_request_reauth(const char *url,
 			strbuf_reset(result);
 			break;
 		default:
-			die("BUG: HTTP_KEEP_ERROR is only supported with strbufs");
+			BUG("HTTP_KEEP_ERROR is only supported with strbufs");
 		}
 	}
 
@@ -2114,7 +2114,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
 	*lst = (*lst)->next;
 
 	if (!strip_suffix(preq->tmpfile, ".pack.temp", &len))
-		die("BUG: pack tmpfile does not end in .pack.temp?");
+		BUG("pack tmpfile does not end in .pack.temp?");
 	tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
 
 	argv_array_push(&ip.args, "index-pack");
@@ -2210,7 +2210,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
 		CURLcode c = curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE,
 						&slot->http_code);
 		if (c != CURLE_OK)
-			die("BUG: curl_easy_getinfo for HTTP code failed: %s",
+			BUG("curl_easy_getinfo for HTTP code failed: %s",
 				curl_easy_strerror(c));
 		if (slot->http_code >= 300)
 			return size;
diff --git a/imap-send.c b/imap-send.c
index 3573cbfb0fc..b4eb886e2a6 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -511,7 +511,7 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
 
 	va_start(va, fmt);
 	if (blen <= 0 || (unsigned)(ret = vsnprintf(buf, blen, fmt, va)) >= (unsigned)blen)
-		die("BUG: buffer too small. Please report a bug.");
+		BUG("buffer too small. Please report a bug.");
 	va_end(va);
 	return ret;
 }
diff --git a/lockfile.c b/lockfile.c
index efcb7d7dfe3..8e8ab4f29f3 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -193,7 +193,7 @@ char *get_locked_file_path(struct lock_file *lk)
 	strbuf_addstr(&ret, get_tempfile_path(lk->tempfile));
 	if (ret.len <= LOCK_SUFFIX_LEN ||
 	    strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
-		die("BUG: get_locked_file_path() called for malformed lock object");
+		BUG("get_locked_file_path() called for malformed lock object");
 	/* remove ".lock": */
 	strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
 	return strbuf_detach(&ret, NULL);
diff --git a/mailinfo.c b/mailinfo.c
index d04142ccc76..3281a37d518 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -716,7 +716,7 @@ static void flush_inbody_header_accum(struct mailinfo *mi)
 	if (!mi->inbody_header_accum.len)
 		return;
 	if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data, 0))
-		die("BUG: inbody_header_accum, if not empty, must always contain a valid in-body header");
+		BUG("inbody_header_accum, if not empty, must always contain a valid in-body header");
 	strbuf_reset(&mi->inbody_header_accum);
 }
 
diff --git a/merge-recursive.c b/merge-recursive.c
index 0c0d48624da..6409d0770f2 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -318,7 +318,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
 				fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
 					(int)ce_namelen(ce), ce->name);
 		}
-		die("BUG: unmerged index entries in merge-recursive.c");
+		BUG("unmerged index entries in merge-recursive.c");
 	}
 
 	if (!active_cache_tree)
@@ -1060,7 +1060,7 @@ static int merge_file_1(struct merge_options *o,
 				break;
 			}
 		} else
-			die("BUG: unsupported object type in the tree");
+			BUG("unsupported object type in the tree");
 	}
 
 	return 0;
@@ -1462,7 +1462,7 @@ static int process_renames(struct merge_options *o,
 			const char *ren2_dst = ren2->pair->two->path;
 			enum rename_type rename_type;
 			if (strcmp(ren1_src, ren2_src) != 0)
-				die("BUG: ren1_src != ren2_src");
+				BUG("ren1_src != ren2_src");
 			ren2->dst_entry->processed = 1;
 			ren2->processed = 1;
 			if (strcmp(ren1_dst, ren2_dst) != 0) {
@@ -1496,7 +1496,7 @@ static int process_renames(struct merge_options *o,
 			ren2 = lookup->util;
 			ren2_dst = ren2->pair->two->path;
 			if (strcmp(ren1_dst, ren2_dst) != 0)
-				die("BUG: ren1_dst != ren2_dst");
+				BUG("ren1_dst != ren2_dst");
 
 			clean_merge = 0;
 			ren2->processed = 1;
@@ -1962,7 +1962,7 @@ static int process_entry(struct merge_options *o,
 		 */
 		remove_file(o, 1, path, !a_mode);
 	} else
-		die("BUG: fatal merge failure, shouldn't happen.");
+		BUG("fatal merge failure, shouldn't happen.");
 
 	return clean_merge;
 }
@@ -2040,7 +2040,7 @@ int merge_trees(struct merge_options *o,
 		for (i = 0; i < entries->nr; i++) {
 			struct stage_data *e = entries->items[i].util;
 			if (!e->processed)
-				die("BUG: unprocessed path??? %s",
+				BUG("unprocessed path??? %s",
 				    entries->items[i].string);
 		}
 
diff --git a/notes-merge.c b/notes-merge.c
index 8e0726a9418..720e24784c4 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -442,7 +442,7 @@ static int merge_one_change(struct notes_merge_options *o,
 			printf("Using remote notes for %s\n",
 						oid_to_hex(&p->obj));
 		if (add_note(t, &p->obj, &p->remote, combine_notes_overwrite))
-			die("BUG: combine_notes_overwrite failed");
+			BUG("combine_notes_overwrite failed");
 		return 0;
 	case NOTES_MERGE_RESOLVE_UNION:
 		if (o->verbosity >= 2)
@@ -490,7 +490,7 @@ static int merge_changes(struct notes_merge_options *o,
 			trace_printf("\t\t\tno local change, adopted remote\n");
 			if (add_note(t, &p->obj, &p->remote,
 				     combine_notes_overwrite))
-				die("BUG: combine_notes_overwrite failed");
+				BUG("combine_notes_overwrite failed");
 		} else {
 			/* need file-level merge between local and remote */
 			trace_printf("\t\t\tneed content-level merge\n");
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 41ae27fb19a..3c7b5edda8a 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -474,7 +474,7 @@ static void write_selected_commits_v1(struct hashfile *f,
 			sha1_pos(stored->commit->object.oid.hash, index, index_nr, sha1_access);
 
 		if (commit_pos < 0)
-			die("BUG: trying to write commit not in index");
+			BUG("trying to write commit not in index");
 
 		hashwrite_be32(f, commit_pos);
 		hashwrite_u8(f, stored->xor_offset);
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 3f2dab340f6..a4837af0f4b 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -255,7 +255,7 @@ static char *pack_bitmap_filename(struct packed_git *p)
 	size_t len;
 
 	if (!strip_suffix(p->pack_name, ".pack", &len))
-		die("BUG: pack_name does not end in .pack");
+		BUG("pack_name does not end in .pack");
 	return xstrfmt("%.*s.bitmap", (int)len, p->pack_name);
 }
 
@@ -723,13 +723,13 @@ int prepare_bitmap_walk(struct rev_info *revs)
 		revs->ignore_missing_links = 0;
 
 		if (haves_bitmap == NULL)
-			die("BUG: failed to perform bitmap walk");
+			BUG("failed to perform bitmap walk");
 	}
 
 	wants_bitmap = find_objects(revs, wants, haves_bitmap);
 
 	if (!wants_bitmap)
-		die("BUG: failed to perform bitmap walk");
+		BUG("failed to perform bitmap walk");
 
 	if (haves_bitmap)
 		bitmap_and_not(wants_bitmap, haves_bitmap);
diff --git a/pack-objects.c b/pack-objects.c
index 9558d13834e..0acab27133c 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -58,7 +58,7 @@ static void rehash_objects(struct packing_data *pdata)
 						       &found);
 
 		if (found)
-			die("BUG: Duplicate object in hash");
+			BUG("Duplicate object in hash");
 
 		pdata->index[ix] = i + 1;
 		entry++;
diff --git a/packfile.c b/packfile.c
index 0bc67d0e009..9df0dab44da 100644
--- a/packfile.c
+++ b/packfile.c
@@ -188,7 +188,7 @@ int open_pack_index(struct packed_git *p)
 		return 0;
 
 	if (!strip_suffix(p->pack_name, ".pack", &len))
-		die("BUG: pack_name does not end in .pack");
+		BUG("pack_name does not end in .pack");
 	idx_name = xstrfmt("%.*s.idx", (int)len, p->pack_name);
 	ret = check_packed_git_idx(idx_name, p);
 	free(idx_name);
@@ -317,7 +317,7 @@ void close_all_packs(struct raw_object_store *o)
 
 	for (p = o->packed_git; p; p = p->next)
 		if (p->do_not_close)
-			die("BUG: want to close pack marked 'do-not-close'");
+			BUG("want to close pack marked 'do-not-close'");
 		else
 			close_pack(p);
 }
@@ -1561,7 +1561,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
 	case OBJ_OFS_DELTA:
 	case OBJ_REF_DELTA:
 		if (data)
-			die("BUG: unpack_entry: left loop at a valid delta");
+			BUG("unpack_entry: left loop at a valid delta");
 		break;
 	case OBJ_COMMIT:
 	case OBJ_TREE:
diff --git a/pathspec.c b/pathspec.c
index 82eb39cd679..a637a6d15c0 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -198,7 +198,7 @@ static void parse_pathspec_attr_match(struct pathspec_item *item, const char *va
 	}
 
 	if (item->attr_check->nr != item->attr_match_nr)
-		die("BUG: should have same number of entries");
+		BUG("should have same number of entries");
 
 	string_list_clear(&list, 0);
 }
@@ -422,7 +422,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 
 	if (pathspec_prefix >= 0 &&
 	    (prefixlen || (prefix && *prefix)))
-		die("BUG: 'prefix' magic is supposed to be used at worktree's root");
+		BUG("'prefix' magic is supposed to be used at worktree's root");
 
 	if ((magic & PATHSPEC_LITERAL) && (magic & PATHSPEC_GLOB))
 		die(_("%s: 'literal' and 'glob' are incompatible"), elt);
@@ -545,7 +545,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
 	if ((flags & PATHSPEC_PREFER_CWD) &&
 	    (flags & PATHSPEC_PREFER_FULL))
-		die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible");
+		BUG("PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible");
 
 	/* No arguments with prefix -> prefix pathspec */
 	if (!entry) {
@@ -553,7 +553,7 @@ void parse_pathspec(struct pathspec *pathspec,
 			return;
 
 		if (!(flags & PATHSPEC_PREFER_CWD))
-			die("BUG: PATHSPEC_PREFER_CWD requires arguments");
+			BUG("PATHSPEC_PREFER_CWD requires arguments");
 
 		pathspec->items = item = xcalloc(1, sizeof(*item));
 		item->match = xstrdup(prefix);
@@ -609,7 +609,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
 	if (pathspec->magic & PATHSPEC_MAXDEPTH) {
 		if (flags & PATHSPEC_KEEP_ORDER)
-			die("BUG: PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
+			BUG("PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
 		QSORT(pathspec->items, pathspec->nr, pathspec_item_cmp);
 	}
 }
diff --git a/pkt-line.c b/pkt-line.c
index 2827ca772a3..cd3dab4025a 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -249,7 +249,7 @@ static int get_packet_data(int fd, char **src_buf, size_t *src_size,
 	ssize_t ret;
 
 	if (fd >= 0 && src_buf && *src_buf)
-		die("BUG: multiple sources given to packet_read");
+		BUG("multiple sources given to packet_read");
 
 	/* Read up to "size" bytes from our source, whatever it is. */
 	if (src_buf && *src_buf) {
diff --git a/prio-queue.c b/prio-queue.c
index 126d0967273..a0784518723 100644
--- a/prio-queue.c
+++ b/prio-queue.c
@@ -20,7 +20,7 @@ void prio_queue_reverse(struct prio_queue *queue)
 	int i, j;
 
 	if (queue->compare != NULL)
-		die("BUG: prio_queue_reverse() on non-LIFO queue");
+		BUG("prio_queue_reverse() on non-LIFO queue");
 	for (i = 0; i < (j = (queue->nr - 1) - i); i++)
 		swap(queue, i, j);
 }
diff --git a/ref-filter.c b/ref-filter.c
index ac82f9f21e1..0291feaf0db 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -751,7 +751,7 @@ static int grab_objectname(const char *name, const struct object_id *oid,
 			v->s = xstrdup(find_unique_abbrev(oid, atom->u.objectname.length));
 			return 1;
 		} else
-			die("BUG: unknown %%(objectname) option");
+			BUG("unknown %%(objectname) option");
 	}
 	return 0;
 }
@@ -1299,7 +1299,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
 		else
 			*s = "";
 	} else
-		die("BUG: unhandled RR_* enum");
+		BUG("unhandled RR_* enum");
 }
 
 char *get_head_description(void)
diff --git a/refs.c b/refs.c
index 8b7a77fe5ee..f7a577c0d60 100644
--- a/refs.c
+++ b/refs.c
@@ -944,10 +944,10 @@ void ref_transaction_free(struct ref_transaction *transaction)
 		/* OK */
 		break;
 	case REF_TRANSACTION_PREPARED:
-		die("BUG: free called on a prepared reference transaction");
+		BUG("free called on a prepared reference transaction");
 		break;
 	default:
-		die("BUG: unexpected reference transaction state");
+		BUG("unexpected reference transaction state");
 		break;
 	}
 
@@ -969,7 +969,7 @@ struct ref_update *ref_transaction_add_update(
 	struct ref_update *update;
 
 	if (transaction->state != REF_TRANSACTION_OPEN)
-		die("BUG: update called for transaction that is not open");
+		BUG("update called for transaction that is not open");
 
 	FLEX_ALLOC_STR(update, refname, refname);
 	ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
@@ -1019,7 +1019,7 @@ int ref_transaction_create(struct ref_transaction *transaction,
 			   struct strbuf *err)
 {
 	if (!new_oid || is_null_oid(new_oid))
-		die("BUG: create called without valid new_oid");
+		BUG("create called without valid new_oid");
 	return ref_transaction_update(transaction, refname, new_oid,
 				      &null_oid, flags, msg, err);
 }
@@ -1031,7 +1031,7 @@ int ref_transaction_delete(struct ref_transaction *transaction,
 			   struct strbuf *err)
 {
 	if (old_oid && is_null_oid(old_oid))
-		die("BUG: delete called with old_oid set to zeros");
+		BUG("delete called with old_oid set to zeros");
 	return ref_transaction_update(transaction, refname,
 				      &null_oid, old_oid,
 				      flags, msg, err);
@@ -1044,7 +1044,7 @@ int ref_transaction_verify(struct ref_transaction *transaction,
 			   struct strbuf *err)
 {
 	if (!old_oid)
-		die("BUG: verify called with old_oid set to NULL");
+		BUG("verify called with old_oid set to NULL");
 	return ref_transaction_update(transaction, refname,
 				      NULL, old_oid,
 				      flags, NULL, err);
@@ -1645,7 +1645,7 @@ static struct ref_store *ref_store_init(const char *gitdir,
 	struct ref_store *refs;
 
 	if (!be)
-		die("BUG: reference backend %s is unknown", be_name);
+		BUG("reference backend %s is unknown", be_name);
 
 	refs = be->init(gitdir, flags);
 	return refs;
@@ -1673,7 +1673,7 @@ static void register_ref_store_map(struct hashmap *map,
 		hashmap_init(map, ref_store_hash_cmp, NULL, 0);
 
 	if (hashmap_put(map, alloc_ref_store_hash_entry(name, refs)))
-		die("BUG: %s ref_store '%s' initialized twice", type, name);
+		BUG("%s ref_store '%s' initialized twice", type, name);
 }
 
 struct ref_store *get_submodule_ref_store(const char *submodule)
@@ -1819,7 +1819,7 @@ int ref_update_reject_duplicates(struct string_list *refnames,
 				    refnames->items[i].string);
 			return 1;
 		} else if (cmp > 0) {
-			die("BUG: ref_update_reject_duplicates() received unsorted list");
+			BUG("ref_update_reject_duplicates() received unsorted list");
 		}
 	}
 	return 0;
@@ -1835,13 +1835,13 @@ int ref_transaction_prepare(struct ref_transaction *transaction,
 		/* Good. */
 		break;
 	case REF_TRANSACTION_PREPARED:
-		die("BUG: prepare called twice on reference transaction");
+		BUG("prepare called twice on reference transaction");
 		break;
 	case REF_TRANSACTION_CLOSED:
-		die("BUG: prepare called on a closed reference transaction");
+		BUG("prepare called on a closed reference transaction");
 		break;
 	default:
-		die("BUG: unexpected reference transaction state");
+		BUG("unexpected reference transaction state");
 		break;
 	}
 
@@ -1868,10 +1868,10 @@ int ref_transaction_abort(struct ref_transaction *transaction,
 		ret = refs->be->transaction_abort(refs, transaction, err);
 		break;
 	case REF_TRANSACTION_CLOSED:
-		die("BUG: abort called on a closed reference transaction");
+		BUG("abort called on a closed reference transaction");
 		break;
 	default:
-		die("BUG: unexpected reference transaction state");
+		BUG("unexpected reference transaction state");
 		break;
 	}
 
@@ -1896,10 +1896,10 @@ int ref_transaction_commit(struct ref_transaction *transaction,
 		/* Fall through to finish. */
 		break;
 	case REF_TRANSACTION_CLOSED:
-		die("BUG: commit called on a closed reference transaction");
+		BUG("commit called on a closed reference transaction");
 		break;
 	default:
-		die("BUG: unexpected reference transaction state");
+		BUG("unexpected reference transaction state");
 		break;
 	}
 
@@ -1980,7 +1980,7 @@ int refs_verify_refname_available(struct ref_store *refs,
 	}
 
 	if (ok != ITER_DONE)
-		die("BUG: error while iterating over references");
+		BUG("error while iterating over references");
 
 	extra_refname = find_descendant_ref(dirname.buf, extras, skip);
 	if (extra_refname)
diff --git a/remote.c b/remote.c
index 91eb010ca98..63c41787882 100644
--- a/remote.c
+++ b/remote.c
@@ -1819,7 +1819,7 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
 		}
 	}
 
-	die("BUG: unhandled push situation");
+	BUG("unhandled push situation");
 }
 
 const char *branch_get_push(struct branch *branch, struct strbuf *err)
diff --git a/revision.c b/revision.c
index b42c836d7a6..67f8e74cbb3 100644
--- a/revision.c
+++ b/revision.c
@@ -2107,7 +2107,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->ignore_missing = 1;
 	} else if (!strcmp(arg, "--exclude-promisor-objects")) {
 		if (fetch_if_missing)
-			die("BUG: exclude_promisor_objects can only be used when fetch_if_missing is 0");
+			BUG("exclude_promisor_objects can only be used when fetch_if_missing is 0");
 		revs->exclude_promisor_objects = 1;
 	} else {
 		int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);
@@ -2173,7 +2173,7 @@ static int handle_revision_pseudo_opt(const char *submodule,
 		 * supported right now, so stick to single worktree.
 		 */
 		if (!revs->single_worktree)
-			die("BUG: --single-worktree cannot be used together with submodule");
+			BUG("--single-worktree cannot be used together with submodule");
 		refs = get_submodule_ref_store(submodule);
 	} else
 		refs = get_main_ref_store();
diff --git a/run-command.c b/run-command.c
index 0ad6f135d5a..84b883c2132 100644
--- a/run-command.c
+++ b/run-command.c
@@ -245,7 +245,7 @@ int sane_execvp(const char *file, char * const argv[])
 static const char **prepare_shell_cmd(struct argv_array *out, const char **argv)
 {
 	if (!argv[0])
-		die("BUG: shell command is empty");
+		BUG("shell command is empty");
 
 	if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
 #ifndef GIT_WINDOWS_NATIVE
@@ -383,7 +383,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
 static void prepare_cmd(struct argv_array *out, const struct child_process *cmd)
 {
 	if (!cmd->argv[0])
-		die("BUG: command is empty");
+		BUG("command is empty");
 
 	/*
 	 * Add SHELL_PATH so in the event exec fails with ENOEXEC we can
@@ -964,7 +964,7 @@ int run_command(struct child_process *cmd)
 	int code;
 
 	if (cmd->out < 0 || cmd->err < 0)
-		die("BUG: run_command with a pipe can cause deadlock");
+		BUG("run_command with a pipe can cause deadlock");
 
 	code = start_command(cmd);
 	if (code)
@@ -1554,7 +1554,7 @@ static void pp_init(struct parallel_processes *pp,
 
 	pp->data = data;
 	if (!get_next_task)
-		die("BUG: you need to specify a get_next_task function");
+		BUG("you need to specify a get_next_task function");
 	pp->get_next_task = get_next_task;
 
 	pp->start_failure = start_failure ? start_failure : default_start_failure;
@@ -1616,7 +1616,7 @@ static int pp_start_one(struct parallel_processes *pp)
 		if (pp->children[i].state == GIT_CP_FREE)
 			break;
 	if (i == pp->max_processes)
-		die("BUG: bookkeeping is hard");
+		BUG("bookkeeping is hard");
 
 	code = pp->get_next_task(&pp->children[i].process,
 				 &pp->children[i].err,
diff --git a/setup.c b/setup.c
index 3e03d442b6f..b24c811c1c3 100644
--- a/setup.c
+++ b/setup.c
@@ -539,7 +539,7 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir)
 	case READ_GITFILE_ERR_NOT_A_REPO:
 		die(_("not a git repository: %s"), dir);
 	default:
-		die("BUG: unknown error code");
+		BUG("unknown error code");
 	}
 }
 
@@ -1086,7 +1086,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 		      "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."),
 		    dir.buf);
 	default:
-		die("BUG: unhandled setup_git_directory_1() result");
+		BUG("unhandled setup_git_directory_1() result");
 	}
 
 	if (prefix)
diff --git a/sha1-lookup.c b/sha1-lookup.c
index 8d0b1db3e27..796ab68da83 100644
--- a/sha1-lookup.c
+++ b/sha1-lookup.c
@@ -81,7 +81,7 @@ int sha1_pos(const unsigned char *sha1, void *table, size_t nr,
 				mi = (nr - 1) * (miv - lov) / (hiv - lov);
 				if (lo <= mi && mi < hi)
 					break;
-				die("BUG: assertion failed in binary search");
+				BUG("assertion failed in binary search");
 			}
 		}
 	}
diff --git a/sha1-name.c b/sha1-name.c
index 5b93bf8da36..60d04bf74e1 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -384,7 +384,7 @@ static int get_short_oid(const char *name, int len, struct object_id *oid,
 		return -1;
 
 	if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
-		die("BUG: multiple get_short_oid disambiguator flags");
+		BUG("multiple get_short_oid disambiguator flags");
 
 	if (flags & GET_OID_COMMIT)
 		ds.fn = disambiguate_commit_only;
@@ -1729,6 +1729,6 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
 int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc)
 {
 	if (flags & GET_OID_FOLLOW_SYMLINKS && flags & GET_OID_ONLY_TO_DIE)
-		die("BUG: incompatible flags for get_sha1_with_context");
+		BUG("incompatible flags for get_sha1_with_context");
 	return get_oid_with_context_1(str, flags, NULL, oid, oc);
 }
diff --git a/shallow.c b/shallow.c
index df4d44ea7a3..c7b6b3d9d8a 100644
--- a/shallow.c
+++ b/shallow.c
@@ -20,7 +20,7 @@ static char *alternate_shallow_file;
 void set_alternate_shallow_file(const char *path, int override)
 {
 	if (is_shallow != -1)
-		die("BUG: is_repository_shallow must not be called before set_alternate_shallow_file");
+		BUG("is_repository_shallow must not be called before set_alternate_shallow_file");
 	if (alternate_shallow_file && !override)
 		return;
 	free(alternate_shallow_file);
@@ -218,7 +218,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
 static void check_shallow_file_for_update(void)
 {
 	if (is_shallow == -1)
-		die("BUG: shallow must be initialized by now");
+		BUG("shallow must be initialized by now");
 
 	if (!stat_validity_check(&shallow_stat, git_path_shallow()))
 		die("shallow file has changed since we read it");
@@ -446,7 +446,7 @@ static uint32_t *paint_alloc(struct paint_info *info)
 	void *p;
 	if (!info->pool_count || size > info->end - info->free) {
 		if (size > POOL_SIZE)
-			die("BUG: pool size too small for %d in paint_alloc()",
+			BUG("pool size too small for %d in paint_alloc()",
 			    size);
 		info->pool_count++;
 		REALLOC_ARRAY(info->pools, info->pool_count);
diff --git a/sigchain.c b/sigchain.c
index 2ac43bbd282..022677b6aba 100644
--- a/sigchain.c
+++ b/sigchain.c
@@ -13,7 +13,7 @@ static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS];
 static void check_signum(int sig)
 {
 	if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS)
-		die("BUG: signal out of range: %d", sig);
+		BUG("signal out of range: %d", sig);
 }
 
 int sigchain_push(int sig, sigchain_fun f)
diff --git a/strbuf.c b/strbuf.c
index 43a840c67b3..2954622c103 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -309,12 +309,12 @@ void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
 	len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, cp);
 	va_end(cp);
 	if (len < 0)
-		die("BUG: your vsnprintf is broken (returned %d)", len);
+		BUG("your vsnprintf is broken (returned %d)", len);
 	if (len > strbuf_avail(sb)) {
 		strbuf_grow(sb, len);
 		len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
 		if (len > strbuf_avail(sb))
-			die("BUG: your vsnprintf is broken (insatiable)");
+			BUG("your vsnprintf is broken (insatiable)");
 	}
 	strbuf_setlen(sb, sb->len + len);
 }
diff --git a/submodule.c b/submodule.c
index 9a50168b237..733db441714 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1398,7 +1398,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
 		    buf.buf[0] == '2') {
 			/* T = line type, XY = status, SSSS = submodule state */
 			if (buf.len < strlen("T XY SSSS"))
-				die("BUG: invalid status --porcelain=2 line %s",
+				BUG("invalid status --porcelain=2 line %s",
 				    buf.buf);
 
 			if (buf.buf[5] == 'S' && buf.buf[8] == 'U')
@@ -1607,7 +1607,7 @@ int submodule_move_head(const char *path,
 	sub = submodule_from_path(&null_oid, path);
 
 	if (!sub)
-		die("BUG: could not get submodule information for '%s'", path);
+		BUG("could not get submodule information for '%s'", path);
 
 	if (old_head && !(flags & SUBMODULE_MOVE_HEAD_FORCE)) {
 		/* Check if the submodule has a dirty index. */
@@ -1965,7 +1965,7 @@ void absorb_git_dir_into_superproject(const char *prefix,
 		struct strbuf sb = STRBUF_INIT;
 
 		if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
-			die("BUG: we don't know how to pass the flags down?");
+			BUG("we don't know how to pass the flags down?");
 
 		strbuf_addstr(&sb, get_super_prefix_or_empty());
 		strbuf_addstr(&sb, path);
diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c
index 081115bf8eb..a20a6161e4f 100644
--- a/t/helper/test-example-decorate.c
+++ b/t/helper/test-example-decorate.c
@@ -30,10 +30,10 @@ int cmd__example_decorate(int argc, const char **argv)
 	two = lookup_unknown_object(two_oid.hash);
 	ret = add_decoration(&n, one, &decoration_a);
 	if (ret)
-		die("BUG: when adding a brand-new object, NULL should be returned");
+		BUG("when adding a brand-new object, NULL should be returned");
 	ret = add_decoration(&n, two, NULL);
 	if (ret)
-		die("BUG: when adding a brand-new object, NULL should be returned");
+		BUG("when adding a brand-new object, NULL should be returned");
 
 	/*
 	 * When re-adding an already existing object, the old decoration is
@@ -41,10 +41,10 @@ int cmd__example_decorate(int argc, const char **argv)
 	 */
 	ret = add_decoration(&n, one, NULL);
 	if (ret != &decoration_a)
-		die("BUG: when readding an already existing object, existing decoration should be returned");
+		BUG("when readding an already existing object, existing decoration should be returned");
 	ret = add_decoration(&n, two, &decoration_b);
 	if (ret)
-		die("BUG: when readding an already existing object, existing decoration should be returned");
+		BUG("when readding an already existing object, existing decoration should be returned");
 
 	/*
 	 * Lookup returns the added declarations, or NULL if the object was
@@ -52,14 +52,14 @@ int cmd__example_decorate(int argc, const char **argv)
 	 */
 	ret = lookup_decoration(&n, one);
 	if (ret)
-		die("BUG: lookup should return added declaration");
+		BUG("lookup should return added declaration");
 	ret = lookup_decoration(&n, two);
 	if (ret != &decoration_b)
-		die("BUG: lookup should return added declaration");
+		BUG("lookup should return added declaration");
 	three = lookup_unknown_object(three_oid.hash);
 	ret = lookup_decoration(&n, three);
 	if (ret)
-		die("BUG: lookup for unknown object should return NULL");
+		BUG("lookup for unknown object should return NULL");
 
 	/*
 	 * The user can also loop through all entries.
@@ -69,7 +69,7 @@ int cmd__example_decorate(int argc, const char **argv)
 			objects_noticed++;
 	}
 	if (objects_noticed != 2)
-		die("BUG: should have 2 objects");
+		BUG("should have 2 objects");
 
 	return 0;
 }
diff --git a/tmp-objdir.c b/tmp-objdir.c
index fea3f55545c..91c00567f4d 100644
--- a/tmp-objdir.c
+++ b/tmp-objdir.c
@@ -127,7 +127,7 @@ struct tmp_objdir *tmp_objdir_create(void)
 	struct tmp_objdir *t;
 
 	if (the_tmp_objdir)
-		die("BUG: only one tmp_objdir can be used at a time");
+		BUG("only one tmp_objdir can be used at a time");
 
 	t = xmalloc(sizeof(*t));
 	strbuf_init(&t->path, 0);
diff --git a/trailer.c b/trailer.c
index c508c9b7521..4e309460d13 100644
--- a/trailer.c
+++ b/trailer.c
@@ -298,7 +298,7 @@ static void apply_arg_if_exists(struct trailer_item *in_tok,
 			free_arg_item(arg_tok);
 		break;
 	default:
-		die("BUG: trailer.c: unhandled value %d",
+		BUG("trailer.c: unhandled value %d",
 		    arg_tok->conf.if_exists);
 	}
 }
@@ -323,7 +323,7 @@ static void apply_arg_if_missing(struct list_head *head,
 			list_add(&to_add->list, head);
 		break;
 	default:
-		die("BUG: trailer.c: unhandled value %d",
+		BUG("trailer.c: unhandled value %d",
 		    arg_tok->conf.if_missing);
 	}
 }
@@ -557,7 +557,7 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
 			warning(_("unknown value '%s' for key '%s'"), value, conf_key);
 		break;
 	default:
-		die("BUG: trailer.c: unhandled type %d", type);
+		BUG("trailer.c: unhandled type %d", type);
 	}
 	return 0;
 }
diff --git a/transport.c b/transport.c
index 94eccf29aa3..969645ccb13 100644
--- a/transport.c
+++ b/transport.c
@@ -636,7 +636,7 @@ void transport_take_over(struct transport *transport,
 	struct git_transport_data *data;
 
 	if (!transport->smart_options)
-		die("BUG: taking over transport requires non-NULL "
+		BUG("taking over transport requires non-NULL "
 		    "smart_options field.");
 
 	data = xcalloc(1, sizeof(*data));
@@ -761,7 +761,7 @@ int is_transport_allowed(const char *type, int from_user)
 		return from_user;
 	}
 
-	die("BUG: invalid protocol_allow_config type");
+	BUG("invalid protocol_allow_config type");
 }
 
 void transport_check_allowed(const char *type)
diff --git a/unpack-trees.c b/unpack-trees.c
index e73745051e5..4239dfd285e 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -398,7 +398,7 @@ static int check_updates(struct unpack_trees_options *o)
 
 		if (ce->ce_flags & CE_UPDATE) {
 			if (ce->ce_flags & CE_WT_REMOVE)
-				die("BUG: both update and delete flags are set on %s",
+				BUG("both update and delete flags are set on %s",
 				    ce->name);
 			display_progress(progress, ++cnt);
 			ce->ce_flags &= ~CE_UPDATE;
diff --git a/worktree.c b/worktree.c
index 28989cf06ef..97cda5f97bb 100644
--- a/worktree.c
+++ b/worktree.c
@@ -338,7 +338,7 @@ void update_worktree_location(struct worktree *wt, const char *path_)
 	struct strbuf path = STRBUF_INIT;
 
 	if (is_main_worktree(wt))
-		die("BUG: can't relocate main worktree");
+		BUG("can't relocate main worktree");
 
 	strbuf_realpath(&path, path_, 1);
 	if (fspathcmp(wt->path, path.buf)) {
diff --git a/wrapper.c b/wrapper.c
index 1fd5e33ea8f..e4fa9d84cd0 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -643,9 +643,9 @@ int xsnprintf(char *dst, size_t max, const char *fmt, ...)
 	va_end(ap);
 
 	if (len < 0)
-		die("BUG: your snprintf is broken");
+		BUG("your snprintf is broken");
 	if (len >= max)
-		die("BUG: attempt to snprintf into too-small buffer");
+		BUG("attempt to snprintf into too-small buffer");
 	return len;
 }
 
diff --git a/wt-status.c b/wt-status.c
index 50815e5faff..26d037610ee 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -264,7 +264,7 @@ static const char *wt_status_unmerged_status_string(int stagemask)
 	case 7:
 		return _("both modified:");
 	default:
-		die("BUG: unhandled unmerged status %x", stagemask);
+		BUG("unhandled unmerged status %x", stagemask);
 	}
 }
 
@@ -377,7 +377,7 @@ static void wt_longstatus_print_change_data(struct wt_status *s,
 		status = d->worktree_status;
 		break;
 	default:
-		die("BUG: unhandled change_type %d in wt_longstatus_print_change_data",
+		BUG("unhandled change_type %d in wt_longstatus_print_change_data",
 		    change_type);
 	}
 
@@ -395,7 +395,7 @@ static void wt_longstatus_print_change_data(struct wt_status *s,
 	status_printf(s, color(WT_STATUS_HEADER, s), "\t");
 	what = wt_status_diff_status_string(status);
 	if (!what)
-		die("BUG: unhandled diff status %c", status);
+		BUG("unhandled diff status %c", status);
 	len = label_width - utf8_strwidth(what);
 	assert(len >= 0);
 	if (one_name != two_name)
@@ -470,7 +470,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
 		case DIFF_STATUS_COPIED:
 		case DIFF_STATUS_RENAMED:
 			if (d->rename_status)
-				die("BUG: multiple renames on the same target? how?");
+				BUG("multiple renames on the same target? how?");
 			d->rename_source = xstrdup(p->one->path);
 			d->rename_score = p->score * 100 / MAX_SCORE;
 			d->rename_status = p->status;
@@ -484,7 +484,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
 			break;
 
 		default:
-			die("BUG: unhandled diff-files status '%c'", p->status);
+			BUG("unhandled diff-files status '%c'", p->status);
 			break;
 		}
 
@@ -547,7 +547,7 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
 		case DIFF_STATUS_COPIED:
 		case DIFF_STATUS_RENAMED:
 			if (d->rename_status)
-				die("BUG: multiple renames on the same target? how?");
+				BUG("multiple renames on the same target? how?");
 			d->rename_source = xstrdup(p->one->path);
 			d->rename_score = p->score * 100 / MAX_SCORE;
 			d->rename_status = p->status;
@@ -569,7 +569,7 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
 			break;
 
 		default:
-			die("BUG: unhandled diff-index status '%c'", p->status);
+			BUG("unhandled diff-index status '%c'", p->status);
 			break;
 		}
 	}
@@ -2158,7 +2158,7 @@ static void wt_porcelain_v2_print_unmerged_entry(
 	case 6: key = "AA"; break; /* both added */
 	case 7: key = "UU"; break; /* both modified */
 	default:
-		die("BUG: unhandled unmerged status %x", d->stagemask);
+		BUG("unhandled unmerged status %x", d->stagemask);
 	}
 
 	/*
@@ -2185,7 +2185,7 @@ static void wt_porcelain_v2_print_unmerged_entry(
 		sum |= (1 << (stage - 1));
 	}
 	if (sum != d->stagemask)
-		die("BUG: observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
+		BUG("observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
 
 	if (s->null_termination)
 		path_index = it->string;
@@ -2289,7 +2289,7 @@ void wt_status_print(struct wt_status *s)
 		wt_porcelain_v2_print(s);
 		break;
 	case STATUS_FORMAT_UNSPECIFIED:
-		die("BUG: finalize_deferred_config() should have been called");
+		BUG("finalize_deferred_config() should have been called");
 		break;
 	case STATUS_FORMAT_NONE:
 	case STATUS_FORMAT_LONG:
diff --git a/zlib.c b/zlib.c
index 4223f1a8c57..d594cba3fc9 100644
--- a/zlib.c
+++ b/zlib.c
@@ -52,9 +52,9 @@ static void zlib_post_call(git_zstream *s)
 	bytes_consumed = s->z.next_in - s->next_in;
 	bytes_produced = s->z.next_out - s->next_out;
 	if (s->z.total_out != s->total_out + bytes_produced)
-		die("BUG: total_out mismatch");
+		BUG("total_out mismatch");
 	if (s->z.total_in != s->total_in + bytes_consumed)
-		die("BUG: total_in mismatch");
+		BUG("total_in mismatch");
 
 	s->total_out = s->z.total_out;
 	s->total_in = s->z.total_in;
-- 
2.17.0.windows.1.36.gdf4ca5fb72a



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 6/6] Convert remaining die*(BUG) messages
  2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
                   ` (4 preceding siblings ...)
  2018-04-29 22:19 ` [PATCH 5/6] Replace all die("BUG: ...") calls by BUG() ones Johannes Schindelin
@ 2018-04-29 22:19 ` Johannes Schindelin
  2018-04-30  2:53   ` Eric Sunshine
  5 siblings, 1 reply; 15+ messages in thread
From: Johannes Schindelin @ 2018-04-29 22:19 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Jeff King

These were not caught by the previous commit, as they did not match the
regular expression.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 git-compat-util.h     | 2 +-
 pathspec.c            | 2 +-
 submodule.c           | 2 +-
 vcs-svn/fast_export.c | 6 ++++--
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index 07e383257b4..3a7216f5313 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -1052,7 +1052,7 @@ int git_qsort_s(void *base, size_t nmemb, size_t size,
 
 #define QSORT_S(base, n, compar, ctx) do {			\
 	if (qsort_s((base), (n), sizeof(*(base)), compar, ctx))	\
-		die("BUG: qsort_s() failed");			\
+		BUG("qsort_s() failed");			\
 } while (0)
 
 #ifndef REG_STARTEND
diff --git a/pathspec.c b/pathspec.c
index a637a6d15c0..27cd6067860 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 	/* sanity checks, pathspec matchers assume these are sane */
 	if (item->nowildcard_len > item->len ||
 	    item->prefix         > item->len) {
-		die ("BUG: error initializing pathspec_item");
+		BUG("error initializing pathspec_item");
 	}
 }
 
diff --git a/submodule.c b/submodule.c
index 733db441714..c282fa8fe51 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2043,7 +2043,7 @@ const char *get_superproject_working_tree(void)
 
 		if (super_sub_len > cwd_len ||
 		    strcmp(&cwd[cwd_len - super_sub_len], super_sub))
-			die (_("BUG: returned path string doesn't match cwd?"));
+			BUG("returned path string doesn't match cwd?");
 
 		super_wt = xstrdup(cwd);
 		super_wt[cwd_len - super_sub_len] = '\0';
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 3fd047a8b82..b5b8913cb0f 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -320,7 +320,8 @@ const char *fast_export_read_path(const char *path, uint32_t *mode_out)
 	err = fast_export_ls(path, mode_out, &buf);
 	if (err) {
 		if (errno != ENOENT)
-			die_errno("BUG: unexpected fast_export_ls error");
+			BUG("unexpected fast_export_ls error: %s",
+			    strerror(errno));
 		/* Treat missing paths as directories. */
 		*mode_out = S_IFDIR;
 		return NULL;
@@ -338,7 +339,8 @@ void fast_export_copy(uint32_t revision, const char *src, const char *dst)
 	err = fast_export_ls_rev(revision, src, &mode, &data);
 	if (err) {
 		if (errno != ENOENT)
-			die_errno("BUG: unexpected fast_export_ls_rev error");
+			BUG("unexpected fast_export_ls_rev error: %s",
+			    strerror(errno));
 		fast_export_delete(dst);
 		return;
 	}
-- 
2.17.0.windows.1.36.gdf4ca5fb72a

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/6] Convert remaining die*(BUG) messages
  2018-04-29 22:19 ` [PATCH 6/6] Convert remaining die*(BUG) messages Johannes Schindelin
@ 2018-04-30  2:53   ` Eric Sunshine
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Sunshine @ 2018-04-30  2:53 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git List, Junio C Hamano, Jeff King

On Sun, Apr 29, 2018 at 6:19 PM, Johannes Schindelin
<johannes.schindelin@gmx.de> wrote:
> These were not caught by the previous commit, as they did not match the
> regular expression.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> diff --git a/submodule.c b/submodule.c
> @@ -2043,7 +2043,7 @@ const char *get_superproject_working_tree(void)
>                 if (super_sub_len > cwd_len ||
>                     strcmp(&cwd[cwd_len - super_sub_len], super_sub))
> -                       die (_("BUG: returned path string doesn't match cwd?"));
> +                       BUG("returned path string doesn't match cwd?");

This message used to be localizable but no longer is, which makes
sense since it's not intended as a user-facing error message but
rather is meant for Git developers. Good.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-04-29 22:17 ` [PATCH 2/6] t1406: prepare for the refs code to fail with BUG() Johannes Schindelin
@ 2018-04-30 19:32   ` Johannes Sixt
  2018-05-01 11:04     ` Johannes Schindelin
  2018-05-01 11:26   ` Duy Nguyen
  1 sibling, 1 reply; 15+ messages in thread
From: Johannes Sixt @ 2018-04-30 19:32 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git, Junio C Hamano, Jeff King

Am 30.04.2018 um 00:17 schrieb Johannes Schindelin:
> t1406 specifically verifies that certain code paths fail with a BUG: ...
> message.
> 
> In the upcoming commit, we will convert that message to be generated via
> BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
> regular exit code.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>   t/t1406-submodule-ref-store.sh | 15 +++++++++------
>   1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh
> index e093782cc37..0ea3457cae3 100755
> --- a/t/t1406-submodule-ref-store.sh
> +++ b/t/t1406-submodule-ref-store.sh
> @@ -16,7 +16,7 @@ test_expect_success 'setup' '
>   '
>   
>   test_expect_success 'pack_refs() not allowed' '
> -	test_must_fail $RUN pack-refs 3
> +	test_must_fail ok=sigabrt $RUN pack-refs 3
>   '
>   
>   test_expect_success 'peel_ref(new-tag)' '
> @@ -27,15 +27,18 @@ test_expect_success 'peel_ref(new-tag)' '
>   '
>   
>   test_expect_success 'create_symref() not allowed' '
> -	test_must_fail $RUN create-symref FOO refs/heads/master nothing
> +	test_must_fail ok=sigabrt \
> +		$RUN create-symref FOO refs/heads/master nothing
>   '
>   
>   test_expect_success 'delete_refs() not allowed' '
> -	test_must_fail $RUN delete-refs 0 nothing FOO refs/tags/new-tag
> +	test_must_fail ok=sigabrt \
> +		$RUN delete-refs 0 nothing FOO refs/tags/new-tag
>   '
>   
>   test_expect_success 'rename_refs() not allowed' '
> -	test_must_fail $RUN rename-ref refs/heads/master refs/heads/new-master
> +	test_must_fail ok=sigabrt \
> +		$RUN rename-ref refs/heads/master refs/heads/new-master
>   '
>   
>   test_expect_success 'for_each_ref(refs/heads/)' '
> @@ -91,11 +94,11 @@ test_expect_success 'reflog_exists(HEAD)' '
>   '
>   
>   test_expect_success 'delete_reflog() not allowed' '
> -	test_must_fail $RUN delete-reflog HEAD
> +	test_must_fail ok=sigabrt $RUN delete-reflog HEAD
>   '
>   
>   test_expect_success 'create-reflog() not allowed' '
> -	test_must_fail $RUN create-reflog HEAD 1
> +	test_must_fail ok=sigabrt $RUN create-reflog HEAD 1
>   '

I can't quite follow the rationale for this change. A 'BUG' error exit 
must never be reached, otherwise it is a bug in the program by 
definition. It cannot be OK that SIGABRT is a valid result from Git.

If SIGABRT occurs as a result of BUG(), and we know that this happens 
for certain cases, it means we have an unfixed bug. Should then not run 
these cases under test_expect_failure instead of test_expect_success to 
identify them as known bugs?

Confused.

-- Hannes

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-04-30 19:32   ` Johannes Sixt
@ 2018-05-01 11:04     ` Johannes Schindelin
  2018-05-01 11:22       ` Duy Nguyen
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Schindelin @ 2018-05-01 11:04 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git, Junio C Hamano, Jeff King

Hi Hannes,

On Mon, 30 Apr 2018, Johannes Sixt wrote:

> Am 30.04.2018 um 00:17 schrieb Johannes Schindelin:
> > t1406 specifically verifies that certain code paths fail with a BUG: ...
> > message.
> > 
> > In the upcoming commit, we will convert that message to be generated via
> > BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
> > regular exit code.
> >
> > [...]
> >
> >   test_expect_success 'create-reflog() not allowed' '
> > -	test_must_fail $RUN create-reflog HEAD 1
> > +	test_must_fail ok=sigabrt $RUN create-reflog HEAD 1
> >   '
> 
> I can't quite follow the rationale for this change. A 'BUG' error exit must
> never be reached, otherwise it is a bug in the program by definition. It
> cannot be OK that SIGABRT is a valid result from Git.

I thought so at first, too. However, what these test cases run is not Git
itself. Instead, they run a t/helper/ command *specifically* designed to
hit the BUG code path, probably to ensure that bugs in future code will
actually not be silently ignored, but do exit with an error.

> If SIGABRT occurs as a result of BUG(), and we know that this happens for
> certain cases, it means we have an unfixed bug.

Not in this case: The code in question is in
https://github.com/git/git/blob/v2.17.0/t/helper/test-ref-store.c#L190-L201
and it is called in a way that fails to have the required flags for the
operation. This would normally indicate a bug, but in this case, that is
exactly what the regression test tries to trigger: we *want* such a bug to
cause a failure.

I'll do my best to clarify that in the commit message.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-05-01 11:04     ` Johannes Schindelin
@ 2018-05-01 11:22       ` Duy Nguyen
  0 siblings, 0 replies; 15+ messages in thread
From: Duy Nguyen @ 2018-05-01 11:22 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Sixt, Git Mailing List, Junio C Hamano, Jeff King

On Tue, May 1, 2018 at 1:04 PM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>> If SIGABRT occurs as a result of BUG(), and we know that this happens for
>> certain cases, it means we have an unfixed bug.
>
> Not in this case: The code in question is in
> https://github.com/git/git/blob/v2.17.0/t/helper/test-ref-store.c#L190-L201
> and it is called in a way that fails to have the required flags for the
> operation.

To elaborate, in this particular case, developers are not supposed to
call calling create_reflog() on a submodule ref store because the
store's implementation does not support it (yet). So it's definitely
BUG() to catch devs from doing so. But due to the multiple layer
abstractions, we also need to verify that ref code will bug out in
this case :P

> This would normally indicate a bug, but in this case, that is
> exactly what the regression test tries to trigger: we *want* such a bug to
> cause a failure.
-- 
Duy

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-04-29 22:17 ` [PATCH 2/6] t1406: prepare for the refs code to fail with BUG() Johannes Schindelin
  2018-04-30 19:32   ` Johannes Sixt
@ 2018-05-01 11:26   ` Duy Nguyen
  2018-05-02  3:40     ` Junio C Hamano
  1 sibling, 1 reply; 15+ messages in thread
From: Duy Nguyen @ 2018-05-01 11:26 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git Mailing List, Junio C Hamano, Jeff King

On Mon, Apr 30, 2018 at 12:17 AM, Johannes Schindelin
<johannes.schindelin@gmx.de> wrote:
> t1406 specifically verifies that certain code paths fail with a BUG: ...
> message.
>
> In the upcoming commit, we will convert that message to be generated via
> BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
> regular exit code.

On the other hand, SIGABRT on linux creates core dumps. And on some
setup (like mine) core dumps may be redirected to some central place
via /proc/sys/kernel/core_pattern. I think systemd does it too but I
didn't check.

This moving to SIGABRT when we know it _will_ happen when running the
test suite will accumulate core dumps over time and not cleaned up by
the test suite. Maybe keeping die("BUG: here is a good compromise.
-- 
Duy

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-05-01 11:26   ` Duy Nguyen
@ 2018-05-02  3:40     ` Junio C Hamano
  2018-05-02  7:41       ` Johannes Schindelin
  0 siblings, 1 reply; 15+ messages in thread
From: Junio C Hamano @ 2018-05-02  3:40 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Johannes Schindelin, Git Mailing List, Jeff King

Duy Nguyen <pclouds@gmail.com> writes:

> On Mon, Apr 30, 2018 at 12:17 AM, Johannes Schindelin
> <johannes.schindelin@gmx.de> wrote:
>> t1406 specifically verifies that certain code paths fail with a BUG: ...
>> message.
>>
>> In the upcoming commit, we will convert that message to be generated via
>> BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
>> regular exit code.
>
> On the other hand, SIGABRT on linux creates core dumps. And on some
> setup (like mine) core dumps may be redirected to some central place
> via /proc/sys/kernel/core_pattern. I think systemd does it too but I
> didn't check.
>
> This moving to SIGABRT when we know it _will_ happen when running the
> test suite will accumulate core dumps over time and not cleaned up by
> the test suite. Maybe keeping die("BUG: here is a good compromise.

I do not think it is.  At regular runtime, we _do_ want Git to dump
core if it triggers BUG() condition, whose point is to mark
conditions that should never happen.

As discussed in this thread, tests that use t/helper/ executables
that try to trickle BUG() codepath to ensure that these "should
never happen" conditions are caught do need to deal with it.  If
dumping core is undesirable, tweaking BUG() implementation so that
it becomes die("BUG: ...") *ONLY* when the caller knows what it is
doing (e.g. running t/helper/ commands) is probably a good idea.
Perhaps GIT_TEST_OPTS can gain one feature "--bug-no-abort" and set
an environment variable so that implementation of BUG() can notice,
or something.

When we are testing normal parts of Git outside t/helper/, we never
want to hit BUG().  Aborting and dumping core when that happens is
an desirable outcome.  From that point of view, the idea in 1/6 of
this patch series to annotate test_must_fail and say "we know this
one is going to hit BUG()" is a sound one.  The implementation in
1/6 to treat SIGABRT as an acceptable failure needs to be replaced
to instead use the above mechanism you would use to tell BUG() not
to abort but die with message to arrange that to happen before
running the git command (most likely something from t/helper/) under
test_must_fail ok=sigabrt; and then those who regularly break their
Git being tested (read: us devs) and hit BUG() could instead set the
environment variable (i.e. internal implementation detail) manually
in their environment to turn these BUG()s into die("BUG:...)s while
testing their early mistakes if they do not want core (of course,
you could just do "ulimit -c", and that may be simpler solution of
your "testing Git contaminates central core depot" issue).







^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-05-02  3:40     ` Junio C Hamano
@ 2018-05-02  7:41       ` Johannes Schindelin
  2018-05-02 10:41         ` Junio C Hamano
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Schindelin @ 2018-05-02  7:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List, Jeff King

Hi,

On Wed, 2 May 2018, Junio C Hamano wrote:

> Duy Nguyen <pclouds@gmail.com> writes:
> 
> > On Mon, Apr 30, 2018 at 12:17 AM, Johannes Schindelin
> > <johannes.schindelin@gmx.de> wrote:
> >> t1406 specifically verifies that certain code paths fail with a BUG: ...
> >> message.
> >>
> >> In the upcoming commit, we will convert that message to be generated via
> >> BUG() instead of die("BUG: ..."), which implies SIGABRT instead of a
> >> regular exit code.
> >
> > On the other hand, SIGABRT on linux creates core dumps. And on some
> > setup (like mine) core dumps may be redirected to some central place
> > via /proc/sys/kernel/core_pattern. I think systemd does it too but I
> > didn't check.
> >
> > This moving to SIGABRT when we know it _will_ happen when running the
> > test suite will accumulate core dumps over time and not cleaned up by
> > the test suite. Maybe keeping die("BUG: here is a good compromise.
> 
> I do not think it is.  At regular runtime, we _do_ want Git to dump
> core if it triggers BUG() condition, whose point is to mark
> conditions that should never happen.

Indeed.

> As discussed in this thread, tests that use t/helper/ executables
> that try to trickle BUG() codepath to ensure that these "should
> never happen" conditions are caught do need to deal with it.  If
> dumping core is undesirable, tweaking BUG() implementation so that
> it becomes die("BUG: ...") *ONLY* when the caller knows what it is
> doing (e.g. running t/helper/ commands) is probably a good idea.
> Perhaps GIT_TEST_OPTS can gain one feature "--bug-no-abort" and set
> an environment variable so that implementation of BUG() can notice,
> or something.

I think we can do even better than that. t/helper/*.c could set a global
variable that no other code is supposed to set, to trigger an alternative
to SIGABRT. Something like

-- snip --
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 87066ced62a..5176f9f20ae 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -47,7 +47,9 @@ static struct test_cmd cmds[] = {
 int cmd_main(int argc, const char **argv)
 {
 	int i;
+	extern int BUG_exit_code;
 
+	BUG_exit_code = 99;
 	if (argc < 2)
 		die("I need a test name!");
 
diff --git a/usage.c b/usage.c
index cdd534c9dfc..9c84dccfa97 100644
--- a/usage.c
+++ b/usage.c
@@ -210,6 +210,9 @@ void warning(const char *warn, ...)
 	va_end(params);
 }
 
+/* Only set this, ever, from t/helper/, when verifying that bugs are
caught. */
+int BUG_exit_code;
+
 static NORETURN void BUG_vfl(const char *file, int line, const char *fmt,
va_list params)
 {
 	char prefix[256];
@@ -221,6 +224,8 @@ static NORETURN void BUG_vfl(const char *file, int
line, const char *fmt, va_lis
 		snprintf(prefix, sizeof(prefix), "BUG: ");
 
 	vreportf(prefix, fmt, params);
+	if (BUG_exit_code)
+		exit(BUG_exit_code);
 	abort();
 }
 
-- snap --

I'll try to find some time to play with this.

Ciao,
Dscho
> 
> When we are testing normal parts of Git outside t/helper/, we never
> want to hit BUG().  Aborting and dumping core when that happens is
> an desirable outcome.  From that point of view, the idea in 1/6 of
> this patch series to annotate test_must_fail and say "we know this
> one is going to hit BUG()" is a sound one.  The implementation in
> 1/6 to treat SIGABRT as an acceptable failure needs to be replaced
> to instead use the above mechanism you would use to tell BUG() not
> to abort but die with message to arrange that to happen before
> running the git command (most likely something from t/helper/) under
> test_must_fail ok=sigabrt; and then those who regularly break their
> Git being tested (read: us devs) and hit BUG() could instead set the
> environment variable (i.e. internal implementation detail) manually
> in their environment to turn these BUG()s into die("BUG:...)s while
> testing their early mistakes if they do not want core (of course,
> you could just do "ulimit -c", and that may be simpler solution of
> your "testing Git contaminates central core depot" issue).
> 
> 
> 
> 
> 
> 
> 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/6] t1406: prepare for the refs code to fail with BUG()
  2018-05-02  7:41       ` Johannes Schindelin
@ 2018-05-02 10:41         ` Junio C Hamano
  0 siblings, 0 replies; 15+ messages in thread
From: Junio C Hamano @ 2018-05-02 10:41 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Duy Nguyen, Git Mailing List, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> As discussed in this thread, tests that use t/helper/ executables
>> that try to trickle BUG() codepath to ensure that these "should
>> never happen" conditions are caught do need to deal with it.  If
>> dumping core is undesirable, tweaking BUG() implementation so that
>> it becomes die("BUG: ...") *ONLY* when the caller knows what it is
>> doing (e.g. running t/helper/ commands) is probably a good idea.
>> Perhaps GIT_TEST_OPTS can gain one feature "--bug-no-abort" and set
>> an environment variable so that implementation of BUG() can notice,
>> or something.
>
> I think we can do even better than that. t/helper/*.c could set a global
> variable that no other code is supposed to set, to trigger an alternative
> to SIGABRT. Something like

Yes, I agree with that solution for t/helper/ part.

But we also need to arrange a way for things outside t/helper/ to
set the BUG_exit_code at runtime, so that those like Duy who causes
BUG() to trigger in some "git cmd" under development when running
tests for himself, where he does not want his BUG() to dump core and
contaminate global core storage.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-05-02 10:41 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-29 22:17 [PATCH 0/6] Finish the conversion from die("BUG: ...") to BUG() Johannes Schindelin
2018-04-29 22:17 ` [PATCH 1/6] test_must_fail: support ok=sigabrt Johannes Schindelin
2018-04-29 22:17 ` [PATCH 2/6] t1406: prepare for the refs code to fail with BUG() Johannes Schindelin
2018-04-30 19:32   ` Johannes Sixt
2018-05-01 11:04     ` Johannes Schindelin
2018-05-01 11:22       ` Duy Nguyen
2018-05-01 11:26   ` Duy Nguyen
2018-05-02  3:40     ` Junio C Hamano
2018-05-02  7:41       ` Johannes Schindelin
2018-05-02 10:41         ` Junio C Hamano
2018-04-29 22:18 ` [PATCH 3/6] refs/*: report bugs using the BUG() macro Johannes Schindelin
2018-04-29 22:18 ` [PATCH 4/6] run-command: use BUG() to report bugs, not die() Johannes Schindelin
2018-04-29 22:19 ` [PATCH 5/6] Replace all die("BUG: ...") calls by BUG() ones Johannes Schindelin
2018-04-29 22:19 ` [PATCH 6/6] Convert remaining die*(BUG) messages Johannes Schindelin
2018-04-30  2:53   ` Eric Sunshine

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).