{"thread":{"id":"11054","subject":"[PATCH] receive-pack: allow deletion of corrupt refs","startedAt":"2007-11-29T01:02:53Z","lastAt":"2007-11-29T03:55:39Z","messageCount":3,"participants":["Johannes Schindelin","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"61345","messageId":"Pine.LNX.4.64.0711290101420.27959@racer.site","threadId":"11054","inReplyTo":null,"subject":"[PATCH] receive-pack: allow deletion of corrupt refs","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-11-29T01:02:53Z","receivedAt":"2007-11-29T01:02:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nOccasionally, in some setups (*cough* forks on repo.or.cz *cough*) some\nrefs go stale, e.g. when the forkee rebased and lost some objects needed\nby the fork.  The quick & dirty way to deal with those refs is to delete\nthem and push them again.\n\nHowever, git-push first would first fetch the current commit name for the\nref, would receive a null sha1 since the ref does not point to a valid\nobject, then tell receive-pack that it should delete the ref with this\ncommit name.  delete_ref() would be subsequently be called, and check that\nresolve_ref() (which does _not_ check for validity of the object) returns\nthe same commit name.  Which would fail.\n\nThe proper fix is to avoid corrupting repositories, but in the meantime\nthis is a good fix in any case.\n\nIncidentally, some instances of \"cd ..\" in the test cases were fixed, so\nthat subsequent test cases run in t/trash/ irrespective of the outcome of\nthe previous test cases.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tI was bitten one time too many by a rebased git/mingw.git/.\n\n\tWill work on the \"proper fix\" I hinted at.\n\n receive-pack.c        |    4 ++++\n t/t5516-fetch-push.sh |   41 ++++++++++++++++++++++++++---------------\n 2 files changed, 30 insertions(+), 15 deletions(-)\n\ndiff --git a/receive-pack.c b/receive-pack.c\nindex ed44b89..fba4cf8 100644\n--- a/receive-pack.c\n+++ b/receive-pack.c\n@@ -200,6 +200,10 @@ static const char *update(struct command *cmd)\n \t}\n \n \tif (is_null_sha1(new_sha1)) {\n+\t\tif (!parse_object(old_sha1)) {\n+\t\t\twarning (\"Allowing deletion of corrupt ref.\");\n+\t\t\told_sha1 = NULL;\n+\t\t}\n \t\tif (delete_ref(name, old_sha1)) {\n \t\t\terror(\"failed to delete %s\", name);\n \t\t\treturn \"failed to delete\";\ndiff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh\nindex fd5f284..9d2dc33 100755\n--- a/t/t5516-fetch-push.sh\n+++ b/t/t5516-fetch-push.sh\n@@ -274,9 +274,8 @@ test_expect_success 'push with HEAD nonexisting at remote' '\n test_expect_success 'push with dry-run' '\n \n \tmk_test heads/master &&\n-\tcd testrepo &&\n-\told_commit=$(git show-ref -s --verify refs/heads/master) &&\n-\tcd .. &&\n+\t(cd testrepo &&\n+\t old_commit=$(git show-ref -s --verify refs/heads/master)) &&\n \tgit push --dry-run testrepo &&\n \tcheck_push_result $old_commit heads/master\n '\n@@ -284,28 +283,40 @@ test_expect_success 'push with dry-run' '\n test_expect_success 'push updates local refs' '\n \n \trm -rf parent child &&\n-\tmkdir parent && cd parent && git init &&\n-\t\techo one >foo && git add foo && git commit -m one &&\n-\tcd .. &&\n-\tgit clone parent child && cd child &&\n+\tmkdir parent &&\n+\t(cd parent && git init &&\n+\t\techo one >foo && git add foo && git commit -m one) &&\n+\tgit clone parent child &&\n+\t(cd child &&\n \t\techo two >foo && git commit -a -m two &&\n \t\tgit push &&\n-\ttest $(git rev-parse master) = $(git rev-parse remotes/origin/master)\n+\ttest $(git rev-parse master) = $(git rev-parse remotes/origin/master))\n \n '\n \n test_expect_success 'push does not update local refs on failure' '\n \n \trm -rf parent child &&\n-\tmkdir parent && cd parent && git init &&\n+\tmkdir parent &&\n+\t(cd parent && git init &&\n \t\techo one >foo && git add foo && git commit -m one &&\n \t\techo exit 1 >.git/hooks/pre-receive &&\n-\t\tchmod +x .git/hooks/pre-receive &&\n-\tcd .. &&\n-\tgit clone parent child && cd child &&\n-\t\techo two >foo && git commit -a -m two || exit 1\n-\t\tgit push && exit 1\n-\ttest $(git rev-parse master) != $(git rev-parse remotes/origin/master)\n+\t\tchmod +x .git/hooks/pre-receive) &&\n+\tgit clone parent child &&\n+\t(cd child &&\n+\t\techo two >foo && git commit -a -m two &&\n+\t\t! git push &&\n+\t\ttest $(git rev-parse master) != \\\n+\t\t\t$(git rev-parse remotes/origin/master))\n+\n+'\n+\n+test_expect_success 'allow deleting an invalid remote ref' '\n+\n+\tpwd &&\n+\trm -f testrepo/.git/objects/??/* &&\n+\tgit push testrepo :refs/heads/master &&\n+\t(cd testrepo && ! git rev-parse --verify refs/heads/master)\n \n '\n \n-- \n1.5.3.6.2065.gd47ac\n"},{"id":"61347","messageId":"Pine.LNX.4.64.0711290103400.27959@racer.site","threadId":"11054","inReplyTo":"Pine.LNX.4.64.0711290101420.27959@racer.site","subject":"Re: [PATCH] receive-pack: allow deletion of corrupt refs","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-11-29T01:04:26Z","receivedAt":"2007-11-29T01:04:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 29 Nov 2007, Johannes Schindelin wrote:\n\n> Incidentally, some instances of \"cd ..\" in the test cases were fixed, so \n> that subsequent test cases run in t/trash/ irrespective of the outcome \n> of the previous test cases.\n\nJust to clarify: I was quite surprised that my test case did not succeed, \nand eventually found out that $(pwd) was t/trash/child/child after the \nlast test.\n\nCiao,\nDscho\n"},{"id":"61361","messageId":"20071129035539.GT1001@machine.or.cz","threadId":"11054","inReplyTo":"Pine.LNX.4.64.0711290101420.27959@racer.site","subject":"Re: [PATCH] receive-pack: allow deletion of corrupt refs","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-11-29T03:55:39Z","receivedAt":"2007-11-29T03:55:39Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"  Hi,\n\nOn Thu, Nov 29, 2007 at 01:02:53AM +0000, Johannes Schindelin wrote:\n> Occasionally, in some setups (*cough* forks on repo.or.cz *cough*) some\n> refs go stale, e.g. when the forkee rebased and lost some objects needed\n> by the fork.  The quick & dirty way to deal with those refs is to delete\n> them and push them again.\n\n  repo.or.cz now has this patch. I'm also repacking the kernel\nrepository which is in a pretty awful state, I'm hoping that will fix\nsome of the heavy performance problems repo.or.cz is hitting currently.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nWe don't know who it was that discovered water, but we're pretty sure\nthat it wasn't a fish.\t\t-- Marshall McLuhan\n"}]}