* Re: [PATCH 2/7] Switch git_mmap to use pread.
From: Alon Ziv @ 2006-12-24 19:30 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612241407250.19693@wbgn013.biozentrum.uni-wuerzburg.de>
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
On Sun, 2006-12-24 at 14:09 +0100, Johannes Schindelin wrote:
> I don't think it matters much. The _only_ platform we really use NO_MMAP
> (other than for testing) is Windows, and AFAICT it does not have pread(),
> so it is emulated by lseek/read/lseek anyway.
>
Well, Win32 does have a pread()-like behavior in its generic ReadFile()
system call (using a curiously-named "lpOverlapped" parameter). I would
have expected Cygwin to use it, but unfortunately from the CVS sources
it appears not to :(
-az
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2156 bytes --]
^ permalink raw reply
* Re: Updated Kernel Hacker's guide to git
From: Horst H. von Brand @ 2006-12-24 18:07 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Linux Kernel, Git Mailing List
In-Reply-To: <4589F9B1.2020405@garzik.org>
Jeff Garzik <jeff@garzik.org> wrote:
> I refreshed my git intro/cookbook for kernel hackers, at
> http://linux.yyz.us/git-howto.html
Looks nice, starting to look it over.
Notes:
Getting started:
There are RPM packages available (I think they are for latest Fedora; in
case of doubt get the latest SRPM and build yourself, sometimes the
distros lag /way/ behind). There are also Debian packages there, dunno
about those.
Basic tasks:
'git pull' should be enough, no need to give the URL each time.
It is useful to tell people how to get "nonofficial" branches (via URL +
branches) too.
Miscellaneous debris:
'git pull' has gotten tags each time for me?
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 2654431
Universidad Tecnica Federico Santa Maria +56 32 2654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 2797513
^ permalink raw reply
* [PATCH] commit encoding: store it in commit header rather than mucking with NUL
From: Johannes Schindelin @ 2006-12-24 15:44 UTC (permalink / raw)
To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0612241505290.19693@wbgn013.biozentrum.uni-wuerzburg.de>
It also fixes a segmentation fault when iconv does not know the
encoding (defaulting to no conversion).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
On Sun, 24 Dec 2006, Johannes Schindelin wrote:
> I don't like the convention to add the encoding after a trailing
> NUL. I'd rather have it as an "encoding blabl" header like the
> author and committer headers.
This is a patch implementing that, on top of pu.
builtin-commit-tree.c | 20 ++++++-------
commit.c | 70 ++++++++++++++++++++----------------------------
2 files changed, 38 insertions(+), 52 deletions(-)
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 9aff980..33c29f7 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -92,6 +92,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
char comment[1000];
char *buffer;
unsigned int size;
+ int encoding_is_utf8;
setup_ident();
git_config(git_default_config);
@@ -117,6 +118,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
parents++;
}
+ encoding_is_utf8 = !strcmp(git_commit_encoding, "utf-8");
+
init_buffer(&buffer, &size);
add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
@@ -130,7 +133,11 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
/* Person/date information */
add_buffer(&buffer, &size, "author %s\n", git_author_info(1));
- add_buffer(&buffer, &size, "committer %s\n\n", git_committer_info(1));
+ add_buffer(&buffer, &size, "committer %s\n", git_committer_info(1));
+ if (!encoding_is_utf8)
+ add_buffer(&buffer, &size,
+ "encoding %s\n", git_commit_encoding);
+ add_buffer(&buffer, &size, "\n");
/* And add the comment */
while (fgets(comment, sizeof(comment), stdin) != NULL)
@@ -138,16 +145,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
/* And check the encoding */
buffer[size] = '\0';
- if (strcmp(git_commit_encoding, "utf-8")) {
- /*
- * Add trailing section: this is safe because
- * add_buffer always allocates one byte more.
- */
- size++;
- add_buffer(&buffer, &size,
- "encoding %s\n", git_commit_encoding);
- }
- else if (!is_utf8(buffer))
+ if (encoding_is_utf8 && !is_utf8(buffer))
fprintf(stderr, commit_utf8_warn);
if (!write_sha1_file(buffer, size, commit_type, commit_sha1)) {
diff --git a/commit.c b/commit.c
index 58c4ecb..3132323 100644
--- a/commit.c
+++ b/commit.c
@@ -598,56 +598,43 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com
return offset;
}
-const char *commit_trailer(const struct commit *commit)
+static char *get_header(const struct commit *commit, const char *key)
{
- unsigned long size, len;
- char type[10];
+ int key_len = strlen(key);
+ const char *line = commit->buffer;
- if (sha1_object_info(commit->object.sha1, type, &size))
- return NULL;
- len = strlen(commit->buffer);
- if (len == size)
- return NULL;
- return commit->buffer + len + 1;
-}
-
-char *find_commit_trailer(const struct commit *commit, const char *key)
-{
- const char *trailer = commit_trailer(commit);
- int keylen = strlen(key);
- if (!trailer)
- return NULL;
- while (*trailer) {
- const char *eol = strchr(trailer, '\n');
- if (!eol)
- eol = trailer + strlen(trailer);
- if (!strncmp(trailer, key, keylen) && trailer[keylen] == ' ') {
- int valsz = eol - trailer - keylen;
- char *val = xmalloc(valsz + 1);
- memcpy(val, trailer + keylen + 1, valsz);
- val[valsz] = '\0';
- if (val[valsz-1] == '\n')
- val[valsz-1] = '\0';
- return val;
+ for (;;) {
+ const char *eol = strchr(line, '\n'), *next;
+
+ if (line == eol)
+ return NULL;
+ if (!eol) {
+ eol = line + strlen(line);
+ next = NULL;
+ } else
+ next = eol + 1;
+ if (!strncmp(line, key, key_len) && line[key_len] == ' ') {
+ int len = eol - line - key_len;
+ char *ret = xmalloc(len);
+ memcpy(ret, line + key_len + 1, len - 1);
+ ret[len - 1] = '\0';
+ return ret;
}
- if (!eol)
- break;
- trailer = eol + 1;
+ line = next;
}
- return NULL;
}
static char *logmsg_to_utf8(const struct commit *commit)
{
- char *encoding = find_commit_trailer(commit, "encoding");
+ char *encoding = get_header(commit, "encoding");
char *out;
if (!encoding)
- return commit->buffer;
+ return NULL;
out = reencode_string(commit->buffer, "utf-8", encoding);
free(encoding);
if (!out)
- return commit->buffer;
+ return NULL;
return out;
}
@@ -662,11 +649,12 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
int parents_shown = 0;
const char *msg = commit->buffer;
int plain_non_ascii = 0;
- int msg_reencoded = 0;
+ char *reencoded = NULL;
if (strcmp(git_commit_encoding, "utf-8") && i18n_log_to_utf8) {
- msg = logmsg_to_utf8(commit);
- msg_reencoded = 1;
+ reencoded = logmsg_to_utf8(commit);
+ if (reencoded)
+ msg = reencoded;
}
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
@@ -816,8 +804,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
buf[offset++] = '\n';
buf[offset] = '\0';
- if (msg_reencoded)
- free((char*)msg);
+ if (reencoded)
+ free(reencoded);
return offset;
}
--
1.4.4.3.g0001f-dirty
^ permalink raw reply related
* [PATCH 6/8] gitweb: Change atom, rss actions to use parse_commits.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <116697071140-git-send-email-robfitz@273k.net>
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 18 +++++++-----------
1 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 53dd225..f752a6f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4483,11 +4483,7 @@ sub git_feed {
# log/feed of current (HEAD) branch, log of given branch, history of file/directory
my $head = $hash || 'HEAD';
- open my $fd, "-|", git_cmd(), "rev-list", "--max-count=150",
- $head, "--", (defined $file_name ? $file_name : ())
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd or die_error(undef, "Reading git-rev-list failed");
+ my @commitlist = parse_commits($head, 150);
my %latest_commit;
my %latest_date;
@@ -4497,8 +4493,8 @@ sub git_feed {
# browser (feed reader) prefers text/xml
$content_type = 'text/xml';
}
- if (defined($revlist[0])) {
- %latest_commit = parse_commit($revlist[0]);
+ if (defined($commitlist[0])) {
+ %latest_commit = %{$commitlist[0]};
%latest_date = parse_date($latest_commit{'author_epoch'});
print $cgi->header(
-type => $content_type,
@@ -4588,9 +4584,9 @@ XML
}
# contents
- for (my $i = 0; $i <= $#revlist; $i++) {
- my $commit = $revlist[$i];
- my %co = parse_commit($commit);
+ for (my $i = 0; $i <= $#commitlist; $i++) {
+ my %co = %{$commitlist[$i]};
+ my $commit = $co{'id'};
# we read 150, we always show 30 and the ones more recent than 48 hours
if (($i >= 20) && ((time - $co{'author_epoch'}) > 48*60*60)) {
last;
@@ -4598,7 +4594,7 @@ XML
my %cd = parse_date($co{'author_epoch'});
# get list of changed files
- open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
+ open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
$co{'parent'}, $co{'id'}, "--", (defined $file_name ? $file_name : ())
or next;
my @difftree = map { chomp; $_ } <$fd>;
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 8/8] gitweb: Use rev-list --skip option.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <11669707111273-git-send-email-robfitz@273k.net>
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 24 +-----------------------
1 files changed, 1 insertions(+), 23 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f9994d9..65fcdb0 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1391,35 +1391,13 @@ sub parse_commits {
$maxcount ||= 1;
$skip ||= 0;
- # Delete once rev-list supports the --skip option
- if ($skip > 0) {
- open my $fd, "-|", git_cmd(), "rev-list",
- ($arg ? ($arg) : ()),
- ("--max-count=" . ($maxcount + $skip)),
- $commit_id,
- "--",
- ($filename ? ($filename) : ())
- or die_error(undef, "Open git-rev-list failed");
- while (my $line = <$fd>) {
- if ($skip-- <= 0) {
- chomp $line;
- my %co = parse_commit($line);
- push @cos, \%co;
- }
- }
- close $fd;
-
- return wantarray ? @cos : \@cos;
- }
-
local $/ = "\0";
open my $fd, "-|", git_cmd(), "rev-list",
"--header",
($arg ? ($arg) : ()),
("--max-count=" . $maxcount),
- # Add once rev-list supports the --skip option
- # ("--skip=" . $skip),
+ ("--skip=" . $skip),
$commit_id,
"--",
($filename ? ($filename) : ())
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 7/8] gitweb: Change history action to use parse_commits.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <1166970711394-git-send-email-robfitz@273k.net>
Also added missing accesskey.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 27 +++++++++------------------
1 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f752a6f..f9994d9 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2750,23 +2750,19 @@ sub git_shortlog_body {
sub git_history_body {
# Warning: assumes constant type (blob or tree) during history
- my ($revlist, $from, $to, $refs, $hash_base, $ftype, $extra) = @_;
+ my ($commitlist, $from, $to, $refs, $hash_base, $ftype, $extra) = @_;
$from = 0 unless defined $from;
- $to = $#{$revlist} unless (defined $to && $to <= $#{$revlist});
+ $to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist});
print "<table class=\"history\" cellspacing=\"0\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
- if ($revlist->[$i] !~ m/^([0-9a-fA-F]{40})/) {
- next;
- }
-
- my $commit = $1;
- my %co = parse_commit($commit);
+ my %co = %{$commitlist->[$i]};
if (!%co) {
next;
}
+ my $commit = $co{'id'};
my $ref = format_ref_marker($refs, $commit);
@@ -4219,12 +4215,7 @@ sub git_history {
$ftype = git_get_type($hash);
}
- open my $fd, "-|",
- git_cmd(), "rev-list", $limit, "--full-history", $hash_base, "--", $file_name
- or die_error(undef, "Open git-rev-list-failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd
- or die_error(undef, "Reading git-rev-list failed");
+ my @commitlist = parse_commits($hash_base, 101, (100 * $page), "--full-history", $file_name);
my $paging_nav = '';
if ($page > 0) {
@@ -4240,7 +4231,7 @@ sub git_history {
$paging_nav .= "first";
$paging_nav .= " ⋅ prev";
}
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($#commitlist >= 100) {
$paging_nav .= " ⋅ " .
$cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base,
file_name=>$file_name, page=>$page+1),
@@ -4249,11 +4240,11 @@ sub git_history {
$paging_nav .= " ⋅ next";
}
my $next_link = '';
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($#commitlist >= 100) {
$next_link =
$cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base,
file_name=>$file_name, page=>$page+1),
- -title => "Alt-n"}, "next");
+ -accesskey => "n", -title => "Alt-n"}, "next");
}
git_header_html();
@@ -4261,7 +4252,7 @@ sub git_history {
git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
git_print_page_path($file_name, $ftype, $hash_base);
- git_history_body(\@revlist, ($page * 100), $#revlist,
+ git_history_body(\@commitlist, 0, 99,
$refs, $hash_base, $ftype, $next_link);
git_footer_html();
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 4/8] gitweb: Change log action to use parse_commits.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <11669707102678-git-send-email-robfitz@273k.net>
Also add missing next link to bottom of page.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 5f1ace9..42b7449 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -3645,28 +3645,25 @@ sub git_log {
}
my $refs = git_get_references();
- my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
- open my $fd, "-|", git_cmd(), "rev-list", $limit, $hash, "--"
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ my @commitlist = parse_commits($hash, 101, (100 * $page));
- my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#revlist);
+ my $paging_nav = format_paging_nav('log', $hash, $head, $page, (100 * ($page+1)));
git_header_html();
git_print_page_nav('log','', $hash,undef,undef, $paging_nav);
- if (!@revlist) {
+ if (!@commitlist) {
my %co = parse_commit($hash);
git_print_header_div('summary', $project);
print "<div class=\"page_body\"> Last change $co{'age_string'}.<br/><br/></div>\n";
}
- for (my $i = ($page * 100); $i <= $#revlist; $i++) {
- my $commit = $revlist[$i];
- my $ref = format_ref_marker($refs, $commit);
- my %co = parse_commit($commit);
+ my $to = ($#commitlist >= 99) ? (99) : ($#commitlist);
+ for (my $i = 0; $i <= $to; $i++) {
+ my %co = %{$commitlist[$i]};
next if !%co;
+ my $commit = $co{'id'};
+ my $ref = format_ref_marker($refs, $commit);
my %ad = parse_date($co{'author_epoch'});
git_print_header_div('commit',
"<span class=\"age\">$co{'age_string'}</span>" .
@@ -3688,6 +3685,12 @@ sub git_log {
git_print_log($co{'comment'}, -final_empty_line=> 1);
print "</div>\n";
}
+ if ($#commitlist >= 100) {
+ print "<div class=\"page_nav\">\n";
+ print $cgi->a({-href => href(action=>"log", hash=>$hash, page=>$page+1),
+ -accesskey => "n", -title => "Alt-n"}, "next");
+ print "</div>\n";
+ }
git_footer_html();
}
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 5/8] gitweb: Change header search action to use parse_commits.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <11669707101872-git-send-email-robfitz@273k.net>
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 23 +++++++++--------------
1 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 42b7449..53dd225 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2910,18 +2910,18 @@ sub git_heads_body {
}
sub git_search_grep_body {
- my ($greplist, $from, $to, $extra) = @_;
+ my ($commitlist, $from, $to, $extra) = @_;
$from = 0 unless defined $from;
- $to = $#{$greplist} if (!defined $to || $#{$greplist} < $to);
+ $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
print "<table class=\"grep\" cellspacing=\"0\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
- my $commit = $greplist->[$i];
- my %co = parse_commit($commit);
+ my %co = %{$commitlist->[$i]};
if (!%co) {
next;
}
+ my $commit = $co{'id'};
if ($alternate) {
print "<tr class=\"dark\">\n";
} else {
@@ -4307,13 +4307,8 @@ sub git_search {
} elsif ($searchtype eq 'committer') {
$greptype = "--committer=";
}
- open my $fd, "-|", git_cmd(), "rev-list",
- ("--max-count=" . (100 * ($page+1))),
- ($greptype . $searchtext),
- $hash, "--"
- or next;
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ $greptype .= $searchtext;
+ my @commitlist = parse_commits($hash, 101, (100 * $page), $greptype);
my $paging_nav = '';
if ($page > 0) {
@@ -4330,7 +4325,7 @@ sub git_search {
$paging_nav .= "first";
$paging_nav .= " ⋅ prev";
}
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($#commitlist >= 100) {
$paging_nav .= " ⋅ " .
$cgi->a({-href => href(action=>"search", hash=>$hash,
searchtext=>$searchtext, searchtype=>$searchtype,
@@ -4340,7 +4335,7 @@ sub git_search {
$paging_nav .= " ⋅ next";
}
my $next_link = '';
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($#commitlist >= 100) {
$next_link =
$cgi->a({-href => href(action=>"search", hash=>$hash,
searchtext=>$searchtext, searchtype=>$searchtype,
@@ -4350,7 +4345,7 @@ sub git_search {
git_print_page_nav('','', $hash,$co{'tree'},$hash, $paging_nav);
git_print_header_div('commit', esc_html($co{'title'}), $hash);
- git_search_grep_body(\@revlist, ($page * 100), $#revlist, $next_link);
+ git_search_grep_body(\@commitlist, 0, 99, $next_link);
}
if ($searchtype eq 'pickaxe') {
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 3/8] gitweb: Change summary, shortlog actions to use parse_commits.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <11669707094097-git-send-email-robfitz@273k.net>
Also added missing accesskey.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 34 ++++++++++++----------------------
1 files changed, 12 insertions(+), 22 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index c645686..5f1ace9 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2704,20 +2704,19 @@ sub git_project_list_body {
sub git_shortlog_body {
# uses global variable $project
- my ($revlist, $from, $to, $refs, $extra) = @_;
+ my ($commitlist, $from, $to, $refs, $extra) = @_;
my $have_snapshot = gitweb_have_snapshot();
$from = 0 unless defined $from;
- $to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
+ $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
print "<table class=\"shortlog\" cellspacing=\"0\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
- my $commit = $revlist->[$i];
- #my $ref = defined $refs ? format_ref_marker($refs, $commit) : '';
+ my %co = %{$commitlist->[$i]};
+ my $commit = $co{'id'};
my $ref = format_ref_marker($refs, $commit);
- my %co = parse_commit($commit);
if ($alternate) {
print "<tr class=\"dark\">\n";
} else {
@@ -3081,14 +3080,10 @@ sub git_summary {
# we need to request one more than 16 (0..15) to check if
# those 16 are all
- open my $fd, "-|", git_cmd(), "rev-list", "--max-count=17",
- $head, "--"
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ my @commitlist = parse_commits($head, 17);
git_print_header_div('shortlog');
- git_shortlog_body(\@revlist, 0, 15, $refs,
- $#revlist <= 15 ? undef :
+ git_shortlog_body(\@commitlist, 0, 15, $refs,
+ $#commitlist <= 15 ? undef :
$cgi->a({-href => href(action=>"shortlog")}, "..."));
if (@taglist) {
@@ -4456,26 +4451,21 @@ sub git_shortlog {
}
my $refs = git_get_references();
- my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
- open my $fd, "-|", git_cmd(), "rev-list", $limit, $hash, "--"
- or die_error(undef, "Open git-rev-list failed");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd;
+ my @commitlist = parse_commits($head, 101, (100 * $page));
- my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist);
+ my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, (100 * ($page+1)));
my $next_link = '';
- if ($#revlist >= (100 * ($page+1)-1)) {
+ if ($#commitlist >= 100) {
$next_link =
$cgi->a({-href => href(action=>"shortlog", hash=>$hash, page=>$page+1),
- -title => "Alt-n"}, "next");
+ -accesskey => "n", -title => "Alt-n"}, "next");
}
-
git_header_html();
git_print_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav);
git_print_header_div('summary', $project);
- git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link);
+ git_shortlog_body(\@commitlist, 0, 99, $refs, $next_link);
git_footer_html();
}
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 2/8] gitweb: We do longer need the --parents flag in rev-list.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
In-Reply-To: <11669707092427-git-send-email-robfitz@273k.net>
We only want to know the direct parents of a given commit object,
these parents are available in the --header output of rev-list. If
--parents is supplied with --full-history the output includes merge
commits that aren't relevant.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 6bd57a4..c645686 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1281,13 +1281,14 @@ sub parse_commit_text {
if (!($header =~ m/^[0-9a-fA-F]{40}/)) {
return;
}
- ($co{'id'}, my @parents) = split ' ', $header;
- $co{'parents'} = \@parents;
- $co{'parent'} = $parents[0];
+ $co{'id'} = $header;
+ my @parents;
while (my $line = shift @commit_lines) {
last if $line eq "\n";
if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) {
$co{'tree'} = $1;
+ } elsif ($line =~ m/^parent ([0-9a-fA-F]{40})$/) {
+ push @parents, $1;
} elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) {
$co{'author'} = $1;
$co{'author_epoch'} = $2;
@@ -1314,6 +1315,8 @@ sub parse_commit_text {
if (!defined $co{'tree'}) {
return;
};
+ $co{'parents'} = \@parents;
+ $co{'parent'} = $parents[0];
foreach my $title (@commit_lines) {
$title =~ s/^ //;
@@ -1371,7 +1374,6 @@ sub parse_commit {
open my $fd, "-|", git_cmd(), "rev-list",
"--header",
- "--parents",
"--max-count=1",
$commit_id,
"--",
@@ -1414,7 +1416,6 @@ sub parse_commits {
open my $fd, "-|", git_cmd(), "rev-list",
"--header",
- "--parents",
($arg ? ($arg) : ()),
("--max-count=" . $maxcount),
# Add once rev-list supports the --skip option
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 1/8] gitweb: Add parse_commits, used to bulk load commit objects.
From: Robert Fitzsimons @ 2006-12-24 14:31 UTC (permalink / raw)
To: git; +Cc: Robert Fitzsimons
Add a new method parse_commits which is able to parse multiple commit
objects at once. Reworked parse_commit to share the commit object
parsing logic.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
gitweb/gitweb.perl | 91 ++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 74 insertions(+), 17 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index d01d689..6bd57a4 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1270,25 +1270,13 @@ sub parse_tag {
return %tag
}
-sub parse_commit {
- my $commit_id = shift;
- my $commit_text = shift;
-
- my @commit_lines;
+sub parse_commit_text {
+ my ($commit_text) = @_;
+ my @commit_lines = split '\n', $commit_text;
my %co;
- if (defined $commit_text) {
- @commit_lines = @$commit_text;
- } else {
- local $/ = "\0";
- open my $fd, "-|", git_cmd(), "rev-list",
- "--header", "--parents", "--max-count=1",
- $commit_id, "--"
- or return;
- @commit_lines = split '\n', <$fd>;
- close $fd or return;
- pop @commit_lines;
- }
+ pop @commit_lines; # Remove '\0'
+
my $header = shift @commit_lines;
if (!($header =~ m/^[0-9a-fA-F]{40}/)) {
return;
@@ -1375,6 +1363,75 @@ sub parse_commit {
return %co;
}
+sub parse_commit {
+ my ($commit_id) = @_;
+ my %co;
+
+ local $/ = "\0";
+
+ open my $fd, "-|", git_cmd(), "rev-list",
+ "--header",
+ "--parents",
+ "--max-count=1",
+ $commit_id,
+ "--",
+ or die_error(undef, "Open git-rev-list failed");
+ %co = parse_commit_text(<$fd>);
+ close $fd;
+
+ return %co;
+}
+
+sub parse_commits {
+ my ($commit_id, $maxcount, $skip, $arg, $filename) = @_;
+ my @cos;
+
+ $maxcount ||= 1;
+ $skip ||= 0;
+
+ # Delete once rev-list supports the --skip option
+ if ($skip > 0) {
+ open my $fd, "-|", git_cmd(), "rev-list",
+ ($arg ? ($arg) : ()),
+ ("--max-count=" . ($maxcount + $skip)),
+ $commit_id,
+ "--",
+ ($filename ? ($filename) : ())
+ or die_error(undef, "Open git-rev-list failed");
+ while (my $line = <$fd>) {
+ if ($skip-- <= 0) {
+ chomp $line;
+ my %co = parse_commit($line);
+ push @cos, \%co;
+ }
+ }
+ close $fd;
+
+ return wantarray ? @cos : \@cos;
+ }
+
+ local $/ = "\0";
+
+ open my $fd, "-|", git_cmd(), "rev-list",
+ "--header",
+ "--parents",
+ ($arg ? ($arg) : ()),
+ ("--max-count=" . $maxcount),
+ # Add once rev-list supports the --skip option
+ # ("--skip=" . $skip),
+ $commit_id,
+ "--",
+ ($filename ? ($filename) : ())
+ or die_error(undef, "Open git-rev-list failed");
+ while (my $line = <$fd>) {
+ my %co = parse_commit_text($line);
+ push @cos, \%co;
+ }
+ close $fd;
+
+ return wantarray ? @cos : \@cos;
+}
+
# parse ref from ref_file, given by ref_id, with given type
sub parse_ref {
my $ref_file = shift;
--
1.4.4.3.ge655-dirty
^ permalink raw reply related
* [PATCH 0/8] gitweb: Bulk load commit objects
From: Robert Fitzsimons @ 2006-12-24 14:30 UTC (permalink / raw)
To: git
The following is a set of patchs which should improve the preformance of
gitweb by bulk loading commit objects.
Note's:
* With a slight change in command line options and the parsing logic it
was possible to bulk load the history action aswell.
* Even without the rev-list --skip option there should be some
improvement as it is possible to bulk load the first page of commit
object.
[PATCH 1/8] gitweb: Add parse_commits, used to bulk load commit objects.
[PATCH 2/8] gitweb: We do longer need the --parents flag in rev-list.
Base support for bulk loading commit objects.
[PATCH 3/8] gitweb: Change summary, shortlog actions to use parse_commits.
[PATCH 4/8] gitweb: Change log action to use parse_commits.
[PATCH 5/8] gitweb: Change header search action to use parse_commits.
[PATCH 6/8] gitweb: Change atom, rss actions to use parse_commits.
[PATCH 7/8] gitweb: Change history action to use parse_commits.
Convert all the commit listing actions (except pickaxe search) to use
parse_commits, also fixes up a few nav links.
[PATCH 8/8] gitweb: Use rev-list --skip option.
This change requires the rev-list --skip change from next to have
been merged.
Robert
^ permalink raw reply
* Re: i18n.logToUTF8: convert commit log message to UTF-8
From: Johannes Schindelin @ 2006-12-24 14:18 UTC (permalink / raw)
To: git, junkio
Hi,
I don't like the convention to add the encoding after a trailing NUL. I'd
rather have it as an "encoding blabl" header like the author and committer
headers. I.e.
-- snip --
tree 519fba5ec35f25cbac7f46574f214fb5eb95d2c8
parent 41c7c86ccbcb846cacf48c5e283983fa797cf37b
author Johannes Schindelin <Johannes.Schindelin@gmx.de> 1166969650 +0100
committer Johannes Schindelin <Johannes.Schindelin@gmx.de> 1166969650 +0100
encoding latin1
git-commit-tree: add encoding header if commitEncoding != utf-8
-- snap --
Our log routines all grok these commit objects.
And I would prefer commit-tree to fail if we explicitely ask for
conversion to UTF-8, but NO_ICONV is set, or reencoding fails for other
reasons.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED.
From: Johannes Schindelin @ 2006-12-24 13:22 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061224054723.GG8146@spearce.org>
Hi,
On Sun, 24 Dec 2006, Shawn O. Pearce wrote:
> diff --git a/diff.c b/diff.c
> index f14288b..244292a 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -1341,10 +1341,8 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
> fd = open(s->path, O_RDONLY);
> if (fd < 0)
> goto err_empty;
> - s->data = mmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);
> + s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);
> close(fd);
> - if (s->data == MAP_FAILED)
> - goto err_empty;
The only gripe I have here is that the old code could actually say where
the problem occurred ("cannot read data blob for <blabla>"), but that
probably does not matter so much, now that we can hardly run out of memory
on a decent machine, even using big packfiles.
> diff --git a/read-cache.c b/read-cache.c
> index b8d83cc..ca3efbb 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -798,7 +798,7 @@ int read_cache_from(const char *path)
> cache_mmap_size = st.st_size;
> errno = EINVAL;
> if (cache_mmap_size >= sizeof(struct cache_header) + 20)
> - cache_mmap = mmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
> + cache_mmap = xmmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
> }
> close(fd);
> if (cache_mmap == MAP_FAILED)
This MAP_FAILED no longer has anything to do with MAP_FAILED, but rather
with fstat failed, so you probably want to move that into an else
construct just before "close(fd);".
All in all it is a good change -- for the builtin programs.
But it is less good for the libification. Maybe it is time for a
discussion about the possible strategies to avoid dying in libgit.a?
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 6/7] Release pack windows before reporting out of memory.
From: Johannes Schindelin @ 2006-12-24 13:10 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061224054719.GF8146@spearce.org>
Hi,
a very cute idea that having x*alloc() in place you can just pluck in some
garbage collection. I like it.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 2/7] Switch git_mmap to use pread.
From: Johannes Schindelin @ 2006-12-24 13:09 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061224054547.GB8146@spearce.org>
Hi,
On Sun, 24 Dec 2006, Shawn O. Pearce wrote:
> Now that Git depends on pread in index-pack its safe to say we can
> also depend on it within the git_mmap emulation we activate when
> NO_MMAP is set. On most systems pread should be slightly faster
> than an lseek/read/lseek sequence as its one system call vs. three
> system calls.
I don't think it matters much. The _only_ platform we really use NO_MMAP
(other than for testing) is Windows, and AFAICT it does not have pread(),
so it is emulated by lseek/read/lseek anyway.
But it's a cleanup, and it deletes more lines than it adds, so Ack from
me.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC] git reflog show
From: Johannes Schindelin @ 2006-12-24 12:49 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061224061151.GE7443@spearce.org>
Hi,
On Sun, 24 Dec 2006, Shawn Pearce wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > I wonder if it would make sense to teach the revision walking machinery
> > about reflogs. A commit could be marked as coming from a reflog entry, and
> > in that case the parents could be determined by the reflog rather than the
> > commit itself.
>
> The revision machinery already knows about reflogs with --reflog,
> used by git-pack-objects via git-repack. But here its really only
> useful to seed the list of commits to be walked as part of a pack
> generation, to make sure the things referenced by the reflog stay
> around after a repacking. And it implies --all.
Ah. I think it is a bit misnamed.
Besides, --reflog options of pack-objects, show-branch and general
revision-walk based programs are independent.
I propose to change the behaviour of "--reflog" in revision.c (which
should not have a big impact, since it is not even documented yet):
- if --all-reflog is passed, include all reflogs (part of the current
behaviour of --reflog), and
- if --reflog is passed, write the reflog messages in addition to the
commit lines, and rewrite the parent(s).
> Rewriting the commits in memory to appear to have parents based
> on their order of appearence in the reflog would nicely generate
> a single strand of perls, but it makes it difficult to then access
> the same commit's real parents, doesn't it? So that may make the
> revision machinary somewhat limited in some applications.
Uhm, we rewrite parents all the time. Just think about "git log Makefile".
> Besides we want the reflog message entry and not the commit message
> when we perform pretty output, etc. So really we are then talking
> about generating synthetic commit objects for the reflog data.
Yes, but if we have to read the reflog anyway to determine the logical
(local) parent, we can just as well read the message, and display it, too.
What it buys us is that we do not duplicate efforts here, and we can
easily visualize the reflog in gitk, too.
Ciao,
Dscho
^ permalink raw reply
* [RFC/PATCH] Enhance git-reflog with 'show' subcommand.
From: Shawn O. Pearce @ 2006-12-24 10:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
We now have a 'show' subcommand to 'git reflog' which dumps out the
contents of the reflog for each ref supplied on the command line,
or 'HEAD' if no ref is supplied.
Entries from the reflogs are sorted by reverse timestamp and then
by reverse order of appearance within the reflog. This replicates
the behavior of 'git log' where newer commits are shown first and
commits are ordered by timestamp when multiple refs are specified
on the command line.
Points in time in the reflog where a non-linear change occurred
(due to for example a rebase, reset or amend) are highlighed by
inserting 'R' in the first column of every line associated with
that log entry.
For example:
$ git reflog show sp/reflog-show
ref sp/reflog-show@{0}
commit 87d8af1.. -> f8ef360..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sun Dec 24 04:39:36 2006 -0500
commit: Enhance git-reflog with 'show' subcommand.
R ref sp/reflog-show@{1}
R commit 57e846c.. -> 87d8af1..
R User: Shawn O. Pearce <spearce@spearce.org>
R Date: Sun Dec 24 00:49:47 2006 -0500
R
R reset --soft
R to "fix macos x build"
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
This is an updated version of my earlier '[RFC] git reflog show'
patch. Lots of bugs have been fixed, I removed the totally
unnecessary need for qsort(), and refs can now be supplied in
shorthand format just like with 'git log'.
One of the _really_ ugly parts of this patch is the duplication
of the fmt table from sha1_refs.c. The shorthand ref -> full ref
name code should be refactored out first. I'm being lazy and not
doing it right now. :-)
I have taken Junio's suggestion of making non-linear changes stand
out more by placing 'R' in the first column of every relevant line
in the log, this visually stands out pretty good without applying
any coloring. Coloring would be nice for people who do that sort
of thing. ;-)
Earlier Junio had suggested that the reflog display should use some
form of graphical (albeit text mode) representation to indicate
how entries relate to each other within the reflog. I'm not sure
that's possible when you get into complex logs where resets and
rebases happen frequently. I for one am not sure how I would
draw some logs.
builtin-reflog.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
git.c | 2 +-
2 files changed, 269 insertions(+), 2 deletions(-)
diff --git a/builtin-reflog.c b/builtin-reflog.c
index de31967..6ee7fd3 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -198,8 +198,273 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
return status;
}
+struct cmd_reflog_list_ref {
+ struct cmd_reflog_list_ref *next;
+ struct cmd_reflog_list_ent *entries;
+ const char *name;
+ unsigned int ent_cnt;
+};
+
+struct cmd_reflog_list_ent {
+ struct cmd_reflog_list_ent *next;
+ struct commit *old;
+ struct commit *new;
+ char *cmd;
+ char *user;
+ unsigned long timestamp;
+ int tz;
+ unsigned int pos;
+ unsigned linear:1;
+ unsigned char old_sha1[20];
+ unsigned char new_sha1[20];
+};
+
+struct cmd_reflog_list_cb {
+ struct cmd_reflog_list_ref *refs;
+ struct cmd_reflog_list_ref *cur_ref;
+ unsigned include_linear_commits:1;
+};
+
+static int list_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+ char *data, void *cb_data)
+{
+ struct cmd_reflog_list_cb *cb = cb_data;
+ struct cmd_reflog_list_ref *cur_ref = cb->cur_ref;
+ struct cmd_reflog_list_ent *e;
+ struct commit *old, *new;
+ unsigned long timestamp;
+ int tz;
+ char *user_end, *cp, *ep;
+
+ cur_ref->ent_cnt++;
+ cp = strchr(data, '>');
+ if (!cp || *++cp != ' ')
+ return 0; /* corrupt line? */
+ user_end = cp;
+ timestamp = strtoul(cp, &ep, 10);
+ if (*ep++ != ' ')
+ return 0; /* corrupt line? */
+ tz = strtol(ep, &cp, 10);
+ if (*cp++ != '\t')
+ return 0; /* corrupt line? */
+ while (isspace(*cp))
+ cp++;
+
+ if (is_null_sha1(osha1))
+ old = NULL;
+ else
+ old = lookup_commit_reference_gently(osha1, 1);
+
+ if (is_null_sha1(nsha1))
+ new = NULL;
+ else
+ new = lookup_commit_reference_gently(nsha1, 1);
+
+ if (!cb->include_linear_commits
+ && old && new && new->parents
+ && new->parents->item == old
+ && !new->parents->next
+ && cur_ref->entries && cur_ref->entries->new == old
+ && (!strncmp(cp, "commit", 6) || !strncmp(cp, "am: ", 4)))
+ return 0;
+
+ e = xmalloc(sizeof(*e));
+ e->cmd = xstrdup(cp);
+ cp = strrchr(e->cmd, '\n');
+ if (cp)
+ *cp = 0;
+ if (*e->cmd) {
+ cp = e->cmd + strlen(e->cmd) - 1;
+ while (isspace(*cp))
+ *cp-- = 0;
+ }
+ e->user = xmalloc(user_end - data + 1);
+ strncpy(e->user, data, user_end - data);
+ e->user[user_end - data] = 0;
+ e->timestamp = timestamp;
+ e->tz = tz;
+ e->pos = cur_ref->ent_cnt - 1;
+ e->old = old;
+ e->new = new;
+ hashcpy(e->old_sha1, osha1);
+ hashcpy(e->new_sha1, nsha1);
+
+ if (new && cur_ref->entries && cur_ref->entries->new)
+ e->linear = in_merge_bases(cur_ref->entries->new, new);
+ else if (!e->pos)
+ e->linear = 1;
+ else
+ e->linear = 0;
+
+ e->next = cur_ref->entries;
+ cur_ref->entries = e;
+ return 0;
+}
+
+static int list_reflog(const char *ref, const unsigned char *sha1,
+ int unused, void *cb_data)
+{
+ struct cmd_reflog_list_cb *cb = cb_data;
+
+ cb->cur_ref = xmalloc(sizeof(*cb->cur_ref));
+ cb->cur_ref->name = xstrdup(ref);
+ cb->cur_ref->ent_cnt = 0;
+ cb->cur_ref->entries = NULL;
+ cb->cur_ref->next = cb->refs;
+ cb->refs = cb->cur_ref;
+
+ for_each_reflog_ent(ref, list_reflog_ent, cb);
+ return 0;
+}
+
+static void reflog_show_pfx(struct cmd_reflog_list_ent *e)
+{
+ printf("%c ", e->linear ? ' ' : 'R');
+}
+
+static void reflog_show_cmtid(int abbrev,
+ unsigned char *sha1,
+ struct commit *cmt)
+{
+ if (cmt)
+ printf("%s..", find_unique_abbrev(sha1, abbrev));
+ else if (!is_null_sha1(sha1))
+ printf("%s (missing)", sha1_to_hex(sha1));
+ else
+ printf("deleted");
+}
+
+static void reflog_show(int abbrev,
+ struct cmd_reflog_list_ref *ref,
+ struct cmd_reflog_list_ent *e)
+{
+ const char *name = ref->name;
+ if (!strncmp("refs/tags/", name, 10))
+ name += 10;
+ else if (!strncmp("refs/heads/", name, 11))
+ name += 11;
+ else if (!strncmp("refs/remotes/", name, 13))
+ name += 13;
+
+ reflog_show_pfx(e);
+ printf("ref %s@{%u}\n", name, ref->ent_cnt - e->pos - 1);
+
+ reflog_show_pfx(e);
+ printf("commit ");
+ reflog_show_cmtid(abbrev, e->old_sha1, e->old);
+ printf(" -> ");
+ reflog_show_cmtid(abbrev, e->new_sha1, e->new);
+ printf("\n");
+
+ reflog_show_pfx(e);
+ printf("User: %s\n", e->user);
+
+ reflog_show_pfx(e);
+ printf("Date: %s\n", show_date(e->timestamp, e->tz, 0));
+
+ reflog_show_pfx(e);
+ printf("\n");
+
+ reflog_show_pfx(e);
+ printf(" %s\n", e->cmd);
+
+ /* Historically some commands have not logged very much detail.
+ * We should dump out the oneline of the new commit to help.
+ */
+ if (e->new && (!strcmp(e->cmd, "reset --hard")
+ || !strcmp(e->cmd, "reset --soft")
+ || !strncmp(e->cmd, "fetch ", 6)
+ || !strncmp(e->cmd, "merge ", 6)
+ || !strncmp(e->cmd, "pull ", 5))) {
+ char subject[256];
+ pretty_print_commit(CMIT_FMT_ONELINE, e->new, ~0,
+ subject, sizeof(subject), 0,
+ NULL, NULL, 0);
+ reflog_show_pfx(e);
+ printf(" to \"%s\"\n", subject);
+ }
+
+ printf("\n");
+}
+
+static const char reflog_show_usage[] =
+"git-reflog show [--all|<refs>...]";
+
+static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
+{
+ struct cmd_reflog_list_cb cb;
+ unsigned char sha1[20];
+ int i, do_all = 0, status = 0;
+
+ cb.refs = NULL;
+ cb.cur_ref = NULL;
+ cb.include_linear_commits = 1;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(arg, "--all"))
+ do_all = 1;
+ else if (!strcmp(arg, "--no-commits"))
+ cb.include_linear_commits = 0;
+ else if (arg[0] == '-')
+ usage(reflog_show_usage);
+ else
+ break;
+ }
+ if (do_all)
+ status |= for_each_ref(list_reflog, &cb);
+ if (i == argc) {
+ const char *ref = resolve_ref("HEAD", sha1, 1, NULL);
+ if (ref)
+ status |= list_reflog(ref, sha1, 0, &cb);
+ else
+ status |= error("no such ref: HEAD");
+ }
+ while (i < argc) {
+ static const char *fmt[] = {
+ "%.*s",
+ "refs/%.*s",
+ "refs/tags/%.*s",
+ "refs/heads/%.*s",
+ "refs/remotes/%.*s",
+ "refs/remotes/%.*s/HEAD",
+ NULL
+ };
+ const char *arg = argv[i++], **p;
+ for (p = fmt; *p; p++) {
+ const char *ref = mkpath(*p, strlen(arg), arg);
+ ref = resolve_ref(ref, sha1, 1, NULL);
+ if (ref) {
+ status |= list_reflog(ref, sha1, 0, &cb);
+ break;
+ }
+ }
+ if (!*p)
+ status |= error("no such ref: %s", arg);
+ }
+
+ for (;;) {
+ struct cmd_reflog_list_ref *r, *min_r = NULL;
+ struct cmd_reflog_list_ent *e;
+ for (r = cb.refs; r; r = r->next) {
+ if (!r->entries)
+ continue;
+ if (!min_r
+ || r->entries->timestamp > min_r->entries->timestamp)
+ min_r = r;
+ }
+ if (!min_r)
+ break;
+ e = min_r->entries;
+ min_r->entries = e->next;
+ reflog_show(DEFAULT_ABBREV, min_r, e);
+ }
+
+ return status;
+}
+
static const char reflog_usage[] =
-"git-reflog (expire | ...)";
+"git-reflog (expire | show | ...)";
int cmd_reflog(int argc, const char **argv, const char *prefix)
{
@@ -207,6 +472,8 @@ int cmd_reflog(int argc, const char **argv, const char *prefix)
usage(reflog_usage);
else if (!strcmp(argv[1], "expire"))
return cmd_reflog_expire(argc - 1, argv + 1, prefix);
+ else if (!strcmp(argv[1], "show"))
+ return cmd_reflog_show(argc - 1, argv + 1, prefix);
else
usage(reflog_usage);
}
diff --git a/git.c b/git.c
index 50ebd86..27bbc75 100644
--- a/git.c
+++ b/git.c
@@ -246,7 +246,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "prune-packed", cmd_prune_packed, RUN_SETUP },
{ "push", cmd_push, RUN_SETUP },
{ "read-tree", cmd_read_tree, RUN_SETUP },
- { "reflog", cmd_reflog, RUN_SETUP },
+ { "reflog", cmd_reflog, RUN_SETUP | USE_PAGER },
{ "repo-config", cmd_repo_config },
{ "rerere", cmd_rerere, RUN_SETUP },
{ "rev-list", cmd_rev_list, RUN_SETUP },
--
1.4.4.3.g389e
^ permalink raw reply related
* Re: [PATCH 0/17] Sliding window mmap for packfiles.
From: Shawn Pearce @ 2006-12-24 9:49 UTC (permalink / raw)
To: Francis Moreau; +Cc: Junio C Hamano, git
In-Reply-To: <38b2ab8a0612240136r559376d4s14af3123f762a45d@mail.gmail.com>
Francis Moreau <francis.moro@gmail.com> wrote:
> On 12/24/06, Shawn Pearce <spearce@spearce.org> wrote:
> >However with this series even a 32 bit OS which only permits
> >processes to have at most 2 GiB of address space (2 GiB split
> >between kernel space and userspace) can access packfiles up
> >to 4 GiB in size. That seems to be the split most OSes wind
> >up using, if they didn't push it out to 3.2 GiB like Linux
> >and Solaris have done.
> >
>
> Does it still needed for 64 bit OS ?
Not really. Almost any reasonable 64 bit OS which is also running
a Git compiled for 64 bit userspace would be able to mmap multiple
4 GiB packfiles without this series.
> if not, can the overhead (if there is a significant one) implied by
> your rework be avoid for such cases ?
The overhead is rather low. I did try hard to make it only a handful
of machine instructions worth of additional work, and even then I
tried to ammortize those over relatively large blocks of data to
reduce the impact. But yes, there is an overhead over the current
shipping version of Git.
However at least some of the overhead can be avoided by setting
core.packedGitWindowSize and core.packedGitLimit to higher values.
This will allow the implementation to mmap() larger windows of the
packfiles and retain a greater number of windows in memory at once.
If core.packedGitWindowSize is larger than your largest packfile
then most of the code will just "shutoff" and won't get in the way.
Its default is 32 MiB (see Documentation/config.txt).
I think the additional overhead added by this series is neglible
and worth the more graceful degredation it allows when virtual
address space becomes limited.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 0/17] Sliding window mmap for packfiles.
From: Francis Moreau @ 2006-12-24 9:36 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061224090508.GF7443@spearce.org>
On 12/24/06, Shawn Pearce <spearce@spearce.org> wrote:
> Francis Moreau <francis.moro@gmail.com> wrote:
> > On 12/23/06, Shawn O. Pearce <spearce@spearce.org> wrote:
> > >This 17 patch series implements my much discussed, but never produced
> > [snip]
> > >
> > >This series also permits accessing packfiles up to 4 GiB in size,
> > >even on systems which permit only 2 GiB of virtual memory within
> > >a single process (e.g. Windows and some older UNIXes). Of course
> >
> > Just out of curiosity, do you mean that there are some OS running on
> > 32 bits machines which allow 4GiB size of virtual memory within a
> > single process ? If so, could you give an example of such OS ?
>
> No. What I meant was the Git packfile/index format currently
> supports up to 4 GiB of data in a single packfile. But *no*
> OS using 32 bit virtual address space would permit us to access
> that packfile prior to this series as we would have *no* memory
> left for a stack, let alone for parsing commits, etc., as *all*
> of the address space would have been dedicated to the packfile.
>
ok.
> However with this series even a 32 bit OS which only permits
> processes to have at most 2 GiB of address space (2 GiB split
> between kernel space and userspace) can access packfiles up
> to 4 GiB in size. That seems to be the split most OSes wind
> up using, if they didn't push it out to 3.2 GiB like Linux
> and Solaris have done.
>
Does it still needed for 64 bit OS ?
if not, can the overhead (if there is a significant one) implied by
your rework be avoid for such cases ?
> This series is a good change because Git can now really make
> full use of the space allowed by a single packfile. :-)
>
Yes I agree with you.
--
Francis
^ permalink raw reply
* Re: [PATCH 0/17] Sliding window mmap for packfiles.
From: Linus Torvalds @ 2006-12-24 9:29 UTC (permalink / raw)
To: Francis Moreau; +Cc: Shawn O. Pearce, Junio C Hamano, git
In-Reply-To: <38b2ab8a0612240056k152344ael891e9b0b9f8cbc47@mail.gmail.com>
On Sun, 24 Dec 2006, Francis Moreau wrote:
>
> Just out of curiosity, do you mean that there are some OS running on
> 32 bits machines which allow 4GiB size of virtual memory within a
> single process ? If so, could you give an example of such OS ?
Actually, Linux will do it on certain architectures (some architectures
have separate "address spaces" for kernel and user). And even on x86, if
you apply the (insane) 4GB patches, user space will actually have almost
all of the 4GB, because there's only a _tiny_ trampoline thing that
switches the whole page table around that is kernel-mapped and takes away
from the 4GB thing.
In practice, though, most 32-bit architectures will have between 1-3GB of
user virtual memory. And obviously stack space, binaries, heap etc take up
space, so you often end up with with just ~0.5 GB of actual dependable
contiguous virtual memory.
Linus
^ permalink raw reply
* Re: [PATCH 0/17] Sliding window mmap for packfiles.
From: Shawn Pearce @ 2006-12-24 9:05 UTC (permalink / raw)
To: Francis Moreau; +Cc: Junio C Hamano, git
In-Reply-To: <38b2ab8a0612240056k152344ael891e9b0b9f8cbc47@mail.gmail.com>
Francis Moreau <francis.moro@gmail.com> wrote:
> On 12/23/06, Shawn O. Pearce <spearce@spearce.org> wrote:
> >This 17 patch series implements my much discussed, but never produced
> [snip]
> >
> >This series also permits accessing packfiles up to 4 GiB in size,
> >even on systems which permit only 2 GiB of virtual memory within
> >a single process (e.g. Windows and some older UNIXes). Of course
>
> Just out of curiosity, do you mean that there are some OS running on
> 32 bits machines which allow 4GiB size of virtual memory within a
> single process ? If so, could you give an example of such OS ?
No. What I meant was the Git packfile/index format currently
supports up to 4 GiB of data in a single packfile. But *no*
OS using 32 bit virtual address space would permit us to access
that packfile prior to this series as we would have *no* memory
left for a stack, let alone for parsing commits, etc., as *all*
of the address space would have been dedicated to the packfile.
However with this series even a 32 bit OS which only permits
processes to have at most 2 GiB of address space (2 GiB split
between kernel space and userspace) can access packfiles up
to 4 GiB in size. That seems to be the split most OSes wind
up using, if they didn't push it out to 3.2 GiB like Linux
and Solaris have done.
This series is a good change because Git can now really make
full use of the space allowed by a single packfile. :-)
--
Shawn.
^ permalink raw reply
* Re: [PATCH 0/17] Sliding window mmap for packfiles.
From: Francis Moreau @ 2006-12-24 8:56 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20061223073317.GA9837@spearce.org>
Hi,
On 12/23/06, Shawn O. Pearce <spearce@spearce.org> wrote:
> This 17 patch series implements my much discussed, but never produced
[snip]
>
> This series also permits accessing packfiles up to 4 GiB in size,
> even on systems which permit only 2 GiB of virtual memory within
> a single process (e.g. Windows and some older UNIXes). Of course
Just out of curiosity, do you mean that there are some OS running on
32 bits machines which allow 4GiB size of virtual memory within a
single process ? If so, could you give an example of such OS ?
thanks
--
Francis
^ permalink raw reply
* Re: confusion over the new branch and merge config
From: Jeff King @ 2006-12-24 6:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nicolas Pitre, git
In-Reply-To: <7vbqlvrldk.fsf@assigned-by-dhcp.cox.net>
On Sat, Dec 23, 2006 at 01:51:03AM -0800, Junio C Hamano wrote:
> If you (or other people) use branch.*.merge, with its value set
> to remote name _and_ local name, and actually verify that either
> form works without confusion, please report back and I'll apply.
I am happy to try this out and report back. However, I'm out of town for
the holidays, so I won't have anything useful to say until next week.
-Peff
^ permalink raw reply
* Re: [RFC] git reflog show
From: Shawn Pearce @ 2006-12-24 6:11 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612231552140.19693@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> I wonder if it would make sense to teach the revision walking machinery
> about reflogs. A commit could be marked as coming from a reflog entry, and
> in that case the parents could be determined by the reflog rather than the
> commit itself.
The revision machinery already knows about reflogs with --reflog,
used by git-pack-objects via git-repack. But here its really only
useful to seed the list of commits to be walked as part of a pack
generation, to make sure the things referenced by the reflog stay
around after a repacking. And it implies --all.
Rewriting the commits in memory to appear to have parents based
on their order of appearence in the reflog would nicely generate
a single strand of perls, but it makes it difficult to then access
the same commit's real parents, doesn't it? So that may make the
revision machinary somewhat limited in some applications.
Besides we want the reflog message entry and not the commit message
when we perform pretty output, etc. So really we are then talking
about generating synthetic commit objects for the reflog data.
--
Shawn.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox