mirror of
https://github.com/git/git.git
synced 2024-11-17 22:44:49 +01:00
Merge branch 'jc/fmt-patch' into next
* jc/fmt-patch: Split up builtin commands into separate files from git.c git-log produces no output
This commit is contained in:
commit
6082c4433b
6 changed files with 384 additions and 342 deletions
9
Makefile
9
Makefile
|
@ -213,6 +213,9 @@ LIB_OBJS = \
|
||||||
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
|
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
|
||||||
$(DIFF_OBJS)
|
$(DIFF_OBJS)
|
||||||
|
|
||||||
|
BUILTIN_OBJS = \
|
||||||
|
builtin-log.o builtin-help.o
|
||||||
|
|
||||||
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
|
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
|
||||||
LIBS = $(GITLIBS) -lz
|
LIBS = $(GITLIBS) -lz
|
||||||
|
|
||||||
|
@ -462,10 +465,10 @@ all:
|
||||||
strip: $(PROGRAMS) git$X
|
strip: $(PROGRAMS) git$X
|
||||||
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
|
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
|
||||||
|
|
||||||
git$X: git.c common-cmds.h $(GITLIBS)
|
git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS)
|
||||||
$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
|
$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
|
||||||
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
|
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
|
||||||
$(ALL_LDFLAGS) $(LIBS)
|
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
$(BUILT_INS): git$X
|
$(BUILT_INS): git$X
|
||||||
rm -f $@ && ln git$X $@
|
rm -f $@ && ln git$X $@
|
||||||
|
@ -565,7 +568,7 @@ init-db.o: init-db.c
|
||||||
$(CC) -c $(ALL_CFLAGS) \
|
$(CC) -c $(ALL_CFLAGS) \
|
||||||
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
|
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
|
||||||
|
|
||||||
$(LIB_OBJS): $(LIB_H)
|
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
|
||||||
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
|
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
|
||||||
$(DIFF_OBJS): diffcore.h
|
$(DIFF_OBJS): diffcore.h
|
||||||
|
|
||||||
|
|
241
builtin-help.c
Normal file
241
builtin-help.c
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
/*
|
||||||
|
* builtin-help.c
|
||||||
|
*
|
||||||
|
* Builtin help-related commands (help, usage, version)
|
||||||
|
*/
|
||||||
|
#include "cache.h"
|
||||||
|
#include "builtin.h"
|
||||||
|
#include "exec_cmd.h"
|
||||||
|
#include "common-cmds.h"
|
||||||
|
|
||||||
|
static const char git_usage[] =
|
||||||
|
"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
|
||||||
|
|
||||||
|
/* most gui terms 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)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (fmt) {
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
printf("git: ");
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
puts(git_usage);
|
||||||
|
|
||||||
|
if (exec_path) {
|
||||||
|
putchar('\n');
|
||||||
|
if (show_all)
|
||||||
|
list_commands(exec_path, "git-*");
|
||||||
|
else
|
||||||
|
list_common_cmds_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_version(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
printf("git version %s\n", git_version_string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_help(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
const char *help_cmd = argv[1];
|
||||||
|
if (!help_cmd)
|
||||||
|
cmd_usage(0, git_exec_path(), NULL);
|
||||||
|
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
|
||||||
|
cmd_usage(1, git_exec_path(), NULL);
|
||||||
|
else
|
||||||
|
show_man_page(help_cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
108
builtin-log.c
Normal file
108
builtin-log.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Builtin "git log" and related commands (show, whatchanged)
|
||||||
|
*
|
||||||
|
* (C) Copyright 2006 Linus Torvalds
|
||||||
|
* 2006 Junio Hamano
|
||||||
|
*/
|
||||||
|
#include "cache.h"
|
||||||
|
#include "commit.h"
|
||||||
|
#include "diff.h"
|
||||||
|
#include "revision.h"
|
||||||
|
#include "log-tree.h"
|
||||||
|
#include "builtin.h"
|
||||||
|
|
||||||
|
static int cmd_log_wc(int argc, const char **argv, char **envp,
|
||||||
|
struct rev_info *rev)
|
||||||
|
{
|
||||||
|
struct commit *commit;
|
||||||
|
|
||||||
|
rev->abbrev = DEFAULT_ABBREV;
|
||||||
|
rev->commit_format = CMIT_FMT_DEFAULT;
|
||||||
|
rev->verbose_header = 1;
|
||||||
|
argc = setup_revisions(argc, argv, rev, "HEAD");
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
die("unrecognized argument: %s", argv[1]);
|
||||||
|
|
||||||
|
prepare_revision_walk(rev);
|
||||||
|
setup_pager();
|
||||||
|
while ((commit = get_revision(rev)) != NULL) {
|
||||||
|
log_tree_commit(rev, commit);
|
||||||
|
free(commit->buffer);
|
||||||
|
commit->buffer = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_whatchanged(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
struct rev_info rev;
|
||||||
|
|
||||||
|
init_revisions(&rev);
|
||||||
|
rev.diff = 1;
|
||||||
|
rev.diffopt.recursive = 1;
|
||||||
|
return cmd_log_wc(argc, argv, envp, &rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_show(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
struct rev_info rev;
|
||||||
|
|
||||||
|
init_revisions(&rev);
|
||||||
|
rev.diff = 1;
|
||||||
|
rev.diffopt.recursive = 1;
|
||||||
|
rev.combine_merges = 1;
|
||||||
|
rev.dense_combined_merges = 1;
|
||||||
|
rev.always_show_header = 1;
|
||||||
|
rev.ignore_merges = 0;
|
||||||
|
rev.no_walk = 1;
|
||||||
|
return cmd_log_wc(argc, argv, envp, &rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_log(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
struct rev_info rev;
|
||||||
|
|
||||||
|
init_revisions(&rev);
|
||||||
|
rev.always_show_header = 1;
|
||||||
|
rev.diffopt.recursive = 1;
|
||||||
|
return cmd_log_wc(argc, argv, envp, &rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_format_patch(int argc, const char **argv, char **envp)
|
||||||
|
{
|
||||||
|
struct commit *commit;
|
||||||
|
struct commit **list = NULL;
|
||||||
|
struct rev_info rev;
|
||||||
|
int nr = 0;
|
||||||
|
|
||||||
|
init_revisions(&rev);
|
||||||
|
rev.commit_format = CMIT_FMT_EMAIL;
|
||||||
|
rev.verbose_header = 1;
|
||||||
|
rev.diff = 1;
|
||||||
|
rev.diffopt.with_raw = 0;
|
||||||
|
rev.diffopt.with_stat = 1;
|
||||||
|
rev.combine_merges = 0;
|
||||||
|
rev.ignore_merges = 1;
|
||||||
|
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||||
|
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
||||||
|
|
||||||
|
prepare_revision_walk(&rev);
|
||||||
|
while ((commit = get_revision(&rev)) != NULL) {
|
||||||
|
nr++;
|
||||||
|
list = realloc(list, nr * sizeof(list[0]));
|
||||||
|
list[nr - 1] = commit;
|
||||||
|
}
|
||||||
|
while (0 <= --nr) {
|
||||||
|
int shown;
|
||||||
|
commit = list[nr];
|
||||||
|
shown = log_tree_commit(&rev, commit);
|
||||||
|
free(commit->buffer);
|
||||||
|
commit->buffer = NULL;
|
||||||
|
if (shown)
|
||||||
|
printf("-- \n%s\n\n", git_version_string);
|
||||||
|
}
|
||||||
|
free(list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
24
builtin.h
Normal file
24
builtin.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef BUILTIN_H
|
||||||
|
#define BUILTIN_H
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
# define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char git_version_string[];
|
||||||
|
|
||||||
|
void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((__format__(__printf__, 3, 4), __noreturn__))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
extern int cmd_help(int argc, const char **argv, char **envp);
|
||||||
|
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_format_patch(int argc, const char **argv, char **envp);
|
||||||
|
|
||||||
|
#endif
|
342
git.c
342
git.c
|
@ -11,215 +11,8 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include "git-compat-util.h"
|
#include "git-compat-util.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include "common-cmds.h"
|
|
||||||
|
|
||||||
#include "cache.h"
|
#include "builtin.h"
|
||||||
#include "commit.h"
|
|
||||||
#include "diff.h"
|
|
||||||
#include "revision.h"
|
|
||||||
#include "log-tree.h"
|
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
# define PATH_MAX 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char git_usage[] =
|
|
||||||
"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
|
|
||||||
|
|
||||||
/* most gui terms 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)");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
static void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
|
|
||||||
__attribute__((__format__(__printf__, 3, 4), __noreturn__));
|
|
||||||
#endif
|
|
||||||
static void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if (fmt) {
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
printf("git: ");
|
|
||||||
vprintf(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
puts(git_usage);
|
|
||||||
|
|
||||||
if (exec_path) {
|
|
||||||
putchar('\n');
|
|
||||||
if (show_all)
|
|
||||||
list_commands(exec_path, "git-*");
|
|
||||||
else
|
|
||||||
list_common_cmds_help();
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void prepend_to_path(const char *dir, int len)
|
static void prepend_to_path(const char *dir, int len)
|
||||||
{
|
{
|
||||||
|
@ -240,136 +33,7 @@ static void prepend_to_path(const char *dir, int len)
|
||||||
setenv("PATH", path, 1);
|
setenv("PATH", path, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_man_page(const char *git_cmd)
|
const char git_version_string[] = GIT_VERSION;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_version(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
printf("git version %s\n", GIT_VERSION);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_help(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
const char *help_cmd = argv[1];
|
|
||||||
if (!help_cmd)
|
|
||||||
cmd_usage(0, git_exec_path(), NULL);
|
|
||||||
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
|
|
||||||
cmd_usage(1, git_exec_path(), NULL);
|
|
||||||
else
|
|
||||||
show_man_page(help_cmd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_format_patch(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
struct commit *commit;
|
|
||||||
struct commit **list = NULL;
|
|
||||||
struct rev_info rev;
|
|
||||||
int nr = 0;
|
|
||||||
|
|
||||||
init_revisions(&rev);
|
|
||||||
rev.commit_format = CMIT_FMT_EMAIL;
|
|
||||||
rev.verbose_header = 1;
|
|
||||||
rev.diff = 1;
|
|
||||||
rev.diffopt.with_raw = 0;
|
|
||||||
rev.diffopt.with_stat = 1;
|
|
||||||
rev.combine_merges = 0;
|
|
||||||
rev.ignore_merges = 1;
|
|
||||||
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
|
|
||||||
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
|
||||||
|
|
||||||
prepare_revision_walk(&rev);
|
|
||||||
while ((commit = get_revision(&rev)) != NULL) {
|
|
||||||
nr++;
|
|
||||||
list = realloc(list, nr * sizeof(list[0]));
|
|
||||||
list[nr - 1] = commit;
|
|
||||||
}
|
|
||||||
while (0 <= --nr) {
|
|
||||||
int shown;
|
|
||||||
commit = list[nr];
|
|
||||||
shown = log_tree_commit(&rev, commit);
|
|
||||||
free(commit->buffer);
|
|
||||||
commit->buffer = NULL;
|
|
||||||
if (shown)
|
|
||||||
printf("-- \n%s\n\n", GIT_VERSION);
|
|
||||||
}
|
|
||||||
free(list);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_log_wc(int argc, const char **argv, char **envp,
|
|
||||||
struct rev_info *rev)
|
|
||||||
{
|
|
||||||
struct commit *commit;
|
|
||||||
|
|
||||||
rev->abbrev = DEFAULT_ABBREV;
|
|
||||||
rev->commit_format = CMIT_FMT_DEFAULT;
|
|
||||||
rev->verbose_header = 1;
|
|
||||||
argc = setup_revisions(argc, argv, rev, "HEAD");
|
|
||||||
|
|
||||||
if (argc > 1)
|
|
||||||
die("unrecognized argument: %s", argv[1]);
|
|
||||||
|
|
||||||
prepare_revision_walk(rev);
|
|
||||||
setup_pager();
|
|
||||||
while ((commit = get_revision(rev)) != NULL) {
|
|
||||||
log_tree_commit(rev, commit);
|
|
||||||
free(commit->buffer);
|
|
||||||
commit->buffer = NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_wc(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
struct rev_info rev;
|
|
||||||
|
|
||||||
init_revisions(&rev);
|
|
||||||
rev.diff = 1;
|
|
||||||
rev.diffopt.recursive = 1;
|
|
||||||
return cmd_log_wc(argc, argv, envp, &rev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_show(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
struct rev_info rev;
|
|
||||||
|
|
||||||
init_revisions(&rev);
|
|
||||||
rev.diff = 1;
|
|
||||||
rev.diffopt.recursive = 1;
|
|
||||||
rev.combine_merges = 1;
|
|
||||||
rev.dense_combined_merges = 1;
|
|
||||||
rev.always_show_header = 1;
|
|
||||||
rev.ignore_merges = 0;
|
|
||||||
rev.no_walk = 1;
|
|
||||||
return cmd_log_wc(argc, argv, envp, &rev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_log(int argc, const char **argv, char **envp)
|
|
||||||
{
|
|
||||||
struct rev_info rev;
|
|
||||||
|
|
||||||
init_revisions(&rev);
|
|
||||||
rev.always_show_header = 1;
|
|
||||||
rev.diffopt.recursive = 1;
|
|
||||||
return cmd_log_wc(argc, argv, envp, &rev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_internal_command(int argc, const char **argv, char **envp)
|
static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
|
@ -381,7 +45,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||||
{ "version", cmd_version },
|
{ "version", cmd_version },
|
||||||
{ "help", cmd_help },
|
{ "help", cmd_help },
|
||||||
{ "log", cmd_log },
|
{ "log", cmd_log },
|
||||||
{ "whatchanged", cmd_wc },
|
{ "whatchanged", cmd_whatchanged },
|
||||||
{ "show", cmd_show },
|
{ "show", cmd_show },
|
||||||
{ "fmt-patch", cmd_format_patch },
|
{ "fmt-patch", cmd_format_patch },
|
||||||
};
|
};
|
||||||
|
|
2
pager.c
2
pager.c
|
@ -8,6 +8,7 @@
|
||||||
static void run_pager(const char *pager)
|
static void run_pager(const char *pager)
|
||||||
{
|
{
|
||||||
execlp(pager, pager, NULL);
|
execlp(pager, pager, NULL);
|
||||||
|
execl("/bin/sh", "sh", "-c", pager, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_pager(void)
|
void setup_pager(void)
|
||||||
|
@ -47,5 +48,6 @@ void setup_pager(void)
|
||||||
|
|
||||||
setenv("LESS", "-S", 0);
|
setenv("LESS", "-S", 0);
|
||||||
run_pager(pager);
|
run_pager(pager);
|
||||||
|
die("unable to execute pager '%s'", pager);
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue