From patchwork Tue Oct 12 14:30:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12552823 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7944C433F5 for ; Tue, 12 Oct 2021 14:30:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 99125610C7 for ; Tue, 12 Oct 2021 14:30:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237260AbhJLOc5 (ORCPT ); Tue, 12 Oct 2021 10:32:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237150AbhJLOc4 (ORCPT ); Tue, 12 Oct 2021 10:32:56 -0400 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6FD8C06161C for ; Tue, 12 Oct 2021 07:30:54 -0700 (PDT) Received: by mail-wr1-x42e.google.com with SMTP id e3so33928145wrc.11 for ; Tue, 12 Oct 2021 07:30:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SLujjciZZ2pT7WKD2jFZTNaF/vyzr1U9vbILgiSbAdY=; b=XaHSkj+4/c1f9JowODc4UhgGnk4Qzouq4hwXA3iR5P3MKA8d60vCkuPmO5y0yUR1Ua Xq7PuyUhUlOFY898N2XW6WULW7h02nXdZcBoUrjXiBGuqZSXmcTWkPklZG5T8dN4JiG0 Mxm912H3Y7KBers8C9qihQ8lrwxuCERBXzA9/mVNoVmTzXRK+TmsL7sXjN9Ze1R8iJdN 57cVmrfGaZEMS1NLeOA5TmChyfmcn/K0jnJLsYGLmoJHhRwWhiPDIsgDTk7HCvRIAGBf 3idocQ72INPbr4xZxCY4EVcFuiB4W/Ph3kJcsp1yhn+Z0HySjRZSTQA9Pds45H5Nyczf 6LcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SLujjciZZ2pT7WKD2jFZTNaF/vyzr1U9vbILgiSbAdY=; b=1OjXrQEPtoPio+Ez4URj10INAVtAAOWdcdbB0ysoVpxyViN0+m4lbd+L0+IHKVflda ayVs0LUUn60Ybvt4TaANlPrvCZ9zyseDUz8i3WBH8RNwimg9NgzH6bRYe0srL3ijGYEP vm5OUCu8fpJyAy7Jj4wYQNT48P9d9/yM9hNmnnsxLRSNtHS1FHC89G1pI9GjdCA/qz7R K/rV6l6E1FiBKSwcrQY7sVI0nhfv2vcpfVbBYQr4b/1dXy2aDzxLzRohDRbrx2IlVCzx 0GAZTCbxS1i1aFsE8BMPTDZggsF3oYP7vzq4Si30amfinOdM9YEQ0uvV1HvYWo88hCgb UBUg== X-Gm-Message-State: AOAM532aYg+iBJZp2uMlo88DdqyJF5iYwT1miSiv3ufnW7cZttCxK33I hSmh5dbsXbdTevimUDiXK9ZfcbhFdLmJ9g== X-Google-Smtp-Source: ABdhPJyQlwClzHmOklv5g9lC5/w7EpRAFwaq7wKvJ5t+dQfeH+6ReMJzrTHir/+1bGp84NvDXfBYxg== X-Received: by 2002:adf:a190:: with SMTP id u16mr32082100wru.114.1634049052982; Tue, 12 Oct 2021 07:30:52 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id l2sm3149791wmi.1.2021.10.12.07.30.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 07:30:52 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , David Turner , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= Subject: [PATCH v2 1/2] unwritable tests: assert exact error output Date: Tue, 12 Oct 2021 16:30:48 +0200 Message-Id: X-Mailer: git-send-email 2.33.0.1567.g7b23ce7ed9e In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In preparation for fixing a regression where we started emitting some of these error messages twice, let's assert what the output from "git commit" and friends is now in the case of permission errors. As noted in [1] using test_expect_failure to mark up a TODO test has some unexpected edge cases, e.g. we don't want to break --run=3 by skipping the "test_lazy_prereq" here. This pattern allows us to test just the test_cmp (and the "cat", which shouldn't fail) with the added "test_expect_failure", we'll flip that to a "test_expect_success" in the next commit. 1. https://lore.kernel.org/git/87tuhmk19c.fsf@evledraar.gmail.com/T/#u Signed-off-by: Ævar Arnfjörð Bjarmason --- t/t0004-unwritable.sh | 47 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh index 37d68ef03be..3627ce367c0 100755 --- a/t/t0004-unwritable.sh +++ b/t/t0004-unwritable.sh @@ -19,27 +19,66 @@ test_expect_success setup ' test_expect_success POSIXPERM,SANITY 'write-tree should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && chmod a-w .git/objects .git/objects/?? && - test_must_fail git write-tree + test_must_fail git write-tree 2>out.write-tree +' + +test_lazy_prereq WRITE_TREE_OUT 'test -e "$TRASH_DIRECTORY"/out.write-tree' +test_expect_success WRITE_TREE_OUT 'write-tree output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + fatal: git-write-tree: error building trees + EOF + test_cmp expect out.write-tree ' test_expect_success POSIXPERM,SANITY,!SANITIZE_LEAK 'commit should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && chmod a-w .git/objects .git/objects/?? && - test_must_fail git commit -m second + test_must_fail git commit -m second 2>out.commit +' + +test_lazy_prereq COMMIT_OUT 'test -e "$TRASH_DIRECTORY"/out.commit' +test_expect_failure COMMIT_OUT 'commit output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: Error building trees + EOF + test_cmp expect out.commit ' test_expect_success POSIXPERM,SANITY 'update-index should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && echo 6O >file && chmod a-w .git/objects .git/objects/?? && - test_must_fail git update-index file + test_must_fail git update-index file 2>out.update-index +' + +test_lazy_prereq UPDATE_INDEX_OUT 'test -e "$TRASH_DIRECTORY"/out.update-index' +test_expect_success UPDATE_INDEX_OUT 'update-index output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: file: failed to insert into database + fatal: Unable to process path file + EOF + test_cmp expect out.update-index ' test_expect_success POSIXPERM,SANITY 'add should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && echo b >file && chmod a-w .git/objects .git/objects/?? && - test_must_fail git add file + test_must_fail git add file 2>out.add +' + +test_lazy_prereq ADD_OUT 'test -e "$TRASH_DIRECTORY"/out.add' +test_expect_success ADD_OUT 'add output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: file: failed to insert into database + error: unable to index file '\''file'\'' + fatal: updating files failed + EOF + test_cmp expect out.add ' test_done From patchwork Tue Oct 12 14:30:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12552825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 212BBC433EF for ; Tue, 12 Oct 2021 14:31:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 09D4A6101D for ; Tue, 12 Oct 2021 14:31:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237304AbhJLOdA (ORCPT ); Tue, 12 Oct 2021 10:33:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237285AbhJLOc5 (ORCPT ); Tue, 12 Oct 2021 10:32:57 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C5ED8C06161C for ; Tue, 12 Oct 2021 07:30:55 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id e12so67587659wra.4 for ; Tue, 12 Oct 2021 07:30:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tIvcClGtL+BLliCpVP559eoCgxMjlmsE5VFLX95xufU=; b=CyDS2seH5zwvqN5G6d1xfac+J078MlgZ1bg28Wg/7aVbjKzLPqPPVxwle+1BS6ca5O QuDvIkkRtQFR3u3YsJsXe39rHo6MSrqVf9GOW5QcvAMny4xWYrStv3YQd71TqFYkw04b K4OlzHuE1axC439Me0Ag1bujogFilcDzsgzpeSFAm/ch0eNAvEVd1/pn4uNVCIDtRzPJ MhdFnJZNnqpt7GQlLpG0uy5pe4+8VOtdc1/cMKCVMSZHk2gQi6s9ZniEIl0fuQ09UvPH 5nfYyRTPqzClS8lL4XqB5EJEniIvVHi3XbcmP9iZEvx2MGRVqs/T71uinB+AzCD9daOh OcCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tIvcClGtL+BLliCpVP559eoCgxMjlmsE5VFLX95xufU=; b=KBjioDERp/a5exzU5b+kmH2YdD0tGF+oE1DI51IQG1MvXBli1A2fV4TtsT/GRIYBOE uHsCdQ14qsH2J0xUski74p50ijmYXuTf1v3EYRAfLew0etZ93Rf9FJnk2d7IDaYkU+k8 1MO8iiK43pIqf+ejE2lTgCz8ePIuEY3jm7MFjahVTtiAuTJYumC+Y7MQufH5UBNgAZmT 2iHU66QZEM5N6VWMHgrNkS1o3gStuhpwM5ckBWO+IjiznKMImRgE9JSSrUWUWIAWyq2j MEKXMPHZMseaHG8ImVEXSZtdbgYOoBixFMxVcGUYfyQ0kMtOQ00OOgRVX2HjnXoeXZSA IRkw== X-Gm-Message-State: AOAM53094CSbSR9ABks7nrFBaLS4W60NS8aRqZI+xx6lfNeiLrSUQ5Fq Cc+Lv4zxJHeCyRnSo751heG4jm4Y8WqybA== X-Google-Smtp-Source: ABdhPJzpp9Og41G8VVqLaeRvABnfhD5Cs9N8nNc6dF4fFnvrxFofoMqd8V6x9biB4o0pV6au87gprg== X-Received: by 2002:a5d:630b:: with SMTP id i11mr15121875wru.65.1634049054067; Tue, 12 Oct 2021 07:30:54 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id l2sm3149791wmi.1.2021.10.12.07.30.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Oct 2021 07:30:53 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , David Turner , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= Subject: [PATCH v2 2/2] commit: fix duplication regression in permission error output Date: Tue, 12 Oct 2021 16:30:49 +0200 Message-Id: X-Mailer: git-send-email 2.33.0.1567.g7b23ce7ed9e In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Fix a regression in the error output emitted when .git/objects can't be written to. Before 9c4d6c0297b (cache-tree: Write updated cache-tree after commit, 2014-07-13) we'd emit only one "insufficient permission" error, now we'll do so again. The cause is rather straightforward, we've got WRITE_TREE_SILENT for the use-case of wanting to prepare an index silently, quieting any permission etc. error output. Then when we attempt to update to that (possibly broken) index we'll run into the same errors again. But with 9c4d6c0297b the gap between the cache-tree API and the object store wasn't closed in terms of asking write_object_file() to be silent. I.e. post-9c4d6c0297b the first call is to prepare_index(), and after that we'll call prepare_to_commit(). We only want verbose error output from the latter. So let's add and use that facility with a corresponding HASH_SILENT flag, its only user is cache-tree.c's update_one(), which will set it if its "WRITE_TREE_SILENT" flag is set. Signed-off-by: Ævar Arnfjörð Bjarmason --- cache-tree.c | 5 +++-- cache.h | 1 + object-file.c | 20 ++++++++++++-------- object-store.h | 10 ++++++++-- t/t0004-unwritable.sh | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/cache-tree.c b/cache-tree.c index 90919f9e345..f21bfc631c6 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -440,8 +440,9 @@ static int update_one(struct cache_tree *it, } else if (dryrun) { hash_object_file(the_hash_algo, buffer.buf, buffer.len, tree_type, &it->oid); - } else if (write_object_file(buffer.buf, buffer.len, tree_type, - &it->oid)) { + } else if (write_object_file_flags(buffer.buf, buffer.len, tree_type, + &it->oid, flags & WRITE_TREE_SILENT + ? HASH_SILENT : 0)) { strbuf_release(&buffer); return -1; } diff --git a/cache.h b/cache.h index d092820c943..dc58bfa48a0 100644 --- a/cache.h +++ b/cache.h @@ -887,6 +887,7 @@ int ie_modified(struct index_state *, const struct cache_entry *, struct stat *, #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 #define HASH_RENORMALIZE 4 +#define HASH_SILENT 8 int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags); diff --git a/object-file.c b/object-file.c index 112d9b4badc..8fd67b07e45 100644 --- a/object-file.c +++ b/object-file.c @@ -1873,7 +1873,7 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) static int write_loose_object(const struct object_id *oid, char *hdr, int hdrlen, const void *buf, unsigned long len, - time_t mtime) + time_t mtime, unsigned flags) { int fd, ret; unsigned char compressed[4096]; @@ -1887,7 +1887,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr, fd = create_tmpfile(&tmp_file, filename.buf); if (fd < 0) { - if (errno == EACCES) + if (flags & HASH_SILENT) + return -1; + else if (errno == EACCES) return error(_("insufficient permission for adding an object to repository database %s"), get_object_directory()); else return error_errno(_("unable to create temporary file")); @@ -1937,7 +1939,8 @@ static int write_loose_object(const struct object_id *oid, char *hdr, struct utimbuf utb; utb.actime = mtime; utb.modtime = mtime; - if (utime(tmp_file.buf, &utb) < 0) + if (utime(tmp_file.buf, &utb) < 0 && + !(flags & HASH_SILENT)) warning_errno(_("failed utime() on %s"), tmp_file.buf); } @@ -1962,8 +1965,9 @@ static int freshen_packed_object(const struct object_id *oid) return 1; } -int write_object_file(const void *buf, unsigned long len, const char *type, - struct object_id *oid) +int write_object_file_flags(const void *buf, unsigned long len, + const char *type, struct object_id *oid, + unsigned flags) { char hdr[MAX_HEADER_LEN]; int hdrlen = sizeof(hdr); @@ -1975,7 +1979,7 @@ int write_object_file(const void *buf, unsigned long len, const char *type, &hdrlen); if (freshen_packed_object(oid) || freshen_loose_object(oid)) return 0; - return write_loose_object(oid, hdr, hdrlen, buf, len, 0); + return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags); } int hash_object_file_literally(const void *buf, unsigned long len, @@ -1995,7 +1999,7 @@ int hash_object_file_literally(const void *buf, unsigned long len, goto cleanup; if (freshen_packed_object(oid) || freshen_loose_object(oid)) goto cleanup; - status = write_loose_object(oid, header, hdrlen, buf, len, 0); + status = write_loose_object(oid, header, hdrlen, buf, len, 0, 0); cleanup: free(header); @@ -2017,7 +2021,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime) if (!buf) return error(_("cannot read object for %s"), oid_to_hex(oid)); hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1; - ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime); + ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0); free(buf); return ret; diff --git a/object-store.h b/object-store.h index 1e647a5be30..cea8d38bbd0 100644 --- a/object-store.h +++ b/object-store.h @@ -223,8 +223,14 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf, unsigned long len, const char *type, struct object_id *oid); -int write_object_file(const void *buf, unsigned long len, - const char *type, struct object_id *oid); +int write_object_file_flags(const void *buf, unsigned long len, + const char *type, struct object_id *oid, + unsigned flags); +static inline int write_object_file(const void *buf, unsigned long len, + const char *type, struct object_id *oid) +{ + return write_object_file_flags(buf, len, type, oid, 0); +} int hash_object_file_literally(const void *buf, unsigned long len, const char *type, struct object_id *oid, diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh index 3627ce367c0..2e9d652d826 100755 --- a/t/t0004-unwritable.sh +++ b/t/t0004-unwritable.sh @@ -38,7 +38,7 @@ test_expect_success POSIXPERM,SANITY,!SANITIZE_LEAK 'commit should notice unwrit ' test_lazy_prereq COMMIT_OUT 'test -e "$TRASH_DIRECTORY"/out.commit' -test_expect_failure COMMIT_OUT 'commit output on unwritable repository' ' +test_expect_success COMMIT_OUT 'commit output on unwritable repository' ' cat >expect <<-\EOF && error: insufficient permission for adding an object to repository database .git/objects error: Error building trees