Re: [PATCH] replace: fix replacing object with itself

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] replace: fix replacing object with itself

From: Junio C Hamano <hidden>
Date: 2016-06-15 23:02:57

Manzur Mukhitdinov [off-list ref] writes:
When object is replaced with itself git shows unhelpful messages like(git log):
    "fatal: replace depth too high for object <SHA1>"

Prevents user from replacing object with itself(with test for checking
this case).

Signed-off-by: Manzur Mukhitdinov <redacted>
---
The patch is not wrong per-se, but I wonder how useful this "do not
replace itself but all other forms of loops are not checked at all"
would be in practice.  If your user did this:

	git replace A B ;# pretend as if what is in B is in A
        git replace B C ;# pretend as if what is in C is in B
        git replace C A ;# pretend as if we have loop
	git log C

she would not be helped with this patch at all, no?

We have the "replace depth" thing, which is a poor-man's substitute
for loop detection, primarily because we do not want to incur high
cost of loop detection at runtime.  Shouldn't we be doing at least
the same amount of loop-avoidance check, if we really want to avoid
triggering the "replace depth" check at runtime?
quoted hunk
 builtin/replace.c  |  8 +++-----
 t/t6050-replace.sh | 11 +++++++++--
 2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/builtin/replace.c b/builtin/replace.c
index 294b61b..628377a 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -157,6 +157,9 @@ static int replace_object_sha1(const char *object_ref,
 	char ref[PATH_MAX];
 	struct ref_lock *lock;
 
+	if (!hashcmp(object, repl))
+		return error("new object is the same as the old one: '%s'", sha1_to_hex(object));
+
 	obj_type = sha1_object_info(object, NULL);
 	repl_type = sha1_object_info(repl, NULL);
 	if (!force && obj_type != repl_type)
@@ -295,9 +298,6 @@ static int edit_and_replace(const char *object_ref, int force, int raw)
 
 	free(tmpfile);
 
-	if (!hashcmp(old, new))
-		return error("new object is the same as the old one: '%s'", sha1_to_hex(old));
-
 	return replace_object_sha1(object_ref, old, "replacement", new, force);
 }
 
@@ -406,8 +406,6 @@ static int create_graft(int argc, const char **argv, int force)
 
 	strbuf_release(&buf);
 
-	if (!hashcmp(old, new))
-		return error("new commit is the same as the old one: '%s'", sha1_to_hex(old));
 
 	return replace_object_sha1(old_ref, old, "replacement", new, force);
 }
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 4d5a25e..5f96374 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -369,9 +369,8 @@ test_expect_success '--edit with and without already replaced object' '
 	git cat-file commit "$PARA3" | grep "A fake Thor"
 '
 
-test_expect_success '--edit and change nothing or command failed' '
+test_expect_success '--edit with failed editor' '
 	git replace -d "$PARA3" &&
-	test_must_fail env GIT_EDITOR=true git replace --edit "$PARA3" &&
 	test_must_fail env GIT_EDITOR="./fakeeditor;false" git replace --edit "$PARA3" &&
 	GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&
 	git replace -l | grep "$PARA3" &&
@@ -440,4 +439,12 @@ test_expect_success GPG '--graft on a commit with a mergetag' '
 	git replace -d $HASH10
 '
 
+test_expect_success 'replacing object with itself must fail' '
+    test_must_fail git replace $HASH1 $HASH1 &&
+    HASH8=$(git rev-parse --verify HEAD) &&
+    test_must_fail git replace HEAD $HASH8 &&
+    test_must_fail git replace --graft HEAD HEAD^ &&
+    test_must_fail env GIT_EDITOR=true git replace --edit HEAD
+'
+
 test_done

Re: [PATCH] replace: fix replacing object with itself

From: Christian Couder <hidden>
Date: 2016-06-15 23:02:57

[Sorry to resend this. I am really bad at making gmail on my Android
smartphone send plain text emails.]

On Fri, Nov 14, 2014 at 11:45 PM, Junio C Hamano [off-list ref] wrote:
Manzur Mukhitdinov [off-list ref] writes:
quoted
When object is replaced with itself git shows unhelpful messages like(git log):
    "fatal: replace depth too high for object <SHA1>"

Prevents user from replacing object with itself(with test for checking
this case).

Signed-off-by: Manzur Mukhitdinov <redacted>
---
The patch is not wrong per-se, but I wonder how useful this "do not
replace itself but all other forms of loops are not checked at all"
would be in practice.  If your user did this:

        git replace A B ;# pretend as if what is in B is in A
        git replace B C ;# pretend as if what is in C is in B
        git replace C A ;# pretend as if we have loop
        git log C

she would not be helped with this patch at all, no?
Yeah, but such loops are much less likely mistakes and are more
difficult to detect, so I think this patch is at least a good first
step.
We have the "replace depth" thing, which is a poor-man's substitute
for loop detection, primarily because we do not want to incur high
cost of loop detection at runtime.  Shouldn't we be doing at least
the same amount of loop-avoidance check, if we really want to avoid
triggering the "replace depth" check at runtime?
We could check at replace ref creation time, but what if the user
already has a ref that replaces A using B, and then a fetch adds a ref
that replaces B using A?

Maybe we should accept that we have to rely on the runtime replace
depth anyway, and improve its output first.

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