* [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two @ 2005-11-16 0:23 Andreas Ericsson 2005-11-16 3:45 ` H. Peter Anvin 0 siblings, 1 reply; 9+ messages in thread From: Andreas Ericsson @ 2005-11-16 0:23 UTC (permalink / raw) To: git It's by design a bit stupid (matching ^git rather than ^git-), so as to work with 'gitk' and 'git' as well. Signed-off-by: Andreas Ericsson <ae@op5.se> --- Documentation/git.txt | 2 ++ git.c | 26 ++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) applies-to: 8a47ae8a825ab0e68ac46392bccd1ec16df39456 53e2024f89514d31a45936e3596e3d285dfd1bfe diff --git a/Documentation/git.txt b/Documentation/git.txt index 91e9f9f..7cbfaf8 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -24,6 +24,8 @@ OPTIONS --help:: prints the synopsis and a list of available commands. + If a git command is named this option will bring up the + man-page for that command. --exec-path:: path to wherever your core git programs are installed. diff --git a/git.c b/git.c index d189801..4b7cbf6 100644 --- a/git.c +++ b/git.c @@ -160,6 +160,24 @@ static void prepend_to_path(const char * setenv("PATH", path, 1); } +static void show_man_page(char *git_cmd) +{ + char *page; + + if (!strncmp(git_cmd, "git", 3)) + page = git_cmd; + else { + int page_len = strlen(git_cmd) + 4; + + page = malloc(page_len + 1); + strcpy(page, "git-"); + strcpy(page + 4, git_cmd); + page[page_len] = 0; + } + + execlp("man", "man", page, NULL); +} + int main(int argc, char **argv, char **envp) { char git_command[PATH_MAX + 1]; @@ -199,8 +217,12 @@ int main(int argc, char **argv, char **e usage(NULL, NULL); } - if (i >= argc || show_help) - usage(exec_path, NULL); + if (i >= argc || show_help) { + if (i >= argc) + usage(exec_path, NULL); + + show_man_page(argv[i]); + } /* allow relative paths, but run with exact */ if (chdir(exec_path)) { --- 0.99.9.GIT ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 0:23 [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Andreas Ericsson @ 2005-11-16 3:45 ` H. Peter Anvin 2005-11-16 6:56 ` Andreas Ericsson 2005-11-16 7:29 ` [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Junio C Hamano 0 siblings, 2 replies; 9+ messages in thread From: H. Peter Anvin @ 2005-11-16 3:45 UTC (permalink / raw) To: Andreas Ericsson; +Cc: git Andreas Ericsson wrote: > > +static void show_man_page(char *git_cmd) > +{ > + char *page; > + > + if (!strncmp(git_cmd, "git", 3)) > + page = git_cmd; > + else { > + int page_len = strlen(git_cmd) + 4; > + > + page = malloc(page_len + 1); > + strcpy(page, "git-"); > + strcpy(page + 4, git_cmd); > + page[page_len] = 0; > + } > + > + execlp("man", "man", page, NULL); > +} > + The way this made it into the actual tree was to call /usr/bin/man, but still using execlp(). This is clearly bogus. There *ARE* good reasons to use PATH resolutions for this, since man is one of the interactive commands the user may want to wrapper. So please drop PATH_TO_MAN that made it into the repository and revert to the original patch. -hpa ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 3:45 ` H. Peter Anvin @ 2005-11-16 6:56 ` Andreas Ericsson 2005-11-16 7:17 ` [PATCH] git wrapper: basic fixes Junio C Hamano 2005-11-16 7:29 ` [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Junio C Hamano 1 sibling, 1 reply; 9+ messages in thread From: Andreas Ericsson @ 2005-11-16 6:56 UTC (permalink / raw) To: git H. Peter Anvin wrote: > Andreas Ericsson wrote: >> + >> + execlp("man", "man", page, NULL); >> +} >> + > > > The way this made it into the actual tree was to call /usr/bin/man, but > still using execlp(). This is clearly bogus. There *ARE* good reasons > to use PATH resolutions for this, since man is one of the interactive > commands the user may want to wrapper. > Everyone agrees. I just brained the original implementation. > So please drop PATH_TO_MAN that made it into the repository and revert > to the original patch. > PATH_TO_MAN *was* the original. This is the updated version. I think Junio imported the wrong one by mistake, cause I sent this one specifically to fix the first one. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] git wrapper: basic fixes. 2005-11-16 6:56 ` Andreas Ericsson @ 2005-11-16 7:17 ` Junio C Hamano 2005-11-16 8:22 ` Johannes Schindelin 0 siblings, 1 reply; 9+ messages in thread From: Junio C Hamano @ 2005-11-16 7:17 UTC (permalink / raw) To: Andreas Ericsson; +Cc: git Andreas Ericsson <ae@op5.se> writes: > PATH_TO_MAN *was* the original. This is the updated version. I think > Junio imported the wrong one by mistake, cause I sent this one > specifically to fix the first one. Actually, I already had the original three in my tree before I sent out the message about problems like PATH_TO_MAN and getcwd/chdir pair, because they were not such a big deal to fix later in-tree, and I wanted to have the rest. How does this one look, on top of what we have on the "master" branch? -- >8 -- Updates to fix the nits found during the list discussion. - Lose PATH_TO_MAN; just rely on execlp() to find whereever the "man" command is installed. - Do not randomly chdir(), but concatenate to the current working directory only if the given path is not absolute. - Lose use of glob(); read from exec_path and do sorting ourselves -- it is not that much more work. Signed-off-by: Junio C Hamano <junkio@cox.net> --- git.c | 152 +++++++++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 97 insertions(+), 55 deletions(-) applies-to: 1a3192c27df352fb11cb1f430ad174ecd90a3734 7dbc2c0402d728a206d4f1bc59729bf3a5cc4455 diff --git a/git.c b/git.c index 583923d..b9b8c62 100644 --- a/git.c +++ b/git.c @@ -1,11 +1,13 @@ #include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <limits.h> #include <stdarg.h> -#include <glob.h> #ifndef PATH_MAX # define PATH_MAX 4096 @@ -14,12 +16,6 @@ static const char git_usage[] = "Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; -struct string_list { - size_t len; - char *str; - struct string_list *next; -}; - /* most gui terms set COLUMNS (although some don't export it) */ static int term_columns(void) { @@ -32,30 +28,69 @@ static int term_columns(void) 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 void pretty_print_string_list(struct string_list *list, int longest) +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+1); + 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; int space = longest + 1; /* min 1 SP between words */ int max_cols = term_columns() - 1; /* don't print *on* the edge */ + int i; if (space < max_cols) cols = max_cols / space; - while (list) { + qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare); + + for (i = 0; i < cmdname_cnt; ) { int c; printf(" "); - for (c = cols; c && list; list = list->next) { - printf("%s", list->str); + for (c = cols; c && i < cmdname_cnt; i++) { + printf("%s", cmdname[i]->name); if (--c) - mput_char(' ', space - list->len); + mput_char(' ', space - cmdname[i]->len); } putchar('\n'); } @@ -63,54 +98,53 @@ static void pretty_print_string_list(str static void list_commands(const char *exec_path, const char *pattern) { - struct string_list *list = NULL, *tail = NULL; - unsigned int longest = 0, i; - glob_t gl; + unsigned int longest = 0; + char path[PATH_MAX]; + int dirlen; + DIR *dir = opendir(exec_path); + struct dirent *de; - if (chdir(exec_path) < 0) { - printf("git: '%s': %s\n", exec_path, strerror(errno)); + if (!dir) { + fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno)); exit(1); } - i = glob(pattern, 0, NULL, &gl); - switch(i) { - case GLOB_NOSPACE: - puts("Out of memory when running glob()"); - exit(2); - case GLOB_ABORTED: - printf("'%s': Read error: %s\n", exec_path, strerror(errno)); - exit(2); - case GLOB_NOMATCH: - printf("No git commands available in '%s'.\n", exec_path); - printf("Do you need to specify --exec-path or set GIT_EXEC_PATH?\n"); + dirlen = strlen(exec_path); + if (PATH_MAX - 20 < dirlen) { + fprintf(stderr, "git: insanely long exec-path '%s'\n", + exec_path); exit(1); } - for (i = 0; i < gl.gl_pathc; i++) { - int len = strlen(gl.gl_pathv[i] + 4); + memcpy(path, exec_path, dirlen); + path[dirlen++] = '/'; + + while ((de = readdir(dir)) != NULL) { + struct stat st; + int entlen; - if (access(gl.gl_pathv[i], X_OK)) + 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; - if (longest < len) - longest = len; + entlen = strlen(de->d_name); - if (!tail) - tail = list = malloc(sizeof(struct string_list)); - else { - tail->next = malloc(sizeof(struct string_list)); - tail = tail->next; - } - tail->len = len; - tail->str = gl.gl_pathv[i] + 4; - tail->next = NULL; + 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(list, longest); + pretty_print_string_list(cmdname, longest - 4); putchar('\n'); } @@ -146,7 +180,7 @@ static void prepend_to_path(const char * int path_len = len; if (!old_path) - old_path = "/bin:/usr/bin:."; + old_path = "/usr/local/bin:/usr/bin:/bin"; path_len = len + strlen(old_path) + 1; @@ -160,8 +194,6 @@ static void prepend_to_path(const char * setenv("PATH", path, 1); } -/* has anyone seen 'man' installed anywhere else than in /usr/bin? */ -#define PATH_TO_MAN "/usr/bin/man" static void show_man_page(char *git_cmd) { char *page; @@ -177,7 +209,7 @@ static void show_man_page(char *git_cmd) page[page_len] = 0; } - execlp(PATH_TO_MAN, "man", page, NULL); + execlp("man", "man", page, NULL); } int main(int argc, char **argv, char **envp) @@ -226,15 +258,25 @@ int main(int argc, char **argv, char **e show_man_page(argv[i]); } - /* allow relative paths, but run with exact */ - if (chdir(exec_path)) { - printf("git: '%s': %s\n", exec_path, strerror(errno)); - exit (1); - } - - getcwd(git_command, sizeof(git_command)); - chdir(wd); + if (*exec_path != '/') { + if (!getcwd(git_command, sizeof(git_command))) { + fprintf(stderr, + "git: cannot determine current directory"); + exit(1); + } + len = strlen(git_command); + /* Trivial cleanup */ + while (!strncmp(exec_path, "./", 2)) { + exec_path += 2; + while (*exec_path == '/') + *exec_path++; + } + snprintf(git_command + len, sizeof(git_command) - len, + "/%s", exec_path); + } + else + strcpy(git_command, exec_path); len = strlen(git_command); prepend_to_path(git_command, len); --- 0.99.9.GIT ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] git wrapper: basic fixes. 2005-11-16 7:17 ` [PATCH] git wrapper: basic fixes Junio C Hamano @ 2005-11-16 8:22 ` Johannes Schindelin 0 siblings, 0 replies; 9+ messages in thread From: Johannes Schindelin @ 2005-11-16 8:22 UTC (permalink / raw) To: Junio C Hamano; +Cc: Andreas Ericsson, git Hi, On Tue, 15 Nov 2005, Junio C Hamano wrote: > - Lose use of glob(); read from exec_path and do sorting > ourselves -- it is not that much more work. Clearly a better fix than my patch. Ciao, Dscho ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 3:45 ` H. Peter Anvin 2005-11-16 6:56 ` Andreas Ericsson @ 2005-11-16 7:29 ` Junio C Hamano 2005-11-16 21:53 ` H. Peter Anvin 1 sibling, 1 reply; 9+ messages in thread From: Junio C Hamano @ 2005-11-16 7:29 UTC (permalink / raw) To: H. Peter Anvin; +Cc: git "H. Peter Anvin" <hpa@zytor.com> writes: > The way this made it into the actual tree was to call /usr/bin/man, but > still using execlp(). This is clearly bogus. There *ARE* good reasons > to use PATH resolutions for this, since man is one of the interactive > commands the user may want to wrapper. Oh, that was my call, so please do not blame Andreas. I just sent out a proposed patch to address all the points discussed on the list for the last several hours. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 7:29 ` [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Junio C Hamano @ 2005-11-16 21:53 ` H. Peter Anvin 2005-11-16 23:16 ` Andreas Ericsson 0 siblings, 1 reply; 9+ messages in thread From: H. Peter Anvin @ 2005-11-16 21:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano wrote: > "H. Peter Anvin" <hpa@zytor.com> writes: > >>The way this made it into the actual tree was to call /usr/bin/man, but >>still using execlp(). This is clearly bogus. There *ARE* good reasons >>to use PATH resolutions for this, since man is one of the interactive >>commands the user may want to wrapper. > > Oh, that was my call, so please do not blame Andreas. > I just sent out a proposed patch to address all the points > discussed on the list for the last several hours. > FWIW, I rarely blame people for bad code; *everyone* does something stupid every now and then, and for most of us, far more often than that. "This piece of code is stupid" != "the author of this piece of code is stupid", a distinction which unfortunately often gets lost. I say "rarely", because there are of course a small number of people who *consistently* produce crap. However, even they occationally produce something useful -- it's just not that often, and one has to carefully review it first. With sufficient thrust pigs fly just fine[*], and heck, even RBJ even occationally says something correct. -hpa [*] It is, however, not necessarily a good idea. It can be dangerous for the people on the ground, and annoys the pig. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 21:53 ` H. Peter Anvin @ 2005-11-16 23:16 ` Andreas Ericsson 2005-11-16 23:17 ` H. Peter Anvin 0 siblings, 1 reply; 9+ messages in thread From: Andreas Ericsson @ 2005-11-16 23:16 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Junio C Hamano, git H. Peter Anvin wrote: > Junio C Hamano wrote: > >> "H. Peter Anvin" <hpa@zytor.com> writes: >> >>> The way this made it into the actual tree was to call /usr/bin/man, >>> but still using execlp(). This is clearly bogus. There *ARE* good >>> reasons to use PATH resolutions for this, since man is one of the >>> interactive commands the user may want to wrapper. >> >> >> Oh, that was my call, so please do not blame Andreas. >> I just sent out a proposed patch to address all the points >> discussed on the list for the last several hours. >> > > FWIW, I rarely blame people for bad code; *everyone* does something > stupid every now and then, and for most of us, far more often than that. > "This piece of code is stupid" != "the author of this piece of code is > stupid", a distinction which unfortunately often gets lost. > True, but it's possible to have a 180 iq and still know nothing about programming. Anyhow, I sent the first patch too, so please blame me if anyone. If I was hoping to be admired I'd go play video-games with my 6 year old cousin. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two 2005-11-16 23:16 ` Andreas Ericsson @ 2005-11-16 23:17 ` H. Peter Anvin 0 siblings, 0 replies; 9+ messages in thread From: H. Peter Anvin @ 2005-11-16 23:17 UTC (permalink / raw) To: Andreas Ericsson; +Cc: Junio C Hamano, git Andreas Ericsson wrote: > > True, but it's possible to have a 180 iq and still know nothing about > programming. Anyhow, I sent the first patch too, so please blame me if > anyone. If I was hoping to be admired I'd go play video-games with my 6 > year old cousin. > The point was: mistakes happen. No point in arguing about whose fault it was. -hpa ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-11-16 23:18 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-11-16 0:23 [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Andreas Ericsson 2005-11-16 3:45 ` H. Peter Anvin 2005-11-16 6:56 ` Andreas Ericsson 2005-11-16 7:17 ` [PATCH] git wrapper: basic fixes Junio C Hamano 2005-11-16 8:22 ` Johannes Schindelin 2005-11-16 7:29 ` [PATCH 3/3] git --help COMMAND brings up the git-COMMAND man-page., take two Junio C Hamano 2005-11-16 21:53 ` H. Peter Anvin 2005-11-16 23:16 ` Andreas Ericsson 2005-11-16 23:17 ` H. Peter Anvin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).