Merge branch 'jc/blame' into jc/web-blame

* jc/blame:
  git-blame --porcelain
  blame.c: move code to output metainfo into a separate function.
  git-blame: --show-number (and -n)
  git-blame: --show-name (and -f)
  blame.c: whitespace and formatting clean-up.
  gitweb: Make the Git logo link target to point to the homepage
  gitweb: blame: Minimize vertical table row padding
  gitweb: Do not print "log" and "shortlog" redundantly in commit view
  vc-git.el: Switch to using git-blame instead of git-annotate.
  git.el: Fixed inverted "renamed from/to" message.
  tar-tree deprecation: we eat our own dog food.
  Add git-upload-archive to the main git man page
  git-commit: cleanup unused function.
  Fix usage string to match that given in the man page
  Update the gitweb/README file to include setting the GITWEB_CONFIG environment

Conflicts:

	gitweb/gitweb.perl
This commit is contained in:
Junio C Hamano 2006-10-06 00:16:05 -07:00
Родитель b2d3476e15 b5c698d947
Коммит 4b4a5dbb17
10 изменённых файлов: 338 добавлений и 188 удалений

Просмотреть файл

@ -243,6 +243,9 @@ gitlink:git-update-server-info[1]::
Updates auxiliary information on a dumb server to help
clients discover references and packs on it.
gitlink:git-upload-archive[1]::
Invoked by 'git-archive' to send a generated archive.
gitlink:git-upload-pack[1]::
Invoked by 'git-fetch-pack' to push
what are asked for.

Просмотреть файл

@ -860,8 +860,9 @@ git.spec: git.spec.in
mv $@+ $@
GIT_TARNAME=git-$(GIT_VERSION)
dist: git.spec git-tar-tree
./git-tar-tree HEAD^{tree} $(GIT_TARNAME) > $(GIT_TARNAME).tar
dist: git.spec git-archive
./git-archive --format=tar \
--prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar
@mkdir -p $(GIT_TARNAME)
@cp git.spec $(GIT_TARNAME)
@echo $(GIT_VERSION) > $(GIT_TARNAME)/version

447
blame.c
Просмотреть файл

@ -17,19 +17,21 @@
#include "diffcore.h"
#include "revision.h"
#include "xdiff-interface.h"
#include "quote.h"
#define DEBUG 0
static const char blame_usage[] = "git-blame [-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
" -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
" -l, --long Show long commit SHA1 (Default: off)\n"
" -t, --time Show raw timestamp (Default: off)\n"
" -S, --revs-file Use revisions from revs-file instead of calling git-rev-list\n"
" -h, --help This message";
static const char blame_usage[] =
"git-blame [-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
" -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
" -l, --long Show long commit SHA1 (Default: off)\n"
" -t, --time Show raw timestamp (Default: off)\n"
" -S, --revs-file Use revisions from revs-file instead of calling git-rev-list\n"
" -h, --help This message";
static struct commit **blame_lines;
static int num_blame_lines;
static char* blame_contents;
static char *blame_contents;
static int blame_len;
struct util_info {
@ -38,9 +40,10 @@ struct util_info {
char *buf;
unsigned long size;
int num_lines;
const char* pathname;
const char *pathname;
unsigned meta_given:1;
void* topo_data;
void *topo_data;
};
struct chunk {
@ -156,11 +159,10 @@ static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
unsigned mode, int stage);
static unsigned char blob_sha1[20];
static const char* blame_file;
static const char *blame_file;
static int get_blob_sha1(struct tree *t, const char *pathname,
unsigned char *sha1)
{
int i;
const char *pathspec[2];
blame_file = pathname;
pathspec[0] = pathname;
@ -168,12 +170,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname,
hashclr(blob_sha1);
read_tree_recursive(t, "", 0, 0, pathspec, get_blob_sha1_internal);
for (i = 0; i < 20; i++) {
if (blob_sha1[i] != 0)
break;
}
if (i == 20)
if (is_null_sha1(blob_sha1))
return -1;
hashcpy(sha1, blob_sha1);
@ -239,7 +236,8 @@ static void print_map(struct commit *cmit, struct commit *other)
if (i < util->num_lines) {
num = util->line_map[i];
printf("%d\t", num);
} else
}
else
printf("\t");
if (i < util2->num_lines) {
@ -247,7 +245,8 @@ static void print_map(struct commit *cmit, struct commit *other)
printf("%d\t", num2);
if (num != -1 && num2 != num)
printf("---");
} else
}
else
printf("\t");
printf("\n");
@ -266,12 +265,12 @@ static void fill_line_map(struct commit *commit, struct commit *other,
int cur_chunk = 0;
int i1, i2;
if (p->num && DEBUG)
print_patch(p);
if (DEBUG)
if (DEBUG) {
if (p->num)
print_patch(p);
printf("num lines 1: %d num lines 2: %d\n", util->num_lines,
util2->num_lines);
}
for (i1 = 0, i2 = 0; i1 < util->num_lines; i1++, i2++) {
struct chunk *chunk = NULL;
@ -293,7 +292,8 @@ static void fill_line_map(struct commit *commit, struct commit *other,
i2 += chunk->len2;
cur_chunk++;
} else {
}
else {
if (i2 >= util2->num_lines)
break;
@ -327,19 +327,15 @@ static int map_line(struct commit *commit, int line)
return info->line_map[line];
}
static struct util_info* get_util(struct commit *commit)
static struct util_info *get_util(struct commit *commit)
{
struct util_info *util = commit->util;
if (util)
return util;
util = xmalloc(sizeof(struct util_info));
util->buf = NULL;
util->size = 0;
util->line_map = NULL;
util = xcalloc(1, sizeof(struct util_info));
util->num_lines = -1;
util->pathname = NULL;
commit->util = util;
return util;
}
@ -369,7 +365,7 @@ static void alloc_line_map(struct commit *commit)
if (util->buf[i] == '\n')
util->num_lines++;
}
if(util->buf[util->size - 1] != '\n')
if (util->buf[util->size - 1] != '\n')
util->num_lines++;
util->line_map = xmalloc(sizeof(int) * util->num_lines);
@ -378,9 +374,9 @@ static void alloc_line_map(struct commit *commit)
util->line_map[i] = -1;
}
static void init_first_commit(struct commit* commit, const char* filename)
static void init_first_commit(struct commit *commit, const char *filename)
{
struct util_info* util = commit->util;
struct util_info *util = commit->util;
int i;
util->pathname = filename;
@ -395,18 +391,17 @@ static void init_first_commit(struct commit* commit, const char* filename)
util->line_map[i] = i;
}
static void process_commits(struct rev_info *rev, const char *path,
struct commit** initial)
struct commit **initial)
{
int i;
struct util_info* util;
struct util_info *util;
int lines_left;
int *blame_p;
int *new_lines;
int new_lines_len;
struct commit* commit = get_revision(rev);
struct commit *commit = get_revision(rev);
assert(commit);
init_first_commit(commit, path);
@ -442,7 +437,7 @@ static void process_commits(struct rev_info *rev, const char *path,
parents != NULL; parents = parents->next)
num_parents++;
if(num_parents == 0)
if (num_parents == 0)
*initial = commit;
if (fill_util_info(commit))
@ -503,13 +498,12 @@ static void process_commits(struct rev_info *rev, const char *path,
} while ((commit = get_revision(rev)) != NULL);
}
static int compare_tree_path(struct rev_info* revs,
struct commit* c1, struct commit* c2)
static int compare_tree_path(struct rev_info *revs,
struct commit *c1, struct commit *c2)
{
int ret;
const char* paths[2];
struct util_info* util = c2->util;
const char *paths[2];
struct util_info *util = c2->util;
paths[0] = util->pathname;
paths[1] = NULL;
@ -520,12 +514,11 @@ static int compare_tree_path(struct rev_info* revs,
return ret;
}
static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
const char* path)
static int same_tree_as_empty_path(struct rev_info *revs, struct tree *t1,
const char *path)
{
int ret;
const char* paths[2];
const char *paths[2];
paths[0] = path;
paths[1] = NULL;
@ -536,9 +529,9 @@ static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
return ret;
}
static const char* find_rename(struct commit* commit, struct commit* parent)
static const char *find_rename(struct commit *commit, struct commit *parent)
{
struct util_info* cutil = commit->util;
struct util_info *cutil = commit->util;
struct diff_options diff_opts;
const char *paths[1];
int i;
@ -564,9 +557,11 @@ static const char* find_rename(struct commit* commit, struct commit* parent)
for (i = 0; i < diff_queued_diff.nr; i++) {
struct diff_filepair *p = diff_queued_diff.queue[i];
if (p->status == 'R' && !strcmp(p->one->path, cutil->pathname)) {
if (p->status == 'R' &&
!strcmp(p->one->path, cutil->pathname)) {
if (DEBUG)
printf("rename %s -> %s\n", p->one->path, p->two->path);
printf("rename %s -> %s\n",
p->one->path, p->two->path);
return p->two->path;
}
}
@ -582,7 +577,7 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
return;
if (!commit->parents) {
struct util_info* util = commit->util;
struct util_info *util = commit->util;
if (!same_tree_as_empty_path(revs, commit->tree,
util->pathname))
commit->object.flags |= TREECHANGE;
@ -608,17 +603,17 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
case REV_TREE_NEW:
{
struct util_info* util = commit->util;
struct util_info *util = commit->util;
if (revs->remove_empty_trees &&
same_tree_as_empty_path(revs, p->tree,
util->pathname)) {
const char* new_name = find_rename(commit, p);
const char *new_name = find_rename(commit, p);
if (new_name) {
struct util_info* putil = get_util(p);
struct util_info *putil = get_util(p);
if (!putil->pathname)
putil->pathname = xstrdup(new_name);
} else {
}
else {
*pp = parent->next;
continue;
}
@ -639,47 +634,106 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
commit->object.flags |= TREECHANGE;
}
struct commit_info
{
char* author;
char* author_mail;
char *author;
char *author_mail;
unsigned long author_time;
char* author_tz;
char *author_tz;
/* filled only when asked for details */
char *committer;
char *committer_mail;
unsigned long committer_time;
char *committer_tz;
char *summary;
};
static void get_commit_info(struct commit* commit, struct commit_info* ret)
static void get_ac_line(const char *inbuf, const char *what,
int bufsz, char *person, char **mail,
unsigned long *time, char **tz)
{
int len;
char* tmp;
static char author_buf[1024];
char *tmp, *endp;
tmp = strstr(commit->buffer, "\nauthor ") + 8;
len = strchr(tmp, '\n') - tmp;
ret->author = author_buf;
memcpy(ret->author, tmp, len);
tmp = strstr(inbuf, what);
if (!tmp)
goto error_out;
tmp += strlen(what);
endp = strchr(tmp, '\n');
if (!endp)
len = strlen(tmp);
else
len = endp - tmp;
if (bufsz <= len) {
error_out:
/* Ugh */
person = *mail = *tz = "(unknown)";
*time = 0;
return;
}
memcpy(person, tmp, len);
tmp = ret->author;
tmp = person;
tmp += len;
*tmp = 0;
while(*tmp != ' ')
while (*tmp != ' ')
tmp--;
ret->author_tz = tmp+1;
*tz = tmp+1;
*tmp = 0;
while(*tmp != ' ')
while (*tmp != ' ')
tmp--;
ret->author_time = strtoul(tmp, NULL, 10);
*time = strtoul(tmp, NULL, 10);
*tmp = 0;
while(*tmp != ' ')
while (*tmp != ' ')
tmp--;
ret->author_mail = tmp + 1;
*mail = tmp + 1;
*tmp = 0;
}
static const char* format_time(unsigned long time, const char* tz_str,
static void get_commit_info(struct commit *commit, struct commit_info *ret, int detailed)
{
int len;
char *tmp, *endp;
static char author_buf[1024];
static char committer_buf[1024];
static char summary_buf[1024];
ret->author = author_buf;
get_ac_line(commit->buffer, "\nauthor ",
sizeof(author_buf), author_buf, &ret->author_mail,
&ret->author_time, &ret->author_tz);
if (!detailed)
return;
ret->committer = committer_buf;
get_ac_line(commit->buffer, "\ncommitter ",
sizeof(committer_buf), committer_buf, &ret->committer_mail,
&ret->committer_time, &ret->committer_tz);
ret->summary = summary_buf;
tmp = strstr(commit->buffer, "\n\n");
if (!tmp) {
error_out:
sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1));
return;
}
tmp += 2;
endp = strchr(tmp, '\n');
if (!endp)
goto error_out;
len = endp - tmp;
if (len >= sizeof(summary_buf))
goto error_out;
memcpy(summary_buf, tmp, len);
summary_buf[len] = 0;
}
static const char *format_time(unsigned long time, const char *tz_str,
int show_raw_time)
{
static char time_buf[128];
@ -704,15 +758,15 @@ static const char* format_time(unsigned long time, const char* tz_str,
return time_buf;
}
static void topo_setter(struct commit* c, void* data)
static void topo_setter(struct commit *c, void *data)
{
struct util_info* util = c->util;
struct util_info *util = c->util;
util->topo_data = data;
}
static void* topo_getter(struct commit* c)
static void *topo_getter(struct commit *c)
{
struct util_info* util = c->util;
struct util_info *util = c->util;
return util->topo_data;
}
@ -735,6 +789,101 @@ static int read_ancestry(const char *graft_file,
return 0;
}
static int lineno_width(int lines)
{
int i, width;
for (width = 1, i = 10; i <= lines + 1; width++)
i *= 10;
return width;
}
static int find_orig_linenum(struct util_info *u, int lineno)
{
int i;
for (i = 0; i < u->num_lines; i++)
if (lineno == u->line_map[i])
return i + 1;
return 0;
}
static void emit_meta(struct commit *c, int lno,
int sha1_len, int compatibility, int porcelain,
int show_name, int show_number, int show_raw_time,
int longest_file, int longest_author,
int max_digits, int max_orig_digits)
{
struct util_info *u;
int lineno;
struct commit_info ci;
u = c->util;
lineno = find_orig_linenum(u, lno);
if (porcelain) {
int group_size = -1;
struct commit *cc = (lno == 0) ? NULL : blame_lines[lno-1];
if (cc != c) {
/* This is the beginning of this group */
int i;
for (i = lno + 1; i < num_blame_lines; i++)
if (blame_lines[i] != c)
break;
group_size = i - lno;
}
if (0 < group_size)
printf("%s %d %d %d\n", sha1_to_hex(c->object.sha1),
lineno, lno + 1, group_size);
else
printf("%s %d %d\n", sha1_to_hex(c->object.sha1),
lineno, lno + 1);
if (!u->meta_given) {
get_commit_info(c, &ci, 1);
printf("author %s\n", ci.author);
printf("author-mail %s\n", ci.author_mail);
printf("author-time %lu\n", ci.author_time);
printf("author-tz %s\n", ci.author_tz);
printf("committer %s\n", ci.committer);
printf("committer-mail %s\n", ci.committer_mail);
printf("committer-time %lu\n", ci.committer_time);
printf("committer-tz %s\n", ci.committer_tz);
printf("filename ");
if (quote_c_style(u->pathname, NULL, NULL, 0))
quote_c_style(u->pathname, NULL, stdout, 0);
else
fputs(u->pathname, stdout);
printf("\nsummary %s\n", ci.summary);
u->meta_given = 1;
}
putchar('\t');
return;
}
get_commit_info(c, &ci, 0);
fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
if (compatibility) {
printf("\t(%10s\t%10s\t%d)", ci.author,
format_time(ci.author_time, ci.author_tz,
show_raw_time),
lno + 1);
}
else {
if (show_name)
printf(" %-*.*s", longest_file, longest_file,
u->pathname);
if (show_number)
printf(" %*d", max_orig_digits,
lineno);
printf(" (%-*.*s %10s %*d) ",
longest_author, longest_author, ci.author,
format_time(ci.author_time, ci.author_tz,
show_raw_time),
max_digits, lno + 1);
}
}
int main(int argc, const char **argv)
{
int i;
@ -747,38 +896,43 @@ int main(int argc, const char **argv)
int compatibility = 0;
int show_raw_time = 0;
int options = 1;
struct commit* start_commit;
struct commit *start_commit;
const char* args[10];
const char *args[10];
struct rev_info rev;
struct commit_info ci;
const char *buf;
int max_digits;
int longest_file, longest_author;
int found_rename;
int max_digits, max_orig_digits;
int longest_file, longest_author, longest_file_lines;
int show_name = 0;
int show_number = 0;
int porcelain = 0;
const char* prefix = setup_git_directory();
const char *prefix = setup_git_directory();
git_config(git_default_config);
for(i = 1; i < argc; i++) {
if(options) {
if(!strcmp(argv[i], "-h") ||
for (i = 1; i < argc; i++) {
if (options) {
if (!strcmp(argv[i], "-h") ||
!strcmp(argv[i], "--help"))
usage(blame_usage);
else if(!strcmp(argv[i], "-l") ||
!strcmp(argv[i], "--long")) {
if (!strcmp(argv[i], "-l") ||
!strcmp(argv[i], "--long")) {
sha1_len = 40;
continue;
} else if(!strcmp(argv[i], "-c") ||
!strcmp(argv[i], "--compatibility")) {
}
if (!strcmp(argv[i], "-c") ||
!strcmp(argv[i], "--compatibility")) {
compatibility = 1;
continue;
} else if(!strcmp(argv[i], "-t") ||
!strcmp(argv[i], "--time")) {
}
if (!strcmp(argv[i], "-t") ||
!strcmp(argv[i], "--time")) {
show_raw_time = 1;
continue;
} else if(!strcmp(argv[i], "-S")) {
}
if (!strcmp(argv[i], "-S")) {
if (i + 1 < argc &&
!read_ancestry(argv[i + 1], &sha1_p)) {
compatibility = 1;
@ -786,33 +940,50 @@ int main(int argc, const char **argv)
continue;
}
usage(blame_usage);
} else if(!strcmp(argv[i], "--")) {
}
if (!strcmp(argv[i], "-f") ||
!strcmp(argv[i], "--show-name")) {
show_name = 1;
continue;
}
if (!strcmp(argv[i], "-n") ||
!strcmp(argv[i], "--show-number")) {
show_number = 1;
continue;
}
if (!strcmp(argv[i], "--porcelain")) {
porcelain = 1;
sha1_len = 40;
show_raw_time = 1;
continue;
}
if (!strcmp(argv[i], "--")) {
options = 0;
continue;
} else if(argv[i][0] == '-')
}
if (argv[i][0] == '-')
usage(blame_usage);
else
options = 0;
options = 0;
}
if(!options) {
if(!filename)
if (!options) {
if (!filename)
filename = argv[i];
else if(!commit)
else if (!commit)
commit = argv[i];
else
usage(blame_usage);
}
}
if(!filename)
if (!filename)
usage(blame_usage);
if (commit && sha1_p)
usage(blame_usage);
else if(!commit)
else if (!commit)
commit = "HEAD";
if(prefix)
if (prefix)
sprintf(filename_buf, "%s%s", prefix, filename);
else
strcpy(filename_buf, filename);
@ -830,7 +1001,6 @@ int main(int argc, const char **argv)
return 1;
}
init_revisions(&rev, setup_git_directory());
rev.remove_empty_trees = 1;
rev.topo_order = 1;
@ -848,62 +1018,49 @@ int main(int argc, const char **argv)
prepare_revision_walk(&rev);
process_commits(&rev, filename, &initial);
for (i = 0; i < num_blame_lines; i++)
if (!blame_lines[i])
blame_lines[i] = initial;
buf = blame_contents;
for (max_digits = 1, i = 10; i <= num_blame_lines + 1; max_digits++)
i *= 10;
max_digits = lineno_width(num_blame_lines);
longest_file = 0;
longest_author = 0;
found_rename = 0;
longest_file_lines = 0;
for (i = 0; i < num_blame_lines; i++) {
struct commit *c = blame_lines[i];
struct util_info* u;
if (!c)
c = initial;
struct util_info *u;
u = c->util;
if (!found_rename && strcmp(filename, u->pathname))
found_rename = 1;
if (!show_name && strcmp(filename, u->pathname))
show_name = 1;
if (longest_file < strlen(u->pathname))
longest_file = strlen(u->pathname);
get_commit_info(c, &ci);
if (longest_file_lines < u->num_lines)
longest_file_lines = u->num_lines;
get_commit_info(c, &ci, 0);
if (longest_author < strlen(ci.author))
longest_author = strlen(ci.author);
}
max_orig_digits = lineno_width(longest_file_lines);
for (i = 0; i < num_blame_lines; i++) {
struct commit *c = blame_lines[i];
struct util_info* u;
emit_meta(blame_lines[i], i,
sha1_len, compatibility, porcelain,
show_name, show_number, show_raw_time,
longest_file, longest_author,
max_digits, max_orig_digits);
if (!c)
c = initial;
u = c->util;
get_commit_info(c, &ci);
fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
if(compatibility) {
printf("\t(%10s\t%10s\t%d)", ci.author,
format_time(ci.author_time, ci.author_tz,
show_raw_time),
i+1);
} else {
if (found_rename)
printf(" %-*.*s", longest_file, longest_file,
u->pathname);
printf(" (%-*.*s %10s %*d) ",
longest_author, longest_author, ci.author,
format_time(ci.author_time, ci.author_tz,
show_raw_time),
max_digits, i+1);
}
if(i == num_blame_lines - 1) {
if (i == num_blame_lines - 1) {
fwrite(buf, blame_len - (buf - blame_contents),
1, stdout);
if(blame_contents[blame_len-1] != '\n')
if (blame_contents[blame_len-1] != '\n')
putc('\n', stdout);
} else {
char* next_buf = strchr(buf, '\n') + 1;
}
else {
char *next_buf = strchr(buf, '\n') + 1;
fwrite(buf, next_buf - buf, 1, stdout);
buf = next_buf;
}

Просмотреть файл

@ -422,8 +422,8 @@ and returns the process output as a string."
(propertize
(concat " ("
(if (eq state 'copy) "copied from "
(if (eq (git-fileinfo->state info) 'added) "renamed to "
"renamed from "))
(if (eq (git-fileinfo->state info) 'added) "renamed from "
"renamed to "))
(git-escape-file-name (git-fileinfo->orig-name info))
")") 'face 'git-status-face)
"")))

Просмотреть файл

@ -119,10 +119,10 @@
(defun vc-git-annotate-command (file buf &optional rev)
; FIXME: rev is ignored
(let ((name (file-relative-name file)))
(call-process "git" nil buf nil "annotate" name)))
(call-process "git" nil buf nil "blame" name)))
(defun vc-git-annotate-time ()
(and (re-search-forward "[0-9a-f]+\t(.*\t\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\) \\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\) \\([-+0-9]+\\)\t[0-9]+)" nil t)
(and (re-search-forward "[0-9a-f]+ (.* \\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\) \\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\) \\([-+0-9]+\\) +[0-9]+)" nil t)
(vc-annotate-convert-time
(apply #'encode-time (mapcar (lambda (match) (string-to-number (match-string match))) '(6 5 4 3 2 1 7))))))

Просмотреть файл

@ -32,33 +32,6 @@ save_index () {
cp -p "$THIS_INDEX" "$NEXT_INDEX"
}
report () {
header="#
# $1:
# ($2)
#
"
trailer=""
while read status name newname
do
printf '%s' "$header"
header=""
trailer="#
"
case "$status" in
M ) echo "# modified: $name";;
D*) echo "# deleted: $name";;
T ) echo "# typechange: $name";;
C*) echo "# copied: $name -> $newname";;
R*) echo "# renamed: $name -> $newname";;
A*) echo "# new file: $name";;
U ) echo "# unmerged: $name";;
esac
done
printf '%s' "$trailer"
[ "$header" ]
}
run_status () {
# If TMP_INDEX is defined, that means we are doing
# "--only" partial commit, and that index file is used

2
git.c
Просмотреть файл

@ -16,7 +16,7 @@
#include "builtin.h"
const char git_usage_string[] =
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]";
static void prepend_to_path(const char *dir, int len)
{

Просмотреть файл

@ -43,6 +43,7 @@ repositories, you can configure apache like this:
DocumentRoot /pub/git
RewriteEngine on
RewriteRule ^/(.*\.git/(?!/?(info|objects|refs)).*)?$ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
SetEnv GITWEB_CONFIG /etc/gitweb.conf
</VirtualHost>
The above configuration expects your public repositories to live under
@ -51,6 +52,12 @@ both as cloneable GIT URL and as browseable gitweb interface.
If you then start your git-daemon with --base-path=/pub/git --export-all
then you can even use the git:// URL with exactly the same path.
Setting the environment variable GITWEB_CONFIG will tell gitweb to use
the named file (i.e. in this example /etc/gitweb.conf) as a
configuration for gitweb. Perl variables defined in here will
override the defaults given at the head of the gitweb.perl (or
gitweb.cgi). Look at the comments in that file for information on
which variables and what they mean.
Originally written by:

Просмотреть файл

@ -173,6 +173,12 @@ table.blame {
border-collapse: collapse;
}
table.blame td {
padding: 0px 5px;
font-size: 12px;
vertical-align: top;
}
th {
padding: 2px 5px;
font-size: 12px;

Просмотреть файл

@ -59,6 +59,9 @@ our $logo = "++GITWEB_LOGO++";
# URI of GIT favicon, assumed to be image/png type
our $favicon = "++GITWEB_FAVICON++";
our $githelp_url = "http://git.or.cz/";
our $githelp_label = "git homepage";
# source of projects list
our $projects_list = "++GITWEB_LIST++";
@ -1411,7 +1414,9 @@ EOF
}
print "<div class=\"page_header\">\n" .
"<a href=\"http://www.kernel.org/pub/software/scm/git/docs/\" title=\"git documentation\">" .
"<a href=\"" . esc_html($githelp_url) .
"\" title=\"" . esc_html($githelp_label) .
"\">" .
"<img src=\"$logo\" width=\"72\" height=\"27\" alt=\"git\" style=\"float:right; border-width:0px;\"/>" .
"</a>\n";
print $cgi->a({-href => esc_url($home_link)}, $home_link_str) . " / ";
@ -2891,9 +2896,12 @@ sub git_snapshot {
-content_disposition => 'inline; filename="' . "$filename" . '"',
-status => '200 OK');
my $git_command = git_cmd_str();
open my $fd, "-|", "$git_command tar-tree $hash \'$project\' | $command" or
die_error(undef, "Execute git-tar-tree failed.");
my $git = git_cmd_str();
my $name = $project;
$name =~ s/\047/\047\\\047\047/g;
open my $fd, "-|",
"$git archive --format=tar --prefix=\'$name\'/ $hash | $command"
or die_error(undef, "Execute git-tar-tree failed.");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
@ -2990,11 +2998,6 @@ sub git_commit {
$cgi->a({-href => href(action=>"blame", hash_parent=>$parent, file_name=>$file_name)},
"blame");
}
if (defined $co{'parent'}) {
push @views_nav,
$cgi->a({-href => href(action=>"shortlog", hash=>$hash)}, "shortlog"),
$cgi->a({-href => href(action=>"log", hash=>$hash)}, "log");
}
git_header_html(undef, $expires);
git_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff',
$hash, $co{'tree'}, $hash,