commit - 30ee8dc804f0f9c0600dc96bda4a16307d753c96
commit + 72840534edfc1ffa7aafa0ce0ab42568c8ec7145
blob - 52c3d2577c7b0308e62c7ff466152e61a38f3c50
blob + 6a151f9c54a8c0f4fc4fea9a4c91ecc7dec71aed
--- lib/deflate.c
+++ lib/deflate.c
}
const struct got_error *
-got_deflate_read(struct got_deflate_buf *zb, FILE *f, size_t *outlenp)
+got_deflate_read(struct got_deflate_buf *zb, FILE *f, off_t len,
+ size_t *outlenp, off_t *consumed)
{
size_t last_total_out = zb->z.total_out;
z_stream *z = &zb->z;
z->avail_out = zb->outlen;
*outlenp = 0;
+ *consumed = 0;
do {
+ size_t last_total_in = z->total_in;
if (z->avail_in == 0) {
- size_t n = fread(zb->inbuf, 1, zb->inlen, f);
+ size_t n = 0;
+ if (*consumed < len) {
+ n = fread(zb->inbuf, 1,
+ MIN(zb->inlen, len - *consumed), f);
+ }
if (n == 0) {
if (ferror(f))
return got_ferror(f, GOT_ERR_IO);
z->avail_in = n;
}
ret = deflate(z, Z_NO_FLUSH);
+ *consumed += z->total_in - last_total_in;
} while (ret == Z_OK && z->avail_out > 0);
if (ret == Z_OK) {
}
const struct got_error *
-got_deflate_to_file(size_t *outlen, FILE *infile, FILE *outfile,
- struct got_deflate_checksum *csum)
+got_deflate_to_file(off_t *outlen, FILE *infile, off_t len,
+ FILE *outfile, struct got_deflate_checksum *csum)
{
const struct got_error *err;
size_t avail;
+ off_t consumed;
struct got_deflate_buf zb;
err = got_deflate_init(&zb, NULL, GOT_DEFLATE_BUFSIZE);
*outlen = 0;
do {
- err = got_deflate_read(&zb, infile, &avail);
+ err = got_deflate_read(&zb, infile, len, &avail, &consumed);
if (err)
goto done;
+ len -= consumed;
if (avail > 0) {
size_t n;
n = fwrite(zb.outbuf, avail, 1, outfile);
}
const struct got_error *
-got_deflate_to_file_mmap(size_t *outlen, uint8_t *map, size_t offset,
+got_deflate_to_file_mmap(off_t *outlen, uint8_t *map, size_t offset,
size_t len, FILE *outfile, struct got_deflate_checksum *csum)
{
const struct got_error *err;
blob - c0b4fe271d48124cc97b135feff4b79f951c6720
blob + 1c429af85a27229451e05798e9511d0a8f474968
--- lib/got_lib_deflate.h
+++ lib/got_lib_deflate.h
const struct got_error *got_deflate_init(struct got_deflate_buf *, uint8_t *,
size_t);
const struct got_error *got_deflate_read(struct got_deflate_buf *, FILE *,
- size_t *);
+ off_t, size_t *, off_t *);
void got_deflate_end(struct got_deflate_buf *);
-const struct got_error *got_deflate_to_file(size_t *, FILE *, FILE *,
+const struct got_error *got_deflate_to_file(off_t *, FILE *, off_t, FILE *,
struct got_deflate_checksum *);
-const struct got_error *got_deflate_to_file_mmap(size_t *, uint8_t *,
+const struct got_error *got_deflate_to_file_mmap(off_t *, uint8_t *,
size_t, size_t, FILE *, struct got_deflate_checksum *);
blob - 67676602467844816045891f0532476d0e14c799
blob + 1d6840ec3d3bc9318e74417e89f1c1056a322dd0
--- lib/got_lib_object_create.h
+++ lib/got_lib_object_create.h
*/
const struct got_error *got_object_blob_file_create(struct got_object_id **,
- FILE **, const char *);
+ FILE **, off_t *, const char *);
const struct got_error *got_object_blob_create(struct got_object_id **,
const char *, struct got_repository *);
blob - e5e4c44c8a0327211b0094775682f2bed8ea42a8
blob + 3102c04085d4e8c0157a4d3fd9c725a4b76f8c88
--- lib/object_create.c
+++ lib/object_create.c
static const struct got_error *
create_object_file(struct got_object_id *id, FILE *content,
- struct got_repository *repo)
+ off_t content_len, struct got_repository *repo)
{
const struct got_error *err = NULL, *unlock_err = NULL;
char *objpath = NULL, *tmppath = NULL;
FILE *tmpfile = NULL;
struct got_lockfile *lf = NULL;
- size_t tmplen = 0;
+ off_t tmplen = 0;
err = got_object_get_path(&objpath, id, repo);
if (err)
goto done;
}
- err = got_deflate_to_file(&tmplen, content, tmpfile, NULL);
+ err = got_deflate_to_file(&tmplen, content, content_len, tmpfile, NULL);
if (err)
goto done;
const struct got_error *
got_object_blob_file_create(struct got_object_id **id, FILE **blobfile,
- const char *ondisk_path)
+ off_t *blobsize, const char *ondisk_path)
{
const struct got_error *err = NULL;
char *header = NULL;
*id = NULL;
*blobfile = NULL;
+ *blobsize = 0;
SHA1Init(&sha1_ctx);
err = got_ferror(*blobfile, GOT_ERR_IO);
goto done;
}
+ *blobsize += headerlen;
for (;;) {
char buf[PATH_MAX * 8];
ssize_t inlen;
err = got_ferror(*blobfile, GOT_ERR_IO);
goto done;
}
+ *blobsize += n;
if (S_ISLNK(sb.st_mode))
break;
}
{
const struct got_error *err = NULL;
FILE *blobfile = NULL;
+ off_t blobsize;
- err = got_object_blob_file_create(id, &blobfile, ondisk_path);
+ err = got_object_blob_file_create(id, &blobfile, &blobsize,
+ ondisk_path);
if (err)
return err;
- err = create_object_file(*id, blobfile, repo);
+ err = create_object_file(*id, blobfile, blobsize, repo);
if (fclose(blobfile) == EOF && err == NULL)
err = got_error_from_errno("fclose");
if (err) {
char *header = NULL;
size_t headerlen, len = 0, n;
FILE *treefile = NULL;
+ off_t treesize = 0;
struct got_pathlist_entry *pe;
struct got_tree_entry **sorted_entries;
struct got_tree_entry *te;
err = got_ferror(treefile, GOT_ERR_IO);
goto done;
}
+ treesize += headerlen;
for (i = 0; i < nentries; i++) {
te = sorted_entries[i];
goto done;
}
SHA1Update(&sha1_ctx, modebuf, len);
+ treesize += n;
len = strlen(te->name) + 1; /* must include NUL */
n = fwrite(te->name, 1, len, treefile);
goto done;
}
SHA1Update(&sha1_ctx, te->name, len);
+ treesize += n;
len = SHA1_DIGEST_LENGTH;
n = fwrite(te->id.sha1, 1, len, treefile);
goto done;
}
SHA1Update(&sha1_ctx, te->id.sha1, len);
+ treesize += n;
}
*id = malloc(sizeof(**id));
}
rewind(treefile);
- err = create_object_file(*id, treefile, repo);
+ err = create_object_file(*id, treefile, treesize, repo);
done:
free(header);
free(sorted_entries);
char *id_str = NULL;
size_t headerlen, len = 0, n;
FILE *commitfile = NULL;
+ off_t commitsize = 0;
struct got_object_qid *qid;
char *msg0, *msg;
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += headerlen;
err = got_object_id_str(&id_str, tree_id);
if (err)
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
if (parent_ids) {
free(id_str);
free(parent_str);
goto done;
}
+ commitsize += n;
free(parent_str);
free(id_str);
id_str = NULL;
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
len = strlen(committer_str);
SHA1Update(&sha1_ctx, committer_str, len);
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
SHA1Update(&sha1_ctx, "\n", 1);
n = fwrite("\n", 1, 1, commitfile);
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
len = strlen(msg);
SHA1Update(&sha1_ctx, msg, len);
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
SHA1Update(&sha1_ctx, "\n", 1);
n = fwrite("\n", 1, 1, commitfile);
err = got_ferror(commitfile, GOT_ERR_IO);
goto done;
}
+ commitsize += n;
*id = malloc(sizeof(**id));
if (*id == NULL) {
}
rewind(commitfile);
- err = create_object_file(*id, commitfile, repo);
+ err = create_object_file(*id, commitfile, commitsize, repo);
done:
free(id_str);
free(msg0);
char *id_str = NULL, *obj_str = NULL, *type_str = NULL;
size_t headerlen, len = 0, n;
FILE *tagfile = NULL;
+ off_t tagsize = 0;
char *msg0 = NULL, *msg;
const char *obj_type_str;
int obj_type;
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += headerlen;
len = strlen(obj_str);
SHA1Update(&sha1_ctx, obj_str, len);
n = fwrite(obj_str, 1, len, tagfile);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
len = strlen(type_str);
SHA1Update(&sha1_ctx, type_str, len);
n = fwrite(type_str, 1, len, tagfile);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
len = strlen(tag_str);
SHA1Update(&sha1_ctx, tag_str, len);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
len = strlen(tagger_str);
SHA1Update(&sha1_ctx, tagger_str, len);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
SHA1Update(&sha1_ctx, "\n", 1);
n = fwrite("\n", 1, 1, tagfile);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
len = strlen(msg);
SHA1Update(&sha1_ctx, msg, len);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
SHA1Update(&sha1_ctx, "\n", 1);
n = fwrite("\n", 1, 1, tagfile);
err = got_ferror(tagfile, GOT_ERR_IO);
goto done;
}
+ tagsize += n;
*id = malloc(sizeof(**id));
if (*id == NULL) {
}
rewind(tagfile);
- err = create_object_file(*id, tagfile, repo);
+ err = create_object_file(*id, tagfile, tagsize, repo);
done:
free(msg0);
free(header);
blob - 8a3d8a8fd7f7eb29a2707c38e554ff6a37b63685
blob + f4c9f4cd1e5f2d7ec2bb640a2745e9ef11b8f29a
--- lib/pack_create.c
+++ lib/pack_create.c
SHA1_CTX ctx;
struct got_pack_meta *m;
struct got_raw_object *raw = NULL;
- FILE *delta_file = NULL;
char buf[32];
- size_t outlen, n;
+ size_t n;
struct got_deflate_checksum csum;
- off_t packfile_size = 0;
+ off_t outlen, packfile_size = 0;
int outfd = -1;
SHA1Init(&ctx);
goto done;
}
err = got_deflate_to_file(&outlen, raw->f,
- packfile, &csum);
+ raw->size, packfile, &csum);
if (err)
goto done;
}
free(m->delta_buf);
m->delta_buf = NULL;
} else {
- off_t remain;
- if (delta_file == NULL) {
- delta_file = got_opentemp();
- if (delta_file == NULL) {
- err = got_error_from_errno(
- "got_opentemp");
- goto done;
- }
- }
- if (ftruncate(fileno(delta_file), 0L) == -1) {
- err = got_error_from_errno("ftruncate");
- goto done;
- }
- if (fseeko(delta_file, 0L, SEEK_SET) == -1) {
- err = got_error_from_errno("fseeko");
- goto done;
- }
if (fseeko(delta_cache, m->delta_offset, SEEK_SET)
== -1) {
err = got_error_from_errno("fseeko");
goto done;
}
- remain = m->delta_len;
- while (remain > 0) {
- char delta_buf[8192];
- size_t r, w, n;
- n = MIN(remain, sizeof(delta_buf));
- r = fread(delta_buf, 1, n, delta_cache);
- if (r != n) {
- err = got_ferror(delta_cache,
- GOT_ERR_IO);
- goto done;
- }
- w = fwrite(delta_buf, 1, n, delta_file);
- if (w != n) {
- err = got_ferror(delta_file,
- GOT_ERR_IO);
- goto done;
- }
- remain -= n;
- }
err = deltahdr(&packfile_size, &ctx, packfile,
m, use_offset_deltas);
if (err)
goto done;
- if (fseeko(delta_file, 0L, SEEK_SET) == -1) {
- err = got_error_from_errno("fseeko");
- goto done;
- }
- err = got_deflate_to_file(&outlen, delta_file,
- packfile, &csum);
+ err = got_deflate_to_file(&outlen, delta_cache,
+ m->delta_len, packfile, &csum);
if (err)
goto done;
packfile_size += outlen;
goto done;
}
done:
- if (delta_file && fclose(delta_file) == EOF && err == NULL)
- err = got_error_from_errno("fclose");
if (raw)
got_object_raw_close(raw);
if (outfd != -1 && close(outfd) == -1 && err == NULL)
blob - dba36bee48eede3aca73746d5501b4565bbddf64
blob + 0f78ee740bd078fd66df140aa19f2527ef430e0f
--- lib/worktree.c
+++ lib/worktree.c
case GOT_STATUS_ADD: {
struct got_object_id *id;
FILE *blob1_f;
+ off_t blob1_size;
/*
* Delete the added file only if its content already
* exists in the repository.
*/
- err = got_object_blob_file_create(&id, &blob1_f, path1);
+ err = got_object_blob_file_create(&id, &blob1_f,
+ &blob1_size, path1);
if (err)
goto done;
if (got_object_id_cmp(id, id1) == 0) {
blob - d2b9ef37e4422a8ab8e017e17df21a7c6f3be7e8
blob + 34d74d26fefb2a4461a2c489cade5dcd7ebfcd66
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
fi
test_done "$testroot" "$ret"
}
+
+test_commit_large_file() {
+ local testroot=`test_init commit_large_file`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ dd status=none if=/dev/zero of=$testroot/wt/new bs=1m count=64
+ (cd $testroot/wt && got add new >/dev/null)
+ (cd $testroot/wt && got commit -m 'test commit_large_file' \
+ > $testroot/stdout)
+
+ local head_rev=`git_show_head $testroot/repo`
+ echo "A new" > $testroot/stdout.expected
+ echo "Created commit $head_rev" >> $testroot/stdout.expected
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ new_id=`get_blob_id $testroot/repo "" new`
+ got cat -r $testroot/repo $new_id > $testroot/new
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "commit failed unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ cmp -s $testroot/new $testroot/wt/new
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/new $testroot/wt/new
+ fi
+ test_done "$testroot" "$ret"
+
+
+}
+
+
test_parseargs "$@"
run_test test_commit_basic
run_test test_commit_new_subdir
run_test test_commit_symlink
run_test test_commit_fix_bad_symlink
run_test test_commit_prepared_logmsg
+run_test test_commit_large_file