Re: [PATCH v2 2/4] fetch: refactor `s_update_ref` to use common exit path

2 messages, 2 authors, 2021-01-11 · open the first message on its own page

Re: [PATCH v2 2/4] fetch: refactor `s_update_ref` to use common exit path

From: Junio C Hamano <hidden>
Date: 2021-01-08 23:51:03

Patrick Steinhardt [off-list ref] writes:
quoted hunk
@@ -598,30 +598,33 @@ static int s_update_ref(const char *action,
 	msg = xstrfmt("%s: %s", rla, action);
 
 	transaction = ref_transaction_begin(&err);
-	if (!transaction ||
-	    ref_transaction_update(transaction, ref->name,
-				   &ref->new_oid,
-				   check_old ? &ref->old_oid : NULL,
-				   0, msg, &err))
-		goto fail;
+	if (!transaction) {
+		ret = STORE_REF_ERROR_OTHER;
+		goto out;
+	}
+
+	ret = ref_transaction_update(transaction, ref->name, &ref->new_oid,
+				     check_old ? &ref->old_oid : NULL,
+				     0, msg, &err);
+	if (ret) {
+		ret = STORE_REF_ERROR_OTHER;
+		goto out;
+	}
The above certainly got cleaner thanks to Christian's suggestion,
but I wonder why

	transaction = ref_transaction_begin(&err);
	if (!transaction ||
	    ref_transaction_update(transaction, ref->name,
				   &ref->new_oid,
				   check_old ? &ref->old_oid : NULL,
				   0, msg, &err)) {
		ret = STORE_REF_ERROR_OTHER;
		goto out;
	}

shouldn't be sufficient.
 	ret = ref_transaction_commit(transaction, &err);
 	if (ret) {
-		df_conflict = (ret == TRANSACTION_NAME_CONFLICT);
-		goto fail;
+		ret = (ret == TRANSACTION_NAME_CONFLICT) ? STORE_REF_ERROR_DF_CONFLICT
+							 : STORE_REF_ERROR_OTHER;
+		goto out;
 	}

+out:
 	ref_transaction_free(transaction);
It is a bit funny to see a goto that jumps to the label without
having anything else in between, but we know we will be adding more
code just before the "out:" label, so it is a good preliminary
preparation.

I think a variant that is much easier to follow would be to write
like this instead:

	switch (ref_transaction_commit(transaction, &err)) {
        case 0: /* happy */
		break;
	case TRANSACTION_NAME_CONFLICT:
		ret = STORE_REF_ERROR_DF_CONFLICT;
		goto out;
	default:
		ret = STORE_REF_ERROR_OTHER;
		goto out;
	}
+	if (ret)
+		error("%s", err.buf);
OK.
 	strbuf_release(&err);
 	free(msg);
-	return 0;
-fail:
-	ref_transaction_free(transaction);
-	error("%s", err.buf);
-	strbuf_release(&err);
-	free(msg);
-	return df_conflict ? STORE_REF_ERROR_DF_CONFLICT
-			   : STORE_REF_ERROR_OTHER;
+	return ret;
 }
 
 static int refcol_width = 10;
THanks.

Re: [PATCH v2 2/4] fetch: refactor `s_update_ref` to use common exit path

From: Patrick Steinhardt <hidden>
Date: 2021-01-11 10:29:53

On Fri, Jan 08, 2021 at 03:50:00PM -0800, Junio C Hamano wrote:
Patrick Steinhardt [off-list ref] writes:
[snip]
quoted
 	ret = ref_transaction_commit(transaction, &err);
 	if (ret) {
-		df_conflict = (ret == TRANSACTION_NAME_CONFLICT);
-		goto fail;
+		ret = (ret == TRANSACTION_NAME_CONFLICT) ? STORE_REF_ERROR_DF_CONFLICT
+							 : STORE_REF_ERROR_OTHER;
+		goto out;
 	}

+out:
 	ref_transaction_free(transaction);
It is a bit funny to see a goto that jumps to the label without
having anything else in between, but we know we will be adding more
code just before the "out:" label, so it is a good preliminary
preparation.

I think a variant that is much easier to follow would be to write
like this instead:

	switch (ref_transaction_commit(transaction, &err)) {
        case 0: /* happy */
		break;
	case TRANSACTION_NAME_CONFLICT:
		ret = STORE_REF_ERROR_DF_CONFLICT;
		goto out;
	default:
		ret = STORE_REF_ERROR_OTHER;
		goto out;
	}
Agreed, that is easier to read. Thanks!

Patrick
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help