From: Timo Hirvonen Date: Wed, 24 May 2006 11:08:46 +0000 (+0300) Subject: Builtin git-cat-file X-Git-Tag: v1.4.0-rc1~73 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=f81daefe56b3c97b93a851e1ada14eeca0dea47a;p=git.git Builtin git-cat-file Signed-off-by: Timo Hirvonen Signed-off-by: Junio C Hamano --- diff --git a/Makefile b/Makefile index 7e6517f6..dbf19c62 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,6 @@ SIMPLE_PROGRAMS = \ # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ - git-cat-file$X \ git-checkout-index$X git-clone-pack$X \ git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ @@ -174,7 +173,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X \ git-ls-files$X git-ls-tree$X \ git-read-tree$X git-commit-tree$X \ git-apply$X git-show-branch$X git-diff-files$X \ - git-diff-index$X git-diff-stages$X git-diff-tree$X + git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -228,7 +227,8 @@ BUILTIN_OBJS = \ builtin-ls-files.o builtin-ls-tree.o \ builtin-read-tree.o builtin-commit-tree.o \ builtin-apply.o builtin-show-branch.o builtin-diff-files.o \ - builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o + builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ + builtin-cat-file.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-cat-file.c b/builtin-cat-file.c new file mode 100644 index 00000000..8ab136e9 --- /dev/null +++ b/builtin-cat-file.c @@ -0,0 +1,167 @@ +/* + * GIT - The information manager from hell + * + * Copyright (C) Linus Torvalds, 2005 + */ +#include "cache.h" +#include "exec_cmd.h" +#include "tag.h" +#include "tree.h" +#include "builtin.h" + +static void flush_buffer(const char *buf, unsigned long size) +{ + while (size > 0) { + long ret = xwrite(1, buf, size); + if (ret < 0) { + /* Ignore epipe */ + if (errno == EPIPE) + break; + die("git-cat-file: %s", strerror(errno)); + } else if (!ret) { + die("git-cat-file: disk full?"); + } + size -= ret; + buf += ret; + } +} + +static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size) +{ + /* the parser in tag.c is useless here. */ + const char *endp = buf + size; + const char *cp = buf; + + while (cp < endp) { + char c = *cp++; + if (c != '\n') + continue; + if (7 <= endp - cp && !memcmp("tagger ", cp, 7)) { + const char *tagger = cp; + + /* Found the tagger line. Copy out the contents + * of the buffer so far. + */ + flush_buffer(buf, cp - buf); + + /* + * Do something intelligent, like pretty-printing + * the date. + */ + while (cp < endp) { + if (*cp++ == '\n') { + /* tagger to cp is a line + * that has ident and time. + */ + const char *sp = tagger; + char *ep; + unsigned long date; + long tz; + while (sp < cp && *sp != '>') + sp++; + if (sp == cp) { + /* give up */ + flush_buffer(tagger, + cp - tagger); + break; + } + while (sp < cp && + !('0' <= *sp && *sp <= '9')) + sp++; + flush_buffer(tagger, sp - tagger); + date = strtoul(sp, &ep, 10); + tz = strtol(ep, NULL, 10); + sp = show_date(date, tz); + flush_buffer(sp, strlen(sp)); + xwrite(1, "\n", 1); + break; + } + } + break; + } + if (cp < endp && *cp == '\n') + /* end of header */ + break; + } + /* At this point, we have copied out the header up to the end of + * the tagger line and cp points at one past \n. It could be the + * next header line after the tagger line, or it could be another + * \n that marks the end of the headers. We need to copy out the + * remainder as is. + */ + if (cp < endp) + flush_buffer(cp, endp - cp); + return 0; +} + +int cmd_cat_file(int argc, const char **argv, char **envp) +{ + unsigned char sha1[20]; + char type[20]; + void *buf; + unsigned long size; + int opt; + + setup_git_directory(); + git_config(git_default_config); + if (argc != 3) + usage("git-cat-file [-t|-s|-e|-p|] "); + if (get_sha1(argv[2], sha1)) + die("Not a valid object name %s", argv[2]); + + opt = 0; + if ( argv[1][0] == '-' ) { + opt = argv[1][1]; + if ( !opt || argv[1][2] ) + opt = -1; /* Not a single character option */ + } + + buf = NULL; + switch (opt) { + case 't': + if (!sha1_object_info(sha1, type, NULL)) { + printf("%s\n", type); + return 0; + } + break; + + case 's': + if (!sha1_object_info(sha1, type, &size)) { + printf("%lu\n", size); + return 0; + } + break; + + case 'e': + return !has_sha1_file(sha1); + + case 'p': + if (sha1_object_info(sha1, type, NULL)) + die("Not a valid object name %s", argv[2]); + + /* custom pretty-print here */ + if (!strcmp(type, tree_type)) + return execl_git_cmd("ls-tree", argv[2], NULL); + + buf = read_sha1_file(sha1, type, &size); + if (!buf) + die("Cannot read object %s", argv[2]); + if (!strcmp(type, tag_type)) + return pprint_tag(sha1, buf, size); + + /* otherwise just spit out the data */ + break; + case 0: + buf = read_object_with_reference(sha1, argv[1], &size, NULL); + break; + + default: + die("git-cat-file: unknown option: %s\n", argv[1]); + } + + if (!buf) + die("git-cat-file %s: bad file", argv[2]); + + flush_buffer(buf, size); + return 0; +} diff --git a/builtin.h b/builtin.h index 714b9757..738ec3d9 100644 --- a/builtin.h +++ b/builtin.h @@ -42,5 +42,6 @@ extern int cmd_diff_files(int argc, const char **argv, char **envp); extern int cmd_diff_index(int argc, const char **argv, char **envp); extern int cmd_diff_stages(int argc, const char **argv, char **envp); extern int cmd_diff_tree(int argc, const char **argv, char **envp); +extern int cmd_cat_file(int argc, const char **argv, char **envp); #endif diff --git a/cat-file.c b/cat-file.c deleted file mode 100644 index 7413feed..00000000 --- a/cat-file.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * GIT - The information manager from hell - * - * Copyright (C) Linus Torvalds, 2005 - */ -#include "cache.h" -#include "exec_cmd.h" -#include "tag.h" -#include "tree.h" - -static void flush_buffer(const char *buf, unsigned long size) -{ - while (size > 0) { - long ret = xwrite(1, buf, size); - if (ret < 0) { - /* Ignore epipe */ - if (errno == EPIPE) - break; - die("git-cat-file: %s", strerror(errno)); - } else if (!ret) { - die("git-cat-file: disk full?"); - } - size -= ret; - buf += ret; - } -} - -static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size) -{ - /* the parser in tag.c is useless here. */ - const char *endp = buf + size; - const char *cp = buf; - - while (cp < endp) { - char c = *cp++; - if (c != '\n') - continue; - if (7 <= endp - cp && !memcmp("tagger ", cp, 7)) { - const char *tagger = cp; - - /* Found the tagger line. Copy out the contents - * of the buffer so far. - */ - flush_buffer(buf, cp - buf); - - /* - * Do something intelligent, like pretty-printing - * the date. - */ - while (cp < endp) { - if (*cp++ == '\n') { - /* tagger to cp is a line - * that has ident and time. - */ - const char *sp = tagger; - char *ep; - unsigned long date; - long tz; - while (sp < cp && *sp != '>') - sp++; - if (sp == cp) { - /* give up */ - flush_buffer(tagger, - cp - tagger); - break; - } - while (sp < cp && - !('0' <= *sp && *sp <= '9')) - sp++; - flush_buffer(tagger, sp - tagger); - date = strtoul(sp, &ep, 10); - tz = strtol(ep, NULL, 10); - sp = show_date(date, tz); - flush_buffer(sp, strlen(sp)); - xwrite(1, "\n", 1); - break; - } - } - break; - } - if (cp < endp && *cp == '\n') - /* end of header */ - break; - } - /* At this point, we have copied out the header up to the end of - * the tagger line and cp points at one past \n. It could be the - * next header line after the tagger line, or it could be another - * \n that marks the end of the headers. We need to copy out the - * remainder as is. - */ - if (cp < endp) - flush_buffer(cp, endp - cp); - return 0; -} - -int main(int argc, char **argv) -{ - unsigned char sha1[20]; - char type[20]; - void *buf; - unsigned long size; - int opt; - - setup_git_directory(); - git_config(git_default_config); - if (argc != 3) - usage("git-cat-file [-t|-s|-e|-p|] "); - if (get_sha1(argv[2], sha1)) - die("Not a valid object name %s", argv[2]); - - opt = 0; - if ( argv[1][0] == '-' ) { - opt = argv[1][1]; - if ( !opt || argv[1][2] ) - opt = -1; /* Not a single character option */ - } - - buf = NULL; - switch (opt) { - case 't': - if (!sha1_object_info(sha1, type, NULL)) { - printf("%s\n", type); - return 0; - } - break; - - case 's': - if (!sha1_object_info(sha1, type, &size)) { - printf("%lu\n", size); - return 0; - } - break; - - case 'e': - return !has_sha1_file(sha1); - - case 'p': - if (sha1_object_info(sha1, type, NULL)) - die("Not a valid object name %s", argv[2]); - - /* custom pretty-print here */ - if (!strcmp(type, tree_type)) - return execl_git_cmd("ls-tree", argv[2], NULL); - - buf = read_sha1_file(sha1, type, &size); - if (!buf) - die("Cannot read object %s", argv[2]); - if (!strcmp(type, tag_type)) - return pprint_tag(sha1, buf, size); - - /* otherwise just spit out the data */ - break; - case 0: - buf = read_object_with_reference(sha1, argv[1], &size, NULL); - break; - - default: - die("git-cat-file: unknown option: %s\n", argv[1]); - } - - if (!buf) - die("git-cat-file %s: bad file", argv[2]); - - flush_buffer(buf, size); - return 0; -} diff --git a/git.c b/git.c index 5a884bb0..10ea934b 100644 --- a/git.c +++ b/git.c @@ -68,7 +68,8 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "diff-files", cmd_diff_files }, { "diff-index", cmd_diff_index }, { "diff-stages", cmd_diff_stages }, - { "diff-tree", cmd_diff_tree } + { "diff-tree", cmd_diff_tree }, + { "cat-file", cmd_cat_file } }; int i;