diff options
author | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:38 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-04-15 22:50:39 -0700 |
commit | 47de6b0425c79081e64756dcc019bb26344bf7ad (patch) | |
tree | 74179a74db058b14979c3e7a5a5fc97b97965ce6 /builtin | |
parent | 30fd3a54256a54e5a6006a203c923e97641fb2c2 (diff) | |
parent | da591a7f4bbe1a208cc5f955523506eb857c45ca (diff) | |
download | git-47de6b0425c79081e64756dcc019bb26344bf7ad.tar.gz git-47de6b0425c79081e64756dcc019bb26344bf7ad.tar.xz |
Merge branch 'nd/stream-more'
Use API to read blob data in smaller chunks in more places to reduce the
memory footprint.
By Nguyễn Thái Ngọc Duy (6) and Junio C Hamano (1)
* nd/stream-more:
update-server-info: respect core.bigfilethreshold
fsck: use streaming API for writing lost-found blobs
show: use streaming API for showing blobs
parse_object: avoid putting whole blob in core
cat-file: use streaming API to print blobs
Add more large blob test cases
streaming: make streaming-write-entry to be more reusable
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/cat-file.c | 25 | ||||
-rw-r--r-- | builtin/fsck.c | 8 | ||||
-rw-r--r-- | builtin/log.c | 34 | ||||
-rw-r--r-- | builtin/update-server-info.c | 1 |
4 files changed, 48 insertions, 20 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 8ed501f22..36a910443 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -11,6 +11,7 @@ #include "parse-options.h" #include "diff.h" #include "userdiff.h" +#include "streaming.h" #define BATCH 1 #define BATCH_CHECK 2 @@ -127,6 +128,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) return cmd_ls_tree(2, ls_args, NULL); } + if (type == OBJ_BLOB) + return stream_blob_to_fd(1, sha1, NULL, 0); buf = read_sha1_file(sha1, &type, &size); if (!buf) die("Cannot read object %s", obj_name); @@ -149,6 +152,28 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) break; case 0: + if (type_from_string(exp_type) == OBJ_BLOB) { + unsigned char blob_sha1[20]; + if (sha1_object_info(sha1, NULL) == OBJ_TAG) { + enum object_type type; + unsigned long size; + char *buffer = read_sha1_file(sha1, &type, &size); + if (memcmp(buffer, "object ", 7) || + get_sha1_hex(buffer + 7, blob_sha1)) + die("%s not a valid tag", sha1_to_hex(sha1)); + free(buffer); + } else + hashcpy(blob_sha1, sha1); + + if (sha1_object_info(blob_sha1, NULL) == OBJ_BLOB) + return stream_blob_to_fd(1, blob_sha1, NULL, 0); + /* + * we attempted to dereference a tag to a blob + * and failed; there may be new dereference + * mechanisms this code is not aware of. + * fall-back to the usual case. + */ + } buf = read_object_with_reference(sha1, exp_type, &size, NULL); break; diff --git a/builtin/fsck.c b/builtin/fsck.c index 67eb553c7..a710227a6 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -12,6 +12,7 @@ #include "parse-options.h" #include "dir.h" #include "progress.h" +#include "streaming.h" #define REACHABLE 0x0001 #define SEEN 0x0002 @@ -238,13 +239,8 @@ static void check_unreachable_object(struct object *obj) if (!(f = fopen(filename, "w"))) die_errno("Could not open '%s'", filename); if (obj->type == OBJ_BLOB) { - enum object_type type; - unsigned long size; - char *buf = read_sha1_file(obj->sha1, - &type, &size); - if (buf && fwrite(buf, 1, size, f) != size) + if (stream_blob_to_fd(fileno(f), obj->sha1, NULL, 1)) die_errno("Could not write '%s'", filename); - free(buf); } else fprintf(f, "%s\n", sha1_to_hex(obj->sha1)); if (fclose(f)) diff --git a/builtin/log.c b/builtin/log.c index 8a47012b0..690caa783 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -20,6 +20,7 @@ #include "string-list.h" #include "parse-options.h" #include "branch.h" +#include "streaming.h" /* Set a default date-time format for git log ("log.date" config variable) */ static const char *default_date_mode = NULL; @@ -383,8 +384,13 @@ static void show_tagger(char *buf, int len, struct rev_info *rev) strbuf_release(&out); } -static int show_object(const unsigned char *sha1, int show_tag_object, - struct rev_info *rev) +static int show_blob_object(const unsigned char *sha1, struct rev_info *rev) +{ + fflush(stdout); + return stream_blob_to_fd(1, sha1, NULL, 0); +} + +static int show_tag_object(const unsigned char *sha1, struct rev_info *rev) { unsigned long size; enum object_type type; @@ -394,16 +400,16 @@ static int show_object(const unsigned char *sha1, int show_tag_object, if (!buf) return error(_("Could not read object %s"), sha1_to_hex(sha1)); - if (show_tag_object) - while (offset < size && buf[offset] != '\n') { - int new_offset = offset + 1; - while (new_offset < size && buf[new_offset++] != '\n') - ; /* do nothing */ - if (!prefixcmp(buf + offset, "tagger ")) - show_tagger(buf + offset + 7, - new_offset - offset - 7, rev); - offset = new_offset; - } + assert(type == OBJ_TAG); + while (offset < size && buf[offset] != '\n') { + int new_offset = offset + 1; + while (new_offset < size && buf[new_offset++] != '\n') + ; /* do nothing */ + if (!prefixcmp(buf + offset, "tagger ")) + show_tagger(buf + offset + 7, + new_offset - offset - 7, rev); + offset = new_offset; + } if (offset < size) fwrite(buf + offset, size - offset, 1, stdout); @@ -463,7 +469,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) const char *name = objects[i].name; switch (o->type) { case OBJ_BLOB: - ret = show_object(o->sha1, 0, NULL); + ret = show_blob_object(o->sha1, NULL); break; case OBJ_TAG: { struct tag *t = (struct tag *)o; @@ -474,7 +480,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), t->tag, diff_get_color_opt(&rev.diffopt, DIFF_RESET)); - ret = show_object(o->sha1, 1, &rev); + ret = show_tag_object(o->sha1, &rev); rev.shown_one = 1; if (ret) break; diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index b90dce635..0d63c4498 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -15,6 +15,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix) OPT_END() }; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, update_server_info_usage, 0); if (argc > 0) |