summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e414156)
raw | patch | inline | side by side (parent: e414156)
author | Junio C Hamano <junkio@cox.net> | |
Fri, 4 Aug 2006 08:51:04 +0000 (01:51 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Fri, 4 Aug 2006 08:51:04 +0000 (01:51 -0700) |
This cleans up the build procedure for built-in commands by:
- generating mostly redundant definition of BUILT_INS from
BUILTIN_OBJS in the Makefile,
- renaming a few files to make the above possible, and
- sorting the built-in command table in git.c.
It might be a good idea to binary search (or perfect hash) the built-in
command table, but that can be done later when somebody feels like.
Signed-off-by: Junio C Hamano <junkio@cox.net>
- generating mostly redundant definition of BUILT_INS from
BUILTIN_OBJS in the Makefile,
- renaming a few files to make the above possible, and
- sorting the built-in command table in git.c.
It might be a good idea to binary search (or perfect hash) the built-in
command table, but that can be done later when somebody feels like.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Makefile | patch | blob | history | |
builtin-count-objects.c | [new file with mode: 0644] | patch | blob |
builtin-count.c | [deleted file] | patch | blob | history |
builtin-help.c | [deleted file] | patch | blob | history |
builtin.h | patch | blob | history | |
git.c | patch | blob | history | |
help.c | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index 1a3605b1236d6bf90436655ec60299ca59c48565..dc39f72f1eb8b3a05c03ffe16e62b056924cf573 100644 (file)
--- a/Makefile
+++ b/Makefile
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
BUILT_INS = \
- git-checkout-index$X \
- git-log$X git-whatchanged$X git-show$X git-update-ref$X \
- git-count-objects$X git-diff$X git-push$X git-mailsplit$X \
- git-grep$X git-add$X git-rm$X git-rev-list$X git-stripspace$X \
- git-check-ref-format$X git-rev-parse$X git-mailinfo$X \
- git-init-db$X git-tar-tree$X git-upload-tar$X git-format-patch$X \
- git-ls-files$X git-ls-tree$X git-get-tar-commit-id$X \
- git-read-tree$X git-commit-tree$X git-write-tree$X \
- git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \
- git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \
- git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \
- git-repo-config$X git-name-rev$X git-pack-objects$X \
- git-unpack-objects$X git-symbolic-ref$X
+ git-format-patch$X git-show$X git-whatchanged$X \
+ git-get-tar-commit-id$X \
+ $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
blob.h cache.h commit.h csum-file.h delta.h \
diff.h object.h pack.h pkt-line.h quote.h refs.h \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
- tree-walk.h log-tree.h dir.h path-list.h
+ tree-walk.h log-tree.h dir.h path-list.h builtin.h
DIFF_OBJS = \
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
- alloc.o merge-file.o path-list.o $(DIFF_OBJS)
+ alloc.o merge-file.o path-list.o help.o $(DIFF_OBJS)
BUILTIN_OBJS = \
+ builtin-add.o \
+ builtin-apply.o \
+ builtin-cat-file.o \
builtin-checkout-index.o \
- builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
- builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \
- builtin-rm.o builtin-init-db.o builtin-rev-parse.o \
- builtin-tar-tree.o builtin-upload-tar.o builtin-update-index.o \
- builtin-ls-files.o builtin-ls-tree.o builtin-write-tree.o \
- builtin-read-tree.o builtin-commit-tree.o builtin-mailinfo.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-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
- builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
- builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \
- builtin-name-rev.o builtin-pack-objects.o builtin-unpack-objects.o \
- builtin-symbolic-ref.o
+ builtin-check-ref-format.o \
+ builtin-commit-tree.o \
+ builtin-count-objects.o \
+ builtin-diff.o \
+ builtin-diff-files.o \
+ builtin-diff-index.o \
+ builtin-diff-stages.o \
+ builtin-diff-tree.o \
+ builtin-fmt-merge-msg.o \
+ builtin-grep.o \
+ builtin-init-db.o \
+ builtin-log.o \
+ builtin-ls-files.o \
+ builtin-ls-tree.o \
+ builtin-mailinfo.o \
+ builtin-mailsplit.o \
+ builtin-mv.o \
+ builtin-name-rev.o \
+ builtin-pack-objects.o \
+ builtin-prune.o \
+ builtin-prune-packed.o \
+ builtin-push.o \
+ builtin-read-tree.o \
+ builtin-repo-config.o \
+ builtin-rev-list.o \
+ builtin-rev-parse.o \
+ builtin-rm.o \
+ builtin-show-branch.o \
+ builtin-stripspace.o \
+ builtin-symbolic-ref.o \
+ builtin-tar-tree.o \
+ builtin-unpack-objects.o \
+ builtin-update-index.o \
+ builtin-update-ref.o \
+ builtin-upload-tar.o \
+ builtin-write-tree.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
-builtin-help.o: common-cmds.h
+help.o: common-cmds.h
$(BUILT_INS): git$X
rm -f $@ && ln git$X $@
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
--- /dev/null
+++ b/builtin-count-objects.c
@@ -0,0 +1,125 @@
+/*
+ * 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, const char *prefix)
+{
+ 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;
+ if (!packed_git)
+ prepare_packed_git();
+ 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-count.c b/builtin-count.c
--- a/builtin-count.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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, const char *prefix)
-{
- 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;
- if (!packed_git)
- prepare_packed_git();
- 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-help.c b/builtin-help.c
--- a/builtin-help.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * builtin-help.c
- *
- * Builtin help-related commands (help, usage, version)
- */
-#include <sys/ioctl.h>
-#include "cache.h"
-#include "builtin.h"
-#include "exec_cmd.h"
-#include "common-cmds.h"
-
-
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
-{
- char *col_string = getenv("COLUMNS");
- int n_cols = 0;
-
- if (col_string && (n_cols = atoi(col_string)) > 0)
- return n_cols;
-
-#ifdef TIOCGWINSZ
- {
- struct winsize ws;
- if (!ioctl(1, TIOCGWINSZ, &ws)) {
- if (ws.ws_col)
- return ws.ws_col;
- }
- }
-#endif
-
- return 80;
-}
-
-static void oom(void)
-{
- fprintf(stderr, "git: out of memory\n");
- exit(1);
-}
-
-static inline void mput_char(char c, unsigned int num)
-{
- while(num--)
- putchar(c);
-}
-
-static struct cmdname {
- size_t len;
- char name[1];
-} **cmdname;
-static int cmdname_alloc, cmdname_cnt;
-
-static void add_cmdname(const char *name, int len)
-{
- struct cmdname *ent;
- if (cmdname_alloc <= cmdname_cnt) {
- cmdname_alloc = cmdname_alloc + 200;
- cmdname = realloc(cmdname, cmdname_alloc * sizeof(*cmdname));
- if (!cmdname)
- oom();
- }
- ent = malloc(sizeof(*ent) + len);
- if (!ent)
- oom();
- ent->len = len;
- memcpy(ent->name, name, len);
- ent->name[len] = 0;
- cmdname[cmdname_cnt++] = ent;
-}
-
-static int cmdname_compare(const void *a_, const void *b_)
-{
- struct cmdname *a = *(struct cmdname **)a_;
- struct cmdname *b = *(struct cmdname **)b_;
- return strcmp(a->name, b->name);
-}
-
-static void pretty_print_string_list(struct cmdname **cmdname, int longest)
-{
- int cols = 1, rows;
- int space = longest + 1; /* min 1 SP between words */
- int max_cols = term_columns() - 1; /* don't print *on* the edge */
- int i, j;
-
- if (space < max_cols)
- cols = max_cols / space;
- rows = (cmdname_cnt + cols - 1) / cols;
-
- qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);
-
- for (i = 0; i < rows; i++) {
- printf(" ");
-
- for (j = 0; j < cols; j++) {
- int n = j * rows + i;
- int size = space;
- if (n >= cmdname_cnt)
- break;
- if (j == cols-1 || n + rows >= cmdname_cnt)
- size = 1;
- printf("%-*s", size, cmdname[n]->name);
- }
- putchar('\n');
- }
-}
-
-static void list_commands(const char *exec_path, const char *pattern)
-{
- unsigned int longest = 0;
- char path[PATH_MAX];
- int dirlen;
- DIR *dir = opendir(exec_path);
- struct dirent *de;
-
- if (!dir) {
- fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno));
- exit(1);
- }
-
- dirlen = strlen(exec_path);
- if (PATH_MAX - 20 < dirlen) {
- fprintf(stderr, "git: insanely long exec-path '%s'\n",
- exec_path);
- exit(1);
- }
-
- memcpy(path, exec_path, dirlen);
- path[dirlen++] = '/';
-
- while ((de = readdir(dir)) != NULL) {
- struct stat st;
- int entlen;
-
- if (strncmp(de->d_name, "git-", 4))
- continue;
- strcpy(path+dirlen, de->d_name);
- if (stat(path, &st) || /* stat, not lstat */
- !S_ISREG(st.st_mode) ||
- !(st.st_mode & S_IXUSR))
- continue;
-
- entlen = strlen(de->d_name);
- if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
- entlen -= 4;
-
- if (longest < entlen)
- longest = entlen;
-
- add_cmdname(de->d_name + 4, entlen-4);
- }
- closedir(dir);
-
- printf("git commands available in '%s'\n", exec_path);
- printf("----------------------------");
- mput_char('-', strlen(exec_path));
- putchar('\n');
- pretty_print_string_list(cmdname, longest - 4);
- putchar('\n');
-}
-
-static void list_common_cmds_help(void)
-{
- int i, longest = 0;
-
- for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
- if (longest < strlen(common_cmds[i].name))
- longest = strlen(common_cmds[i].name);
- }
-
- puts("The most commonly used git commands are:");
- for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
- printf(" %s", common_cmds[i].name);
- mput_char(' ', longest - strlen(common_cmds[i].name) + 4);
- puts(common_cmds[i].help);
- }
- puts("(use 'git help -a' to get a list of all installed git commands)");
-}
-
-static void show_man_page(const char *git_cmd)
-{
- const char *page;
-
- if (!strncmp(git_cmd, "git", 3))
- page = git_cmd;
- else {
- int page_len = strlen(git_cmd) + 4;
- char *p = malloc(page_len + 1);
- strcpy(p, "git-");
- strcpy(p + 4, git_cmd);
- p[page_len] = 0;
- page = p;
- }
-
- execlp("man", "man", page, NULL);
-}
-
-void help_unknown_cmd(const char *cmd)
-{
- printf("git: '%s' is not a git-command\n\n", cmd);
- list_common_cmds_help();
- exit(1);
-}
-
-int cmd_version(int argc, const char **argv, const char *prefix)
-{
- printf("git version %s\n", git_version_string);
- return 0;
-}
-
-int cmd_help(int argc, const char **argv, const char *prefix)
-{
- const char *help_cmd = argc > 1 ? argv[1] : NULL;
- const char *exec_path = git_exec_path();
-
- if (!help_cmd) {
- printf("usage: %s\n\n", git_usage_string);
- list_common_cmds_help();
- exit(1);
- }
-
- else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
- printf("usage: %s\n\n", git_usage_string);
- if(exec_path)
- list_commands(exec_path, "git-*");
- exit(1);
- }
-
- else
- show_man_page(help_cmd);
-
- return 0;
-}
-
-
diff --git a/builtin.h b/builtin.h
index 3a24637b11d11b1014b5ea3b6927d47e9c0b50fe..c0bdb051bd07775898e7e3a118956024eeb86d78 100644 (file)
--- a/builtin.h
+++ b/builtin.h
extern const char git_usage_string[];
extern void help_unknown_cmd(const char *cmd);
+extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
+extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
+extern void stripspace(FILE *in, FILE *out);
+extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
-extern int cmd_help(int argc, const char **argv, const char *prefix);
-extern int cmd_version(int argc, const char **argv, const char *prefix);
-
-extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
-extern int cmd_show(int argc, const char **argv, const char *prefix);
-extern int cmd_log(int argc, const char **argv, const char *prefix);
-extern int cmd_diff(int argc, const char **argv, const char *prefix);
-extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
-extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
-
-extern int cmd_prune(int argc, const char **argv, const char *prefix);
-extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
-
-extern int cmd_push(int argc, const char **argv, const char *prefix);
-extern int cmd_grep(int argc, const char **argv, const char *prefix);
-extern int cmd_rm(int argc, const char **argv, const char *prefix);
extern int cmd_add(int argc, const char **argv, const char *prefix);
-extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
+extern int cmd_apply(int argc, const char **argv, const char *prefix);
+extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
+extern int cmd_checkout_index(int argc, const char **argv, const char *prefix);
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
-extern int cmd_init_db(int argc, const char **argv, const char *prefix);
-extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
-extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
-extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
-extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
-extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
-extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
-extern int cmd_apply(int argc, const char **argv, const char *prefix);
-extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
+extern int cmd_diff(int argc, const char **argv, const char *prefix);
extern int cmd_diff_stages(int argc, const char **argv, const char *prefix);
extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
-extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
-extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
-extern int cmd_update_index(int argc, const char **argv, const char *prefix);
-extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
+extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
+extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
+extern int cmd_grep(int argc, const char **argv, const char *prefix);
+extern int cmd_help(int argc, const char **argv, const char *prefix);
+extern int cmd_init_db(int argc, const char **argv, const char *prefix);
+extern int cmd_log(int argc, const char **argv, const char *prefix);
+extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
+extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
+extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
extern int cmd_mv(int argc, const char **argv, const char *prefix);
-extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);
-extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_prune(int argc, const char **argv, const char *prefix);
+extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
+extern int cmd_push(int argc, const char **argv, const char *prefix);
+extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
+extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
+extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
+extern int cmd_rm(int argc, const char **argv, const char *prefix);
+extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_show(int argc, const char **argv, const char *prefix);
+extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
-extern int cmd_checkout_index(int argc, const char **argv, const char *prefix);
-
+extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_update_index(int argc, const char **argv, const char *prefix);
+extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
+extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
+extern int cmd_version(int argc, const char **argv, const char *prefix);
+extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
-extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
-
-extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
-extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
-extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
-extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
-
-extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
-extern void stripspace(FILE *in, FILE *out);
#endif
index 07b6d3e9ddb63c09781677c89e1d2d5e837ce0f7..754db1a2ee91dd78277ad11fab3c8c620bb12815 100644 (file)
--- a/git.c
+++ b/git.c
int (*fn)(int, const char **, const char *);
int option;
} commands[] = {
- { "version", cmd_version },
- { "help", cmd_help },
- { "log", cmd_log, NEEDS_PREFIX | USE_PAGER },
- { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER },
- { "show", cmd_show, NEEDS_PREFIX | USE_PAGER },
- { "push", cmd_push },
- { "format-patch", cmd_format_patch, NEEDS_PREFIX },
- { "count-objects", cmd_count_objects },
- { "diff", cmd_diff, NEEDS_PREFIX },
- { "grep", cmd_grep, NEEDS_PREFIX },
- { "rm", cmd_rm, NEEDS_PREFIX },
{ "add", cmd_add, NEEDS_PREFIX },
- { "rev-list", cmd_rev_list, NEEDS_PREFIX },
- { "init-db", cmd_init_db },
- { "get-tar-commit-id", cmd_get_tar_commit_id },
- { "upload-tar", cmd_upload_tar },
+ { "apply", cmd_apply },
+ { "cat-file", cmd_cat_file, NEEDS_PREFIX },
+ { "checkout-index", cmd_checkout_index, NEEDS_PREFIX },
{ "check-ref-format", cmd_check_ref_format },
- { "ls-files", cmd_ls_files, NEEDS_PREFIX },
- { "ls-tree", cmd_ls_tree, NEEDS_PREFIX },
- { "tar-tree", cmd_tar_tree, NEEDS_PREFIX },
- { "read-tree", cmd_read_tree, NEEDS_PREFIX },
{ "commit-tree", cmd_commit_tree, NEEDS_PREFIX },
- { "apply", cmd_apply },
- { "show-branch", cmd_show_branch, NEEDS_PREFIX },
+ { "count-objects", cmd_count_objects },
+ { "diff", cmd_diff, NEEDS_PREFIX },
{ "diff-files", cmd_diff_files, NEEDS_PREFIX },
{ "diff-index", cmd_diff_index, NEEDS_PREFIX },
{ "diff-stages", cmd_diff_stages, NEEDS_PREFIX },
{ "diff-tree", cmd_diff_tree, NEEDS_PREFIX },
- { "cat-file", cmd_cat_file, NEEDS_PREFIX },
- { "rev-parse", cmd_rev_parse, NEEDS_PREFIX },
- { "write-tree", cmd_write_tree, NEEDS_PREFIX },
- { "mailsplit", cmd_mailsplit },
- { "mailinfo", cmd_mailinfo },
- { "stripspace", cmd_stripspace },
- { "update-index", cmd_update_index, NEEDS_PREFIX },
- { "update-ref", cmd_update_ref, NEEDS_PREFIX },
{ "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX },
- { "prune", cmd_prune, NEEDS_PREFIX },
+ { "format-patch", cmd_format_patch, NEEDS_PREFIX },
+ { "get-tar-commit-id", cmd_get_tar_commit_id },
+ { "grep", cmd_grep, NEEDS_PREFIX },
+ { "help", cmd_help },
+ { "init-db", cmd_init_db },
+ { "log", cmd_log, NEEDS_PREFIX | USE_PAGER },
+ { "ls-files", cmd_ls_files, NEEDS_PREFIX },
+ { "ls-tree", cmd_ls_tree, NEEDS_PREFIX },
+ { "mailinfo", cmd_mailinfo },
+ { "mailsplit", cmd_mailsplit },
{ "mv", cmd_mv, NEEDS_PREFIX },
- { "prune-packed", cmd_prune_packed, NEEDS_PREFIX },
- { "repo-config", cmd_repo_config },
{ "name-rev", cmd_name_rev, NEEDS_PREFIX },
{ "pack-objects", cmd_pack_objects, NEEDS_PREFIX },
- { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX },
+ { "prune", cmd_prune, NEEDS_PREFIX },
+ { "prune-packed", cmd_prune_packed, NEEDS_PREFIX },
+ { "push", cmd_push },
+ { "read-tree", cmd_read_tree, NEEDS_PREFIX },
+ { "repo-config", cmd_repo_config },
+ { "rev-list", cmd_rev_list, NEEDS_PREFIX },
+ { "rev-parse", cmd_rev_parse, NEEDS_PREFIX },
+ { "rm", cmd_rm, NEEDS_PREFIX },
+ { "show-branch", cmd_show_branch, NEEDS_PREFIX },
+ { "show", cmd_show, NEEDS_PREFIX | USE_PAGER },
+ { "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, NEEDS_PREFIX },
- { "checkout-index", cmd_checkout_index, NEEDS_PREFIX },
+ { "tar-tree", cmd_tar_tree, NEEDS_PREFIX },
+ { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX },
+ { "update-index", cmd_update_index, NEEDS_PREFIX },
+ { "update-ref", cmd_update_ref, NEEDS_PREFIX },
+ { "upload-tar", cmd_upload_tar },
+ { "version", cmd_version },
+ { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER },
+ { "write-tree", cmd_write_tree, NEEDS_PREFIX },
};
int i;
diff --git a/help.c b/help.c
--- /dev/null
+++ b/help.c
@@ -0,0 +1,234 @@
+/*
+ * builtin-help.c
+ *
+ * Builtin help-related commands (help, usage, version)
+ */
+#include <sys/ioctl.h>
+#include "cache.h"
+#include "builtin.h"
+#include "exec_cmd.h"
+#include "common-cmds.h"
+
+
+/* most GUI terminals set COLUMNS (although some don't export it) */
+static int term_columns(void)
+{
+ char *col_string = getenv("COLUMNS");
+ int n_cols = 0;
+
+ if (col_string && (n_cols = atoi(col_string)) > 0)
+ return n_cols;
+
+#ifdef TIOCGWINSZ
+ {
+ struct winsize ws;
+ if (!ioctl(1, TIOCGWINSZ, &ws)) {
+ if (ws.ws_col)
+ return ws.ws_col;
+ }
+ }
+#endif
+
+ return 80;
+}
+
+static void oom(void)
+{
+ fprintf(stderr, "git: out of memory\n");
+ exit(1);
+}
+
+static inline void mput_char(char c, unsigned int num)
+{
+ while(num--)
+ putchar(c);
+}
+
+static struct cmdname {
+ size_t len;
+ char name[1];
+} **cmdname;
+static int cmdname_alloc, cmdname_cnt;
+
+static void add_cmdname(const char *name, int len)
+{
+ struct cmdname *ent;
+ if (cmdname_alloc <= cmdname_cnt) {
+ cmdname_alloc = cmdname_alloc + 200;
+ cmdname = realloc(cmdname, cmdname_alloc * sizeof(*cmdname));
+ if (!cmdname)
+ oom();
+ }
+ ent = malloc(sizeof(*ent) + len);
+ if (!ent)
+ oom();
+ ent->len = len;
+ memcpy(ent->name, name, len);
+ ent->name[len] = 0;
+ cmdname[cmdname_cnt++] = ent;
+}
+
+static int cmdname_compare(const void *a_, const void *b_)
+{
+ struct cmdname *a = *(struct cmdname **)a_;
+ struct cmdname *b = *(struct cmdname **)b_;
+ return strcmp(a->name, b->name);
+}
+
+static void pretty_print_string_list(struct cmdname **cmdname, int longest)
+{
+ int cols = 1, rows;
+ int space = longest + 1; /* min 1 SP between words */
+ int max_cols = term_columns() - 1; /* don't print *on* the edge */
+ int i, j;
+
+ if (space < max_cols)
+ cols = max_cols / space;
+ rows = (cmdname_cnt + cols - 1) / cols;
+
+ qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);
+
+ for (i = 0; i < rows; i++) {
+ printf(" ");
+
+ for (j = 0; j < cols; j++) {
+ int n = j * rows + i;
+ int size = space;
+ if (n >= cmdname_cnt)
+ break;
+ if (j == cols-1 || n + rows >= cmdname_cnt)
+ size = 1;
+ printf("%-*s", size, cmdname[n]->name);
+ }
+ putchar('\n');
+ }
+}
+
+static void list_commands(const char *exec_path, const char *pattern)
+{
+ unsigned int longest = 0;
+ char path[PATH_MAX];
+ int dirlen;
+ DIR *dir = opendir(exec_path);
+ struct dirent *de;
+
+ if (!dir) {
+ fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno));
+ exit(1);
+ }
+
+ dirlen = strlen(exec_path);
+ if (PATH_MAX - 20 < dirlen) {
+ fprintf(stderr, "git: insanely long exec-path '%s'\n",
+ exec_path);
+ exit(1);
+ }
+
+ memcpy(path, exec_path, dirlen);
+ path[dirlen++] = '/';
+
+ while ((de = readdir(dir)) != NULL) {
+ struct stat st;
+ int entlen;
+
+ if (strncmp(de->d_name, "git-", 4))
+ continue;
+ strcpy(path+dirlen, de->d_name);
+ if (stat(path, &st) || /* stat, not lstat */
+ !S_ISREG(st.st_mode) ||
+ !(st.st_mode & S_IXUSR))
+ continue;
+
+ entlen = strlen(de->d_name);
+ if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
+ entlen -= 4;
+
+ if (longest < entlen)
+ longest = entlen;
+
+ add_cmdname(de->d_name + 4, entlen-4);
+ }
+ closedir(dir);
+
+ printf("git commands available in '%s'\n", exec_path);
+ printf("----------------------------");
+ mput_char('-', strlen(exec_path));
+ putchar('\n');
+ pretty_print_string_list(cmdname, longest - 4);
+ putchar('\n');
+}
+
+static void list_common_cmds_help(void)
+{
+ int i, longest = 0;
+
+ for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
+ if (longest < strlen(common_cmds[i].name))
+ longest = strlen(common_cmds[i].name);
+ }
+
+ puts("The most commonly used git commands are:");
+ for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
+ printf(" %s", common_cmds[i].name);
+ mput_char(' ', longest - strlen(common_cmds[i].name) + 4);
+ puts(common_cmds[i].help);
+ }
+ puts("(use 'git help -a' to get a list of all installed git commands)");
+}
+
+static void show_man_page(const char *git_cmd)
+{
+ const char *page;
+
+ if (!strncmp(git_cmd, "git", 3))
+ page = git_cmd;
+ else {
+ int page_len = strlen(git_cmd) + 4;
+ char *p = malloc(page_len + 1);
+ strcpy(p, "git-");
+ strcpy(p + 4, git_cmd);
+ p[page_len] = 0;
+ page = p;
+ }
+
+ execlp("man", "man", page, NULL);
+}
+
+void help_unknown_cmd(const char *cmd)
+{
+ printf("git: '%s' is not a git-command\n\n", cmd);
+ list_common_cmds_help();
+ exit(1);
+}
+
+int cmd_version(int argc, const char **argv, const char *prefix)
+{
+ printf("git version %s\n", git_version_string);
+ return 0;
+}
+
+int cmd_help(int argc, const char **argv, const char *prefix)
+{
+ const char *help_cmd = argc > 1 ? argv[1] : NULL;
+ const char *exec_path = git_exec_path();
+
+ if (!help_cmd) {
+ printf("usage: %s\n\n", git_usage_string);
+ list_common_cmds_help();
+ exit(1);
+ }
+
+ else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
+ printf("usage: %s\n\n", git_usage_string);
+ if(exec_path)
+ list_commands(exec_path, "git-*");
+ exit(1);
+ }
+
+ else
+ show_man_page(help_cmd);
+
+ return 0;
+}
+
+