Skip to content

Commit

Permalink
Merge branch 'master' into jc/fmt-patch
Browse files Browse the repository at this point in the history
* master:
  Split up builtin commands into separate files from git.c
  git-log produces no output
  fix pack-object buffer size
  mailinfo: decode underscore used in "Q" encoding properly.
  Reintroduce svn pools to solve the memory leak.
  pack-objects: do not stop at object that is "too small"
  git-commit --amend: two fixes.
  get_tree_entry(): make it available from tree-walk
  sha1_name.c: no need to include diff.h; tree-walk.h will do.
  sha1_name.c: prepare to make get_tree_entry() reusable from others.
  get_sha1() shorthands for blob/tree objects
  pre-commit hook: complain about conflict markers.
  git-merge: a bit more readable user guidance.
  diff: move diff.c to diff-lib.c to make room.
  git log: don't do merge diffs by default
  Allow "git repack" users to specify repacking window/depth
  Document git-clone --reference
  Fix filename scaling for binary files
  Fix uninteresting tags in new revision parsing

Conflicts:

    Adjusted the addition of fmt-patch to match the recent split
    from git.c to builtin.log.c.
  • Loading branch information
Junio C Hamano committed Apr 21, 2006
2 parents 43885c2 + 70827b1 commit 91efcf6
Show file tree
Hide file tree
Showing 20 changed files with 514 additions and 369 deletions.
21 changes: 20 additions & 1 deletion Documentation/git-clone.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SYNOPSIS
--------
[verse]
'git-clone' [-l [-s]] [-q] [-n] [--bare] [-o <name>] [-u <upload-pack>]
[--reference <repository>]
<repository> [<directory>]

DESCRIPTION
Expand Down Expand Up @@ -46,10 +47,18 @@ OPTIONS
-s::
When the repository to clone is on the local machine,
instead of using hard links, automatically setup
.git/objects/info/alternatives to share the objects
.git/objects/info/alternates to share the objects
with the source repository. The resulting repository
starts out without any object of its own.

--reference <repository>::
If the reference repository is on the local machine
automatically setup .git/objects/info/alternates to
obtain objects from the reference repository. Using
an already existing repository as an alternate will
require less objects to be copied from the repository
being cloned, reducing network and local storage costs.

--quiet::
-q::
Operate quietly. This flag is passed to "rsync" and
Expand Down Expand Up @@ -112,6 +121,16 @@ $ git show-branch
------------


Clone from upstream while borrowing from an existing local directory::
+
------------
$ git clone --reference my2.6 \
git://git.kernel.org/pub/scm/.../linux-2.7 \
my2.7
$ cd my2.7
------------


Create a bare repository to publish your changes to the public::
+
------------
Expand Down
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ LIB_H = \
tree-walk.h log-tree.h

DIFF_OBJS = \
diff.o diffcore-break.o diffcore-order.o \
diff-lib.o diffcore-break.o diffcore-order.o \
diffcore-pickaxe.o diffcore-rename.o tree-diff.o combine-diff.o \
diffcore-delta.o log-tree.o

Expand All @@ -213,6 +213,9 @@ LIB_OBJS = \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
$(DIFF_OBJS)

BUILTIN_OBJS = \
builtin-log.o builtin-help.o

GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz

Expand Down Expand Up @@ -462,10 +465,10 @@ all:
strip: $(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)"' \
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
$(ALL_LDFLAGS) $(LIBS)
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)

$(BUILT_INS): git$X
rm -f $@ && ln git$X $@
Expand Down Expand Up @@ -565,7 +568,7 @@ init-db.o: init-db.c
$(CC) -c $(ALL_CFLAGS) \
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c

$(LIB_OBJS): $(LIB_H)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
$(DIFF_OBJS): diffcore.h

Expand Down
241 changes: 241 additions & 0 deletions builtin-help.c
Original file line number Diff line number Diff line change
@@ -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;
}


Loading

0 comments on commit 91efcf6

Please sign in to comment.