From 83aa18eade572679319406d6dc12a81599a4d57e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 27 Apr 2006 09:02:54 -0700 Subject: Fix "git help -a" terminal autosizing When I split out the builtin commands into their own files, I left the include of in git.c rather than moving it to the file that needed it (builtin-help.c). Nobody seems to have noticed, because everything still worked, but because the TIOCGWINSZ macro was now no longer defined when compiling the "term_columns()" function, it would no longer automatically notice the terminal size unless your system used the ancient "COLUMNS" environment variable approach. Trivially fixed by just moving the header include to the file that actually needs it. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- git.c | 1 - 1 file changed, 1 deletion(-) (limited to 'git.c') diff --git a/git.c b/git.c index aa2b814d93..01b7e28b8c 100644 --- a/git.c +++ b/git.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "git-compat-util.h" #include "exec_cmd.h" -- cgit 1.2.3-korg From c74320872b445104fe5c265e60785d9d26d94cc5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 27 Apr 2006 15:37:18 -0700 Subject: built-in count-objects. Also it learned to do -v (verbose) to report: - number of loose objects - disk occupied by loose objects - number of objects in local packs - number of loose objects that are also in pack - unrecognised garbage in .git/objects/??/. Signed-off-by: Junio C Hamano --- Makefile | 2 +- builtin-count.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 1 + git.c | 1 + 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 builtin-count.c (limited to 'git.c') diff --git a/Makefile b/Makefile index 8ce27a65fb..14193aa1e2 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ LIB_OBJS = \ $(DIFF_OBJS) BUILTIN_OBJS = \ - builtin-log.o builtin-help.o + builtin-log.o builtin-help.o builtin-count.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-count.c b/builtin-count.c new file mode 100644 index 0000000000..0256369d5b --- /dev/null +++ b/builtin-count.c @@ -0,0 +1,123 @@ +/* + * Builtin "git count-objects". + * + * Copyright (c) 2006 Junio C Hamano + */ + +#include "cache.h" +#include "builtin.h" + +static const char count_objects_usage[] = "git-count-objects [-v]"; + +static void count_objects(DIR *d, char *path, int len, int verbose, + unsigned long *loose, + unsigned long *loose_size, + unsigned long *packed_loose, + unsigned long *garbage) +{ + struct dirent *ent; + while ((ent = readdir(d)) != NULL) { + char hex[41]; + unsigned char sha1[20]; + const char *cp; + int bad = 0; + + if ((ent->d_name[0] == '.') && + (ent->d_name[1] == 0 || + ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)))) + continue; + for (cp = ent->d_name; *cp; cp++) { + int ch = *cp; + if (('0' <= ch && ch <= '9') || + ('a' <= ch && ch <= 'f')) + continue; + bad = 1; + break; + } + if (cp - ent->d_name != 38) + bad = 1; + else { + struct stat st; + memcpy(path + len + 3, ent->d_name, 38); + path[len + 2] = '/'; + path[len + 41] = 0; + if (lstat(path, &st) || !S_ISREG(st.st_mode)) + bad = 1; + else + (*loose_size) += st.st_blocks; + } + if (bad) { + if (verbose) { + error("garbage found: %.*s/%s", + len + 2, path, ent->d_name); + (*garbage)++; + } + continue; + } + (*loose)++; + if (!verbose) + continue; + memcpy(hex, path+len, 2); + memcpy(hex+2, ent->d_name, 38); + hex[40] = 0; + if (get_sha1_hex(hex, sha1)) + die("internal error"); + if (has_sha1_pack(sha1)) + (*packed_loose)++; + } +} + +int cmd_count_objects(int ac, const char **av, char **ep) +{ + int i; + int verbose = 0; + const char *objdir = get_object_directory(); + int len = strlen(objdir); + char *path = xmalloc(len + 50); + unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0; + unsigned long loose_size = 0; + + for (i = 1; i < ac; i++) { + const char *arg = av[i]; + if (*arg != '-') + break; + else if (!strcmp(arg, "-v")) + verbose = 1; + else + usage(count_objects_usage); + } + + /* we do not take arguments other than flags for now */ + if (i < ac) + usage(count_objects_usage); + memcpy(path, objdir, len); + if (len && objdir[len-1] != '/') + path[len++] = '/'; + for (i = 0; i < 256; i++) { + DIR *d; + sprintf(path + len, "%02x", i); + d = opendir(path); + if (!d) + continue; + count_objects(d, path, len, verbose, + &loose, &loose_size, &packed_loose, &garbage); + closedir(d); + } + if (verbose) { + struct packed_git *p; + for (p = packed_git; p; p = p->next) { + if (!p->pack_local) + continue; + packed += num_packed_objects(p); + } + printf("count: %lu\n", loose); + printf("size: %lu\n", loose_size / 2); + printf("in-pack: %lu\n", packed); + printf("prune-packable: %lu\n", packed_loose); + printf("garbage: %lu\n", garbage); + } + else + printf("%lu objects, %lu kilobytes\n", + loose, loose_size / 2); + return 0; +} diff --git a/builtin.h b/builtin.h index 47408a0585..76169e3f05 100644 --- a/builtin.h +++ b/builtin.h @@ -19,5 +19,6 @@ extern int cmd_version(int argc, const char **argv, char **envp); extern int cmd_whatchanged(int argc, const char **argv, char **envp); extern int cmd_show(int argc, const char **argv, char **envp); extern int cmd_log(int argc, const char **argv, char **envp); +extern int cmd_count_objects(int argc, const char **argv, char **envp); #endif diff --git a/git.c b/git.c index 01b7e28b8c..00fb399725 100644 --- a/git.c +++ b/git.c @@ -46,6 +46,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, + { "count-objects", cmd_count_objects }, }; int i; -- cgit 1.2.3-korg From 65056021f2d2dcb7a72f05c5d6cbbd79a79b9d40 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 28 Apr 2006 23:20:52 -0700 Subject: built-in diff. This starts to replace the shell script version of "git diff". Signed-off-by: Junio C Hamano --- Makefile | 2 +- builtin-diff.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 1 + git.c | 1 + 4 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 builtin-diff.c (limited to 'git.c') diff --git a/Makefile b/Makefile index 8ce27a65fb..277c1ac079 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ LIB_OBJS = \ $(DIFF_OBJS) BUILTIN_OBJS = \ - builtin-log.o builtin-help.o + builtin-log.o builtin-help.o builtin-diff.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-diff.c b/builtin-diff.c new file mode 100644 index 0000000000..196821294e --- /dev/null +++ b/builtin-diff.c @@ -0,0 +1,332 @@ +/* + * Builtin "git diff" + * + * Copyright (c) 2006 Junio C Hamano + */ +#include "cache.h" +#include "commit.h" +#include "blob.h" +#include "tag.h" +#include "diff.h" +#include "diffcore.h" +#include "revision.h" +#include "log-tree.h" +#include "builtin.h" + +/* NEEDSWORK: struct object has place for name but we _do_ + * know mode when we extracted the blob out of a tree, which + * we currently lose. + */ +struct blobinfo { + unsigned char sha1[20]; + const char *name; +}; + +static const char builtin_diff_usage[] = +"diff {0,2} -- *"; + +static int builtin_diff_files(struct rev_info *revs, + int argc, const char **argv) +{ + int silent = 0; + while (1 < argc) { + const char *arg = argv[1]; + if (!strcmp(arg, "--base")) + revs->max_count = 1; + else if (!strcmp(arg, "--ours")) + revs->max_count = 2; + else if (!strcmp(arg, "--theirs")) + revs->max_count = 3; + else if (!strcmp(arg, "-q")) + silent = 1; + else if (!strcmp(arg, "--raw")) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + else + usage(builtin_diff_usage); + argv++; argc--; + } + /* + * Make sure there are NO revision (i.e. pending object) parameter, + * rev.max_count is reasonable (0 <= n <= 3), + * there is no other revision filtering parameters. + */ + if (revs->pending_objects || + revs->min_age != -1 || + revs->max_age != -1) + usage(builtin_diff_usage); + /* + * Backward compatibility wart - "diff-files -s" used to + * defeat the common diff option "-s" which asked for + * DIFF_FORMAT_NO_OUTPUT. + */ + if (revs->diffopt.output_format == DIFF_FORMAT_NO_OUTPUT) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + return run_diff_files(revs, silent); +} + +static void stuff_change(struct diff_options *opt, + unsigned old_mode, unsigned new_mode, + const unsigned char *old_sha1, + const unsigned char *new_sha1, + const char *old_name, + const char *new_name) +{ + struct diff_filespec *one, *two; + + if (memcmp(null_sha1, old_sha1, 20) && + memcmp(null_sha1, new_sha1, 20) && + !memcmp(old_sha1, new_sha1, 20)) + return; + + if (opt->reverse_diff) { + unsigned tmp; + const + const unsigned char *tmp_u; + const char *tmp_c; + tmp = old_mode; old_mode = new_mode; new_mode = tmp; + tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u; + tmp_c = old_name; old_name = new_name; new_name = tmp_c; + } + one = alloc_filespec(old_name); + two = alloc_filespec(new_name); + fill_filespec(one, old_sha1, old_mode); + fill_filespec(two, new_sha1, new_mode); + + /* NEEDSWORK: shouldn't this part of diffopt??? */ + diff_queue(&diff_queued_diff, one, two); +} + +static int builtin_diff_b_f(struct rev_info *revs, + int argc, const char **argv, + struct blobinfo *blob, + const char *path) +{ + /* Blob vs file in the working tree*/ + struct stat st; + + while (1 < argc) { + const char *arg = argv[1]; + if (!strcmp(arg, "--raw")) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + else + usage(builtin_diff_usage); + argv++; argc--; + } + if (lstat(path, &st)) + die("'%s': %s", path, strerror(errno)); + if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) + die("'%s': not a regular file or symlink", path); + stuff_change(&revs->diffopt, + canon_mode(st.st_mode), canon_mode(st.st_mode), + blob[0].sha1, null_sha1, + blob[0].name, path); + diffcore_std(&revs->diffopt); + diff_flush(&revs->diffopt); + return 0; +} + +static int builtin_diff_blobs(struct rev_info *revs, + int argc, const char **argv, + struct blobinfo *blob) +{ + /* Blobs */ + unsigned mode = canon_mode(S_IFREG | 0644); + + while (1 < argc) { + const char *arg = argv[1]; + if (!strcmp(arg, "--raw")) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + else + usage(builtin_diff_usage); + argv++; argc--; + } + stuff_change(&revs->diffopt, + mode, mode, + blob[0].sha1, blob[1].sha1, + blob[1].name, blob[1].name); + diffcore_std(&revs->diffopt); + diff_flush(&revs->diffopt); + return 0; +} + +static int builtin_diff_index(struct rev_info *revs, + int argc, const char **argv) +{ + int cached = 0; + while (1 < argc) { + const char *arg = argv[1]; + if (!strcmp(arg, "--cached")) + cached = 1; + else if (!strcmp(arg, "--raw")) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + else + usage(builtin_diff_usage); + argv++; argc--; + } + /* + * Make sure there is one revision (i.e. pending object), + * and there is no revision filtering parameters. + */ + if (!revs->pending_objects || revs->pending_objects->next || + revs->max_count != -1 || revs->min_age != -1 || + revs->max_age != -1) + usage(builtin_diff_usage); + return run_diff_index(revs, cached); +} + +static int builtin_diff_tree(struct rev_info *revs, + int argc, const char **argv, + struct object_list *ent) +{ + /* We saw two trees, ent[0] and ent[1]. + * unless ent[0] is unintesting, they are swapped + */ + const unsigned char *(sha1[2]); + int swap = 1; + while (1 < argc) { + const char *arg = argv[1]; + if (!strcmp(arg, "--raw")) + revs->diffopt.output_format = DIFF_FORMAT_RAW; + else + usage(builtin_diff_usage); + argv++; argc--; + } + if (ent[0].item->flags & UNINTERESTING) + swap = 0; + sha1[swap] = ent[0].item->sha1; + sha1[1-swap] = ent[1].item->sha1; + diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt); + log_tree_diff_flush(revs); + return 0; +} + +static void add_head(struct rev_info *revs) +{ + unsigned char sha1[20]; + struct object *obj; + if (get_sha1("HEAD", sha1)) + return; + obj = parse_object(sha1); + if (!obj) + return; + add_object(obj, &revs->pending_objects, NULL, "HEAD"); +} + +int cmd_diff(int argc, const char **argv, char **envp) +{ + struct rev_info rev; + struct object_list *list, ent[2]; + int ents = 0, blobs = 0, paths = 0; + const char *path = NULL; + struct blobinfo blob[2]; + + /* + * We could get N tree-ish in the rev.pending_objects list. + * Also there could be M blobs there, and P pathspecs. + * + * N=0, M=0: + * cache vs files (diff-files) + * N=0, M=2: + * compare two random blobs. P must be zero. + * N=0, M=1, P=1: + * compare a blob with a working tree file. + * + * N=1, M=0: + * tree vs cache (diff-index --cached) + * + * N=2, M=0: + * tree vs tree (diff-tree) + * + * Other cases are errors. + */ + + git_config(git_diff_config); + init_revisions(&rev); + rev.diffopt.output_format = DIFF_FORMAT_PATCH; + + argc = setup_revisions(argc, argv, &rev, NULL); + /* Do we have --cached and not have a pending object, then + * default to HEAD by hand. Eek. + */ + if (!rev.pending_objects) { + int i; + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, "--")) + break; + else if (!strcmp(arg, "--cached")) { + add_head(&rev); + break; + } + } + } + + for (list = rev.pending_objects; list; list = list->next) { + struct object *obj = list->item; + const char *name = list->name; + int flags = (obj->flags & UNINTERESTING); + if (!obj->parsed) + obj = parse_object(obj->sha1); + obj = deref_tag(obj, NULL, 0); + if (!obj) + die("invalid object '%s' given.", name); + if (!strcmp(obj->type, commit_type)) + obj = &((struct commit *)obj)->tree->object; + if (!strcmp(obj->type, tree_type)) { + if (2 <= ents) + die("more than two trees given: '%s'", name); + obj->flags |= flags; + ent[ents].item = obj; + ent[ents].name = name; + ents++; + continue; + } + if (!strcmp(obj->type, blob_type)) { + if (2 <= blobs) + die("more than two blobs given: '%s'", name); + memcpy(blob[blobs].sha1, obj->sha1, 20); + blob[blobs].name = name; + blobs++; + continue; + + } + die("unhandled object '%s' given.", name); + } + if (rev.prune_data) { + const char **pathspec = rev.prune_data; + while (*pathspec) { + if (!path) + path = *pathspec; + paths++; + pathspec++; + } + } + + /* + * Now, do the arguments look reasonable? + */ + if (!ents) { + switch (blobs) { + case 0: + return builtin_diff_files(&rev, argc, argv); + break; + case 1: + if (paths != 1) + usage(builtin_diff_usage); + return builtin_diff_b_f(&rev, argc, argv, blob, path); + break; + case 2: + return builtin_diff_blobs(&rev, argc, argv, blob); + break; + default: + usage(builtin_diff_usage); + } + } + else if (blobs) + usage(builtin_diff_usage); + else if (ents == 1) + return builtin_diff_index(&rev, argc, argv); + else if (ents == 2) + return builtin_diff_tree(&rev, argc, argv, ent); + usage(builtin_diff_usage); +} diff --git a/builtin.h b/builtin.h index 47408a0585..52ffa526f8 100644 --- a/builtin.h +++ b/builtin.h @@ -19,5 +19,6 @@ extern int cmd_version(int argc, const char **argv, char **envp); extern int cmd_whatchanged(int argc, const char **argv, char **envp); extern int cmd_show(int argc, const char **argv, char **envp); extern int cmd_log(int argc, const char **argv, char **envp); +extern int cmd_diff(int argc, const char **argv, char **envp); #endif diff --git a/git.c b/git.c index 01b7e28b8c..ff9b87abbc 100644 --- a/git.c +++ b/git.c @@ -46,6 +46,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, + { "diffn", cmd_diff }, }; int i; -- cgit 1.2.3-korg From 755225de6ce4c7b39137afefb35208d0dbc14d9d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 29 Apr 2006 21:22:49 -0700 Subject: git builtin "push" This adds a builtin "push" command, which is largely just a C'ification of the "git-push.sh" script. Now, the reason I did it as a built-in is partly because it's yet another step on relying less on shell, but it's actually mostly because I've wanted to be able to push to _multiple_ repositories, and the most obvious and simplest interface for that would seem be to just have a "remotes" file that has multiple URL entries. (For "pull", having multiple entries should either just select the first one, or you could fall back on the others on failure - your choice). And quite frankly, it just became too damn messy to do that in shell. Besides, we actually have a fair amount of infrastructure in C, so it just wasn't that hard to do. Of course, this is almost totally untested. It probably doesn't work for anything but the one trial I threw at it. "Simple" doesn't necessarily mean "obviously correct". Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- Makefile | 2 +- builtin-push.c | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 2 + git.c | 1 + 4 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 builtin-push.c (limited to 'git.c') diff --git a/Makefile b/Makefile index 8ce27a65fb..9919992392 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ LIB_OBJS = \ $(DIFF_OBJS) BUILTIN_OBJS = \ - builtin-log.o builtin-help.o + builtin-log.o builtin-help.o builtin-push.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-push.c b/builtin-push.c new file mode 100644 index 0000000000..a0c1caab52 --- /dev/null +++ b/builtin-push.c @@ -0,0 +1,255 @@ +/* + * "git push" + */ +#include "cache.h" +#include "refs.h" +#include "run-command.h" +#include "builtin.h" + +#define MAX_URI (16) + +static const char push_usage[] = "git push [--all] [--tags] [--force] [...]"; + +static int all = 0, tags = 0, force = 0, thin = 1; +static const char *execute = NULL; + +#define BUF_SIZE (2084) +static char buffer[BUF_SIZE]; + +static const char **refspec = NULL; +static int refspec_nr = 0; + +static void add_refspec(const char *ref) +{ + int nr = refspec_nr + 1; + refspec = xrealloc(refspec, nr * sizeof(char *)); + refspec[nr-1] = ref; + refspec_nr = nr; +} + +static int expand_one_ref(const char *ref, const unsigned char *sha1) +{ + /* Ignore the "refs/" at the beginning of the refname */ + ref += 5; + + if (strncmp(ref, "tags/", 5)) + return 0; + + add_refspec(strdup(ref)); + return 0; +} + +static void expand_refspecs(void) +{ + if (all) { + if (refspec_nr) + die("cannot mix '--all' and a refspec"); + + /* + * No need to expand "--all" - we'll just use + * the "--all" flag to send-pack + */ + return; + } + if (!tags) + return; + for_each_ref(expand_one_ref); +} + +static void set_refspecs(const char **refs, int nr) +{ + if (nr) { + size_t bytes = nr * sizeof(char *); + + refspec = xrealloc(refspec, bytes); + memcpy(refspec, refs, bytes); + refspec_nr = nr; + } + expand_refspecs(); +} + +static int get_remotes_uri(const char *repo, const char *uri[MAX_URI]) +{ + int n = 0; + FILE *f = fopen(git_path("remotes/%s", repo), "r"); + + if (!f) + return -1; + while (fgets(buffer, BUF_SIZE, f)) { + char *s, *p; + + if (strncmp("URL: ", buffer, 5)) + continue; + s = buffer + 5; + + /* Remove whitespace at the head.. */ + while (isspace(*s)) + s++; + if (!*s) + continue; + + /* ..and at the end */ + p = s + strlen(s); + while (isspace(p[-1])) + *--p = 0; + + uri[n++] = strdup(s); + if (n == MAX_URI) + break; + } + fclose(f); + if (!n) + die("remote '%s' has no URL", repo); + return n; +} + +static int get_branches_uri(const char *repo, const char *uri[MAX_URI]) +{ + const char *slash = strchr(repo, '/'); + int n = slash ? slash - repo : 1000; + FILE *f = fopen(git_path("branches/%.*s", n, repo), "r"); + char *s, *p; + int len; + + if (!f) + return 0; + s = fgets(buffer, BUF_SIZE, f); + fclose(f); + if (!s) + return 0; + while (isspace(*s)) + s++; + if (!*s) + return 0; + p = s + strlen(s); + while (isspace(p[-1])) + *--p = 0; + len = p - s; + if (slash) + len += strlen(slash); + p = xmalloc(len + 1); + strcpy(p, s); + if (slash) + strcat(p, slash); + uri[0] = p; + return 1; +} + +static int get_uri(const char *repo, const char *uri[MAX_URI]) +{ + int n; + + if (*repo != '/') { + n = get_remotes_uri(repo, uri); + if (n > 0) + return n; + + n = get_branches_uri(repo, uri); + if (n > 0) + return n; + } + + uri[0] = repo; + return 1; +} + +static int do_push(const char *repo) +{ + const char *uri[MAX_URI]; + int i, n = get_uri(repo, uri); + int remote; + const char **argv; + int argc; + + n = get_uri(repo, uri); + if (n <= 0) + die("bad repository '%s'", repo); + + argv = xmalloc((refspec_nr + 10) * sizeof(char *)); + argv[0] = "dummy-send-pack"; + argc = 1; + if (all) + argv[argc++] = "--all"; + if (force) + argv[argc++] = "--force"; + if (execute) + argv[argc++] = execute; + if (thin) + argv[argc++] = "--thin"; + remote = argc; + argv[argc++] = "dummy-remote"; + while (refspec_nr--) + argv[argc++] = *refspec++; + argv[argc] = NULL; + + for (i = 0; i < n; i++) { + int error; + const char *dest = uri[i]; + const char *sender = "git-send-pack"; + if (!strncmp(dest, "http://", 7) || + !strncmp(dest, "https://", 8)) + sender = "git-http-push"; + argv[0] = sender; + argv[remote] = dest; + error = run_command_v(argc, argv); + if (!error) + continue; + switch (error) { + case -ERR_RUN_COMMAND_FORK: + die("unable to fork for %s", sender); + case -ERR_RUN_COMMAND_EXEC: + die("unable to exec %s", sender); + case -ERR_RUN_COMMAND_WAITPID: + case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: + case -ERR_RUN_COMMAND_WAITPID_SIGNAL: + case -ERR_RUN_COMMAND_WAITPID_NOEXIT: + die("%s died with strange error", sender); + default: + return -error; + } + } + return 0; +} + +int cmd_push(int argc, const char **argv, char **envp) +{ + int i; + const char *repo = "origin"; // default repository + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + + if (arg[0] != '-') { + repo = arg; + i++; + break; + } + if (!strcmp(arg, "--all")) { + all = 1; + continue; + } + if (!strcmp(arg, "--tags")) { + tags = 1; + continue; + } + if (!strcmp(arg, "--force")) { + force = 1; + continue; + } + if (!strcmp(arg, "--thin")) { + thin = 1; + continue; + } + if (!strcmp(arg, "--no-thin")) { + thin = 0; + continue; + } + if (!strncmp(arg, "--exec=", 7)) { + execute = arg; + continue; + } + usage(push_usage); + } + set_refspecs(argv + i, argc - i); + return do_push(repo); +} diff --git a/builtin.h b/builtin.h index 47408a0585..94fa9b5465 100644 --- a/builtin.h +++ b/builtin.h @@ -20,4 +20,6 @@ extern int cmd_whatchanged(int argc, const char **argv, char **envp); extern int cmd_show(int argc, const char **argv, char **envp); extern int cmd_log(int argc, const char **argv, char **envp); +extern int cmd_push(int argc, const char **argv, char **envp); + #endif diff --git a/git.c b/git.c index 01b7e28b8c..fd479e97c1 100644 --- a/git.c +++ b/git.c @@ -46,6 +46,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, + { "push", cmd_push }, }; int i; -- cgit 1.2.3-korg From 8ab99476ec2298a43e94949e0bb7aa5125793a28 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 1 May 2006 22:58:18 -0700 Subject: builtin-diff: call it "git-diff", really. Call it "git diff" not "git diffn", remove the shell script version, and hardlink the git binary to it. Signed-off-by: Junio C Hamano --- Makefile | 5 +++-- git-diff.sh | 74 ------------------------------------------------------------- git.c | 2 +- 3 files changed, 4 insertions(+), 77 deletions(-) delete mode 100755 git-diff.sh (limited to 'git.c') diff --git a/Makefile b/Makefile index 277c1ac079..47b165e301 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ SCRIPT_SH = \ git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \ git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \ - git-count-objects.sh git-diff.sh git-fetch.sh \ + git-count-objects.sh git-fetch.sh \ git-format-patch.sh git-ls-remote.sh \ git-merge-one-file.sh git-parse-remote.sh \ git-prune.sh git-pull.sh git-push.sh git-rebase.sh \ @@ -167,7 +167,8 @@ PROGRAMS = \ git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X -BUILT_INS = git-log$X +BUILT_INS = git-log$X \ + git-diff$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) diff --git a/git-diff.sh b/git-diff.sh deleted file mode 100755 index 0fe6770749..0000000000 --- a/git-diff.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# Copyright (c) 2005 Junio C Hamano - -USAGE='[ --diff-options ] {0,2} [...]' -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -rev=$(git-rev-parse --revs-only --no-flags --sq "$@") || exit -flags=$(git-rev-parse --no-revs --flags --sq "$@") -files=$(git-rev-parse --no-revs --no-flags --sq "$@") - -# I often say 'git diff --cached -p' and get scolded by git-diff-files, but -# obviously I mean 'git diff --cached -p HEAD' in that case. -case "$rev" in -'') - case " $flags " in - *" '--cached' "*) - rev='HEAD ' - ;; - esac -esac - -# If we have -[123] --ours --theirs --base, don't do --cc by default. -case " $flags " in -*" '-"[123]"' "* | *" '--ours' "* | *" '--base' "* | *" '--theirs' "*) - cc_or_p=-p ;; -*) - cc_or_p=--cc ;; -esac - -# If we do not have --name-status, --name-only, -r, -c or --stat, -# default to --cc. -case " $flags " in -*" '--name-status' "* | *" '--name-only' "* | *" '-r' "* | *" '-c' "* | \ -*" '--stat' "*) - ;; -*) - flags="$flags'$cc_or_p' " ;; -esac - -# If we do not have -B, -C, -r, nor -p, default to -M. -case " $flags " in -*" '-"[BCMrp]* | *" '--find-copies-harder' "*) - ;; # something like -M50. -*) - flags="$flags'-M' " ;; -esac - -case "$rev" in -?*' '?*' '?*) - usage - ;; -?*' '^?*) - begin=$(expr "$rev" : '.*^.\([0-9a-f]*\).*') && - end=$(expr "$rev" : '.\([0-9a-f]*\). .*') || exit - cmd="git-diff-tree $flags $begin $end -- $files" - ;; -?*' '?*) - cmd="git-diff-tree $flags $rev -- $files" - ;; -?*' ') - cmd="git-diff-index $flags $rev -- $files" - ;; -'') - cmd="git-diff-files $flags -- $files" - ;; -*) - usage - ;; -esac - -eval "$cmd" diff --git a/git.c b/git.c index ff9b87abbc..e6a960a965 100644 --- a/git.c +++ b/git.c @@ -46,7 +46,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, - { "diffn", cmd_diff }, + { "diff", cmd_diff }, }; int i; -- cgit 1.2.3-korg