Merge branch 'ab/fix-commit-error-message-upon-unwritable-object-store'

"git commit" gave duplicated error message when the object store
was unwritable, which has been corrected.

* ab/fix-commit-error-message-upon-unwritable-object-store:
  commit: fix duplication regression in permission error output
  unwritable tests: assert exact error output
This commit is contained in:
Junio C Hamano 2021-10-25 16:06:57 -07:00
commit 2c428e4205
5 changed files with 67 additions and 16 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -1862,7 +1862,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];
@ -1876,7 +1876,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"));
@ -1926,7 +1928,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);
}
@ -1951,8 +1954,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);
@ -1964,7 +1968,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,
@ -1984,7 +1988,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);
@ -2006,7 +2010,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;

View File

@ -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,

View File

@ -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_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
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