* Re: [PATCH] Documentation/git-commit: rewrite to make it more end-user friendly.
From: Junio C Hamano @ 2006-12-10 23:05 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: git, J. Bruce Fields
In-Reply-To: <Pine.LNX.4.64.0612101704390.2630@xanadu.home>
Nicolas Pitre <nico@cam.org> writes:
>> Man pages are reference documentation, so I figure it's OK to sacrifice
>> a little newbie-friendliness for accuracy and concision.
>
> I disagree. Clarity should be the first goal. And the fact that even
> modified files have to be specified is something worth enphasizing,
> especially since this is not something other systems do.
Let's keep plumbing documentation technical reference material,
but allow more newbie friendliness in Porcelain-ish
documentation.
^ permalink raw reply
* Re: [PATCH 3/3] add test case for recursive merge
From: Johannes Schindelin @ 2006-12-10 22:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Shawn O. Pearce, git
In-Reply-To: <7vmz5w5tuw.fsf@assigned-by-dhcp.cox.net>
Hi,
On Sat, 9 Dec 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > this test succeeds consistently on the machine where I tested it
> > originally, but fails on another of my machines, but only when run without
> > "-v". Very annoying. I will not have time to investigate until Monday,
> > though.
>
> There seem to be cases where stage #1 contains blob 'B' or 'A'
> or nothing depending on something totally random. Ring a bell?
Not at all.
It seems that one merge is conflicting on "a1", and not storing _anything_
in the resulting (unclean) tree. So, there is no stage 1.
However, I also saw that something is left in stage 1 on the box where the
problem arises. Tomorrow.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] remove "[PATCH]" prefix from shortlog output
From: Jakub Narebski @ 2006-12-10 23:10 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.63.0612102337090.28348@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin wrote:
> On Sat, 9 Dec 2006, Nicolas Pitre wrote:
>
>> This doesn't convey much information in the shortlog context.
>> And the perl version did strip it as well.
>
> From the current builtin-shortlog.c:128ff:
>
> if (!strncmp(oneline, "[PATCH", 6)) {
> char *eob = strchr(oneline, ']');
>
> if (eob) {
> while (isspace(eob[1]) && eob[1] != '\n')
> eob++;
> if (eob - oneline < onelinelen) {
> onelinelen -= eob - oneline;
> oneline = eob;
> }
> }
> }
>
> It tries not only to strip "[PATCH]", but also "[PATCH 0/n]" and basically
> every prefix beginning with "[PATCH" and ending in "]". I do not remember
> if I really tested that code, but it should work.
What happens if you have "[PATCH" without closing "]"? Does it work (and
doesn't crash)? Does it strip anything?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH 2/3] merge-recursive: make empty tree a known object
From: Johannes Schindelin @ 2006-12-10 23:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git, Shawn O. Pearce
In-Reply-To: <7vpsar2xom.fsf@assigned-by-dhcp.cox.net>
Hi,
On Sun, 10 Dec 2006, Junio C Hamano wrote:
> Implement "well known" built-in objects.
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Ciao,
^ permalink raw reply
* Re: Collection of stgit issues and wishes
From: Catalin Marinas @ 2006-12-10 23:24 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <200612110002.05847.jnareb@gmail.com>
On 10/12/06, Jakub Narebski <jnareb@gmail.com> wrote:
> Catalin Marinas wrote:
> > Yes, only for updating HEAD. The refs in refs/patches/<branch>/ are
> > written directly. I initialy wanted to add patch history support using
> > reflogs and added "git-update-ref -m ..." for the patch commits but I
> > found slow the pushing operation a bit. Do you only want to track the
> > reflogs for HEAD?
>
> Yes, I want for StGit to provide reasons when updating HEAD. I know that
> StGit manages it's own versioning of patches not using reflog -- fine.
> What matters for me is reflog for HEAD after "stg commit; stg clean".
Just curious, do you run the "stg commit; stg clean" commands together
and in this order? Neither of them would update the HEAD. The "commit"
command simply removes the StGIT metadata for the applied patches
since it no longer needs to track them (permanently stored to the
repository). It doesn't change HEAD. The "clean" command only affects
the HEAD if there are empty applied patches but after a "commit" there
won't be any patches (only the unapplied ones which do not affect
HEAD).
Maybe we could have reflog info for "push", "refresh", some undo
operations. Are they of any use (I haven't used them so I can't tell)?
--
^ permalink raw reply
* Re: [PATCH] remove "[PATCH]" prefix from shortlog output
From: Junio C Hamano @ 2006-12-10 23:32 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0612102337090.28348@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> It tries not only to strip "[PATCH]", but also "[PATCH 0/n]" and basically
> every prefix beginning with "[PATCH" and ending in "]". I do not remember
> if I really tested that code, but it should work.
The problem is that you forgot that the lines are indented when
acting as a filter.
How about this? It also contains the extra whitespace removal
from the author name.
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 7a2ddfe..3fc43dd 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -188,18 +188,25 @@ static void read_from_stdin(struct path_list *list)
bob = buffer + strlen(buffer);
else {
offset = 8;
- if (isspace(bob[-1]))
+ while (buffer + offset < bob &&
+ isspace(bob[-1]))
bob--;
}
while (fgets(buffer2, sizeof(buffer2), stdin) &&
buffer2[0] != '\n')
; /* chomp input */
- if (fgets(buffer2, sizeof(buffer2), stdin))
+ if (fgets(buffer2, sizeof(buffer2), stdin)) {
+ int l2 = strlen(buffer2);
+ int i;
+ for (i = 0; i < l2; i++)
+ if (!isspace(buffer2[i]))
+ break;
insert_author_oneline(list,
buffer + offset,
bob - buffer - offset,
- buffer2, strlen(buffer2));
+ buffer2 + i, l2 - i);
+ }
}
}
}
^ permalink raw reply related
* [PATCH] Make cvsexportcommit work with filenames with spaces and non-ascii characters.
From: Robin Rosenberg @ 2006-12-10 23:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3b7o8s5j.fsf@assigned-by-dhcp.cox.net>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 15050 bytes --]
From: Robin Rosenberg <robin.rosenberg@dewire.com>
This patch uses git-apply to do the patching which simplifies the code a lot
and also uses one pass to git-diff. git-apply gives information on added,
removed files as well as which files are binary.
Removed the test for checking for matching binary files when deleting them
since git-apply happily deletes the file. This is matter of taste since we
allow some fuzz for text patches also.
Error handling was cleaned up, but not much tested.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
Yet another version (maybe I'm learning perl now....). This one uses one pass
to git-diff, but compensates that with two to git-apply.
-- robin
git-cvsexportcommit.perl | 203 +++++++++++++---------------------------
t/t9200-git-cvsexportcommit.sh | 108 ++++++++++++++++-----
2 files changed, 145 insertions(+), 166 deletions(-)
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index c9d1d88..8f37123 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -2,9 +2,8 @@
# Known limitations:
# - does not propagate permissions
-# - tells "ready for commit" even when things could not be completed
-# (not sure this is true anymore, more testing is needed)
-# - does not handle whitespace in pathnames at all.
+# - error handling has not been extensively tested
+#
use strict;
use Getopt::Std;
@@ -115,49 +114,40 @@ if ($opt_a) {
}
close MSG;
-my (@afiles, @dfiles, @mfiles, @dirs);
-my %amodes;
-my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
-#print @files;
-$? && die "Error in git-diff-tree";
-foreach my $f (@files) {
- chomp $f;
- my @fields = split(m!\s+!, $f);
- if ($fields[4] eq 'A') {
- my $path = $fields[5];
- $amodes{$path} = $fields[1];
- push @afiles, $path;
- # add any needed parent directories
- $path = dirname $path;
- while (!-d $path and ! grep { $_ eq $path } @dirs) {
- unshift @dirs, $path;
- $path = dirname $path;
- }
- }
- if ($fields[4] eq 'M') {
- push @mfiles, $fields[5];
- }
- if ($fields[4] eq 'D') {
- push @dfiles, $fields[5];
- }
+`git-diff-tree --binary -p $parent $commit >.cvsexportcommit.diff`;# || die "Cannot diff";
+
+## apply non-binary changes
+my $fuzz = $opt_p ? 0 : 2;
+
+print "Checking if patch will apply\n";
+
+my @stat;
+open APPLY, "GIT_DIR= git-apply -C$fuzz --binary --summary --numstat<.cvsexportcommit.diff|" || die "cannot patch";
+@stat=<APPLY>;
+close APPLY || die "Cannot patch";
+my (@bfiles,@files,@afiles,@dfiles);
+chomp @stat;
+foreach (@stat) {
+ push (@bfiles,$1) if m/^\-\t\-\t(.*)$/;
+ push (@files,$1) if m/^\-\t\-\t(.*)$/;
+ push (@files, $1) if m/^\d+\t\d+\t(.*)$/;
+ push (@afiles,$1) if m/^ +create mode \d+ (.*)$/;
+ push (@dfiles,$1) if m/^ +delete mode \d{6} (.*)$/;
}
-my (@binfiles, @abfiles, @dbfiles, @bfiles, @mbfiles);
-@binfiles = grep m/^Binary files/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit);
-map { chomp } @binfiles;
-@abfiles = grep s/^Binary files \/dev\/null and b\/(.*) differ$/$1/, @binfiles;
-@dbfiles = grep s/^Binary files a\/(.*) and \/dev\/null differ$/$1/, @binfiles;
-@mbfiles = grep s/^Binary files a\/(.*) and b\/(.*) differ$/$1/, @binfiles;
-push @bfiles, @abfiles;
-push @bfiles, @dbfiles;
-push @bfiles, @mbfiles;
-push @mfiles, @mbfiles;
-
-$opt_v && print "The commit affects:\n ";
-$opt_v && print join ("\n ", @afiles,@mfiles,@dfiles) . "\n\n";
-undef @files; # don't need it anymore
+map { s/^"(.*)"$/$1/g } @bfiles,@files;
+map { s/\\([\d]{3})/sprintf('%c',oct $1)/eg } @bfiles,@files;
# check that the files are clean and up to date according to cvs
my $dirty;
+my @dirs;
+foreach my $p (@afiles) {
+ my $path = dirname $p;
+ while (!-d $path and ! grep { $_ eq $path } @dirs) {
+ unshift @dirs, $path;
+ $path = dirname $path;
+ }
+}
+
foreach my $d (@dirs) {
if (-e $d) {
$dirty = 1;
@@ -180,7 +170,8 @@ foreach my $f (@afiles) {
}
}
-foreach my $f (@mfiles, @dfiles) {
+foreach my $f (@files) {
+ next if grep { $_ eq $f } @afiles;
# TODO:we need to handle removed in cvs
my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
@@ -197,87 +188,26 @@ if ($dirty) {
}
}
-###
-### NOTE: if you are planning to die() past this point
-### you MUST call cleanupcvs(@files) before die()
-###
+print "Applying\n";
+`GIT_DIR= git-apply -C$fuzz --binary --summary --numstat --apply <.cvsexportcommit.diff` || die "cannot patch";
-
-print "Creating new directories\n";
+print "Patch applied successfully. Adding new files and directories to CVS\n";
+my $dirtypatch = 0;
foreach my $d (@dirs) {
- unless (mkdir $d) {
- warn "Could not mkdir $d: $!";
- $dirty = 1;
- }
- `cvs add $d`;
- if ($?) {
- $dirty = 1;
+ if (system('cvs','add',$d)) {
+ $dirtypatch = 1;
warn "Failed to cvs add directory $d -- you may need to do it manually";
}
}
-print "'Patching' binary files\n";
-
-foreach my $f (@bfiles) {
- # check that the file in cvs matches the "old" file
- # extract the file to $tmpdir and compare with cmp
- if (not(grep { $_ eq $f } @afiles)) {
- my $tree = safe_pipe_capture('git-rev-parse', "$parent^{tree}");
- chomp $tree;
- my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
- chomp $blob;
- `git-cat-file blob $blob > $tmpdir/blob`;
- if (system('cmp', '-s', $f, "$tmpdir/blob")) {
- warn "Binary file $f in CVS does not match parent.\n";
- if (not $opt_f) {
- $dirty = 1;
- next;
- }
- }
- }
- if (not(grep { $_ eq $f } @dfiles)) {
- my $tree = safe_pipe_capture('git-rev-parse', "$commit^{tree}");
- chomp $tree;
- my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
- chomp $blob;
- # replace with the new file
- `git-cat-file blob $blob > $f`;
- }
-
- # TODO: something smart with file modes
-
-}
-if ($dirty) {
- cleanupcvs(@files);
- die "Exiting: Binary files in CVS do not match parent";
-}
-
-## apply non-binary changes
-my $fuzz = $opt_p ? 0 : 2;
-
-print "Patching non-binary files\n";
-
-if (scalar(@afiles)+scalar(@dfiles)+scalar(@mfiles) != scalar(@bfiles)) {
- print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;
-}
-
-my $dirtypatch = 0;
-if (($? >> 8) == 2) {
- cleanupcvs(@files);
- die "Exiting: Patch reported serious trouble -- you will have to apply this patch manually";
-} elsif (($? >> 8) == 1) { # some hunks failed to apply
- $dirtypatch = 1;
-}
-
foreach my $f (@afiles) {
- set_new_file_permissions($f, $amodes{$f});
if (grep { $_ eq $f } @bfiles) {
system('cvs', 'add','-kb',$f);
} else {
system('cvs', 'add', $f);
}
if ($?) {
- $dirty = 1;
+ $dirtypatch = 1;
warn "Failed to cvs add $f -- you may need to do it manually";
}
}
@@ -285,35 +215,40 @@ foreach my $f (@afiles) {
foreach my $f (@dfiles) {
system('cvs', 'rm', '-f', $f);
if ($?) {
- $dirty = 1;
+ $dirtypatch = 1;
warn "Failed to cvs rm -f $f -- you may need to do it manually";
}
}
print "Commit to CVS\n";
-print "Patch: $title\n";
-my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
-my $cmd = "cvs commit -F .msg $commitfiles";
+print "Patch title (first comment line): $title\n";
+my @commitfiles = map { unless (m/\s/) { '\''.$_.'\''; } else { $_; }; } (@files);
+my $cmd = "cvs commit -F .msg @commitfiles";
if ($dirtypatch) {
print "NOTE: One or more hunks failed to apply cleanly.\n";
- print "Resolve the conflicts and then commit using:\n";
+ print "You'll need to apply the patch in .cvsexportcommit.diff manually\n";
+ print "using a patch program. After applying the patch and resolving the\n";
+ print "problems you may commit using:";
print "\n $cmd\n\n";
exit(1);
}
-
if ($opt_c) {
print "Autocommit\n $cmd\n";
- print safe_pipe_capture('cvs', 'commit', '-F', '.msg', @afiles, @mfiles, @dfiles);
+ print safe_pipe_capture('cvs', 'commit', '-F', '.msg', @files);
if ($?) {
- cleanupcvs(@files);
die "Exiting: The commit did not succeed";
}
print "Committed successfully to CVS\n";
} else {
print "Ready for you to commit, just run:\n\n $cmd\n";
}
+
+# clean up
+unlink(".cvsexportcommit.diff");
+unlink(".msg");
+
sub usage {
print STDERR <<END;
Usage: GIT_DIR=/path/to/.git ${\basename $0} [-h] [-p] [-v] [-c] [-f] [-m msgprefix] [ parent ] commit
@@ -321,17 +256,6 @@ END
exit(1);
}
-# ensure cvs is clean before we die
-sub cleanupcvs {
- my @files = @_;
- foreach my $f (@files) {
- system('cvs', '-q', 'update', '-C', $f);
- if ($?) {
- warn "Warning! Failed to cleanup state of $f\n";
- }
- }
-}
-
# An alternative to `command` that allows input to be passed as an array
# to work around shell problems with weird characters in arguments
# if the exec returns non-zero we die
@@ -346,12 +270,15 @@ sub safe_pipe_capture {
return wantarray ? @output : join('',@output);
}
-# For any file we want to add to cvs, we must first set its permissions
-# properly, *before* the "cvs add ..." command. Otherwise, it is impossible
-# to change the permission of the file in the CVS repository using only cvs
-# commands. This should be fixed in cvs-1.12.14.
-sub set_new_file_permissions {
- my ($file, $perm) = @_;
- chmod oct($perm), $file
- or die "failed to set permissions of \"$file\": $!\n";
+sub safe_pipe_capture_blob {
+ my $output;
+ if (my $pid = open my $child, '-|') {
+ local $/;
+ undef $/;
+ $output = (<$child>);
+ close $child or die join(' ',@_).": $! $?";
+ } else {
+ exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
+ }
+ return $output;
}
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index c102479..ca0513b 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -89,18 +89,17 @@ test_expect_success \
! git cvsexportcommit -c $id
)'
-# Should fail, but only on the git-cvsexportcommit stage
-test_expect_success \
- 'Fail to remove binary file more than one generation old' \
- 'git reset --hard HEAD^ &&
- cat F/newfile6.png >>D/newfile4.png &&
- git commit -a -m "generation 2 (again)" &&
- rm -f D/newfile4.png &&
- git commit -a -m "generation 3" &&
- id=$(git rev-list --max-count=1 HEAD) &&
- (cd "$CVSWORK" &&
- ! git cvsexportcommit -c $id
- )'
+#test_expect_success \
+# 'Fail to remove binary file more than one generation old' \
+# 'git reset --hard HEAD^ &&
+# cat F/newfile6.png >>D/newfile4.png &&
+# git commit -a -m "generation 2 (again)" &&
+# rm -f D/newfile4.png &&
+# git commit -a -m "generation 3" &&
+# id=$(git rev-list --max-count=1 HEAD) &&
+# (cd "$CVSWORK" &&
+# ! git cvsexportcommit -c $id
+# )'
# We reuse the state from two tests back here
@@ -108,7 +107,7 @@ test_expect_success \
# fail with gnu patch, so cvsexportcommit must handle that.
test_expect_success \
'Remove only binary files' \
- 'git reset --hard HEAD^^^ &&
+ 'git reset --hard HEAD^^ &&
rm -f D/newfile4.png &&
git commit -a -m "test: remove only a binary file" &&
id=$(git rev-list --max-count=1 HEAD) &&
@@ -142,20 +141,73 @@ test_expect_success \
diff F/newfile6.png ../F/newfile6.png
)'
-test_expect_success 'Retain execute bit' '
- mkdir G &&
- echo executeon >G/on &&
- chmod +x G/on &&
- echo executeoff >G/off &&
- git add G/on &&
- git add G/off &&
- git commit -a -m "Execute test" &&
- (
- cd "$CVSWORK" &&
- git-cvsexportcommit -c HEAD
- test -x G/on &&
- ! test -x G/off
- )
-'
+test_expect_success \
+ 'New file with spaces in file name' \
+ 'mkdir "G g" &&
+ echo ok then >"G g/with spaces.txt" &&
+ git add "G g/with spaces.txt" && \
+ cp ../test9200a.png "G g/with spaces.png" && \
+ git add "G g/with spaces.png" &&
+ git commit -a -m "With spaces" &&
+ id=$(git rev-list --max-count=1 HEAD) &&
+ (cd "$CVSWORK" &&
+ git-cvsexportcommit -c $id &&
+ test "$(echo $(sort "G g/CVS/Entries"|cut -d/ -f2,3,5))" = "with spaces.png/1.1/-kb with spaces.txt/1.1/"
+ )'
+
+test_expect_success \
+ 'Update file with spaces in file name' \
+ 'echo Ok then >>"G g/with spaces.txt" &&
+ cat ../test9200a.png >>"G g/with spaces.png" && \
+ git add "G g/with spaces.png" &&
+ git commit -a -m "Update with spaces" &&
+ id=$(git rev-list --max-count=1 HEAD) &&
+ (cd "$CVSWORK" &&
+ git-cvsexportcommit -c $id
+ test "$(echo $(sort "G g/CVS/Entries"|cut -d/ -f2,3,5))" = "with spaces.png/1.2/-kb with spaces.txt/1.2/"
+ )'
+
+# This test contains ISO-8859-1 characters
+test_expect_success \
+ 'File with non-ascii file name' \
+ 'mkdir -p Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö &&
+ echo Foo >Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.txt &&
+ git add Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.txt &&
+ cp ../test9200a.png Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.png &&
+ git add Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/gårdetsågårdet.png &&
+ git commit -a -m "Går det så går det" && \
+ id=$(git rev-list --max-count=1 HEAD) &&
+ (cd "$CVSWORK" &&
+ git-cvsexportcommit -v -c $id &&
+ test "$(echo $(sort Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö/CVS/Entries|cut -d/ -f2,3,5))" = "gårdetsågårdet.png/1.1/-kb gårdetsågårdet.txt/1.1/"
+ )'
+
+test_expect_success \
+ 'Mismatching patch should fail' \
+ 'date >>"E/newfile5.txt" &&
+ git add "E/newfile5.txt" &&
+ git commit -a -m "Update one" &&
+ date >>"E/newfile5.txt" &&
+ git add "E/newfile5.txt" &&
+ git commit -a -m "Update two" &&
+ id=$(git rev-list --max-count=1 HEAD) &&
+ (cd "$CVSWORK" &&
+ ! git-cvsexportcommit -c $id
+ )'
+
+test_expect_success \
+ 'Retain execute bit' \
+ 'mkdir G &&
+ echo executeon >G/on &&
+ chmod +x G/on &&
+ echo executeoff >G/off &&
+ git add G/on &&
+ git add G/off &&
+ git commit -a -m "Execute test" &&
+ (cd "$CVSWORK" &&
+ git-cvsexportcommit -c HEAD
+ test -x G/on &&
+ ! test -x G/off
+ )'
^ permalink raw reply related
* Re: Collection of stgit issues and wishes
From: Jakub Narebski @ 2006-12-10 23:37 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
In-Reply-To: <b0943d9e0612101524w3a2cccecqdd12023233e8ec0c@mail.gmail.com>
Catalin Marinas wrote:
> On 10/12/06, Jakub Narebski <jnareb@gmail.com> wrote:
>> Catalin Marinas wrote:
>>> Yes, only for updating HEAD. The refs in refs/patches/<branch>/ are
>>> written directly. I initialy wanted to add patch history support using
>>> reflogs and added "git-update-ref -m ..." for the patch commits but I
>>> found slow the pushing operation a bit. Do you only want to track the
>>> reflogs for HEAD?
>>
>> Yes, I want for StGit to provide reasons when updating HEAD. I know that
>> StGit manages it's own versioning of patches not using reflog -- fine.
>> What matters for me is reflog for HEAD after "stg commit; stg clean".
>
> Just curious, do you run the "stg commit; stg clean" commands together
> and in this order? Neither of them would update the HEAD. The "commit"
> command simply removes the StGIT metadata for the applied patches
> since it no longer needs to track them (permanently stored to the
> repository). It doesn't change HEAD. The "clean" command only affects
> the HEAD if there are empty applied patches but after a "commit" there
> won't be any patches (only the unapplied ones which do not affect
> HEAD).
>
> Maybe we could have reflog info for "push", "refresh", some undo
> operations. Are they of any use (I haven't used them so I can't tell)?
Ooops, I haven't been clear enough.
I meant that afer "stg commit; stg clean" I won't have any StGIT metadata,
but I'd have git metadata in reflog.
I'd like to have info in reflog for each command which changes head;
for example "push", "refresh", perhaps "pop", "float", "uncommit".
Just so I don't have long sequence of ref changes in reflog without
description of said changes after some work with StGIT on branch.
BTW. currently I use StGIT to manage a series of commits on feature
branch which implements step-by-step single feature, and would be
later send as a patch series. With StGIT I can work on final patch
in series, notice that underlying feature developed in earlier patch
(earlier commit) needs modification, so I do refresh, pop until
given patch, change patch, push all, and work on patch. Or for example
if I notice that I'd have to implement some basic feature separately,
best at beginning: pop all, create new patch etc. Very nice.
--
Jakub Narebski
^ permalink raw reply
* Re: [PATCH] remove "[PATCH]" prefix from shortlog output
From: Johannes Schindelin @ 2006-12-10 23:35 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <eli3vr$j6v$1@sea.gmane.org>
Hi,
On Mon, 11 Dec 2006, Jakub Narebski wrote:
> Johannes Schindelin wrote:
>
> > On Sat, 9 Dec 2006, Nicolas Pitre wrote:
> >
> >> This doesn't convey much information in the shortlog context.
> >> And the perl version did strip it as well.
> >
> > From the current builtin-shortlog.c:128ff:
> >
> > if (!strncmp(oneline, "[PATCH", 6)) {
> > char *eob = strchr(oneline, ']');
> >
> > if (eob) {
> > while (isspace(eob[1]) && eob[1] != '\n')
> > eob++;
> > if (eob - oneline < onelinelen) {
> > onelinelen -= eob - oneline;
> > oneline = eob;
> > }
> > }
> > }
> >
> > It tries not only to strip "[PATCH]", but also "[PATCH 0/n]" and basically
> > every prefix beginning with "[PATCH" and ending in "]". I do not remember
> > if I really tested that code, but it should work.
>
> What happens if you have "[PATCH" without closing "]"? Does it work (and
> doesn't crash)? Does it strip anything?
Use the source, Luke!
If "[PATCH" is there, but "]" is not, then eob will be NULL, and nothing
happens.
Well, actually it is not completely true: the code searches for "]" in the
_complete_ commit message (which _is_ terminated by '\0'). But only if it
is found, _and_ it is in the first line, the substring is trimmed away.
Hth,
Dscho
^ permalink raw reply
* Re: [PATCH] remove "[PATCH]" prefix from shortlog output
From: Johannes Schindelin @ 2006-12-10 23:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac1v2uom.fsf@assigned-by-dhcp.cox.net>
Hi,
On Sun, 10 Dec 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > It tries not only to strip "[PATCH]", but also "[PATCH 0/n]" and basically
> > every prefix beginning with "[PATCH" and ending in "]". I do not remember
> > if I really tested that code, but it should work.
>
> The problem is that you forgot that the lines are indented when
> acting as a filter.
Of course!
And your patch looks correct to me.
Ciao,
^ permalink raw reply
* [ANNOUNCE] CGit v0.1-pre
From: Lars Hjemli @ 2006-12-10 23:42 UTC (permalink / raw)
To: git
CGit is another cgi-app for git.
It is written in C (using libgit.a), and implements an internal page
cache. A PoC version is available for cloning at
git://hjemli.net/pub/git/cgit
and it is also (barely) selfhosted at
http://hjemli.net/git/
For a quick summary of the cache algorithm, the project README is here:
http://hjemli.net/git/cgit/view/?id=5917c37ce30b3f0a374c9fa376955f51f1d7bfbf
Enjoy!
--
^ permalink raw reply
* Re: [PATCH] Make cvsexportcommit work with filenames with spaces and non-ascii characters.
From: Robin Rosenberg @ 2006-12-10 23:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlklf4f1s.fsf@assigned-by-dhcp.cox.net>
söndag 10 december 2006 22:27 skrev Junio C Hamano:
> Maybe I am missing something. It tells you about added or
> removed files (either binary or non-binary).
no, I was missing --summary. I thought --numstat did that (man page
says "similar to stat".
> I'd prepare a pair of practice patch files. "forward" has
> creation, "reverse" has addition.
t9200 serves that purpose.
^ permalink raw reply
* Re: [ANNOUNCE] CGit v0.1-pre
From: Jakub Narebski @ 2006-12-11 0:08 UTC (permalink / raw)
To: git
In-Reply-To: <8c5c35580612101542n72d300c7o106e53e219670510@mail.gmail.com>
Lars Hjemli wrote:
> CGit is another cgi-app for git.
I have added this to GitWiki: check out
http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#cgit
Hmmm... git has now 4 web interfaces (5 if counting gittracker, which works
but gittracker repository shows empty): gitweb in Perl, git-php in PHP, wit
in Python (is it actively developed? where it can be downloaded from?),
gitarella in Ruby, now CGit in C...
By the way, it is cgit, CGit or CGIt ;-p?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Marco Costalba @ 2006-12-11 0:15 UTC (permalink / raw)
To: Linus Torvalds
Cc: Git Mailing List, Junio C Hamano, Alex Riesen, Shawn Pearce
In-Reply-To: <Pine.LNX.4.64.0612101439540.12500@woody.osdl.org>
On 12/10/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
> looks about right.
>
Yes it's right. Thanks!
But it's still slow. Almost one second (985ms) to read the little qgit repo:
$ ./qgit HEAD
Found GNU source-highlight 2.5
count is <-1>
count is <60169>
count is <-1>
count is <60505>
count is <-1>
count is <61462>
count is <-1>
count is <61911>
count is <-1>
count is <61392>
count is <-1>
count is <61880>
count is <-1>
count is <62009>
count is <-1>
count is <62549>
count is <-1>
count is <21354>
count is <0>
$
As a compare the temporary file version needs a mere 105ms (1030 revs).
This is the code under test:
bool DataLoader::start(const QStringList& args, const QString& workDir) {
QDir::setCurrent(workDir);
_file = popen(args.join(" ").ascii(), "r");
if (!_file)
return false;
fcntl(fileno(_file), F_SETFL, O_NONBLOCK);
loadTime.start();
guiUpdateTimer.start(10, true);
return true;
}
void DataLoader::on_timeout() {
if (canceling) {
deleteLater();
return;
}
int count;
for (;;) {
QByteArray* ba = new QByteArray(FILE_BLOCK_SIZE); // 64KB
// this is the ONLY deep copy involved in the whole loading
count = read(fileno(_file), ba->data(), ba->size());
dbg(count); // DEBUG print
if (count == 0) {
/* All done, no more to read */
delete ba;
break;
}
if (count < 0) {
delete ba;
if (errno == EAGAIN)
break;
if (errno == EINTR)
continue;
/* Anything else is fatal - report error */
dbg("Fatal error");
on_cancel();
deleteLater();
return;
}
if (count < (int)ba->size()) // very rare
ba->resize(count);
loadedBytes += count;
fh->rowData.append(ba);
parseSingleBuffer(*ba);
}
if (count == 0) {
emit loaded(fh, loadedBytes, loadTime.elapsed(), true, "", "");
pclose(_file);
_file = NULL;
deleteLater();
} else
guiUpdateTimer.start(100, true);
^ permalink raw reply
* Re: [ANNOUNCE] CGit v0.1-pre
From: Jakub Narebski @ 2006-12-11 0:29 UTC (permalink / raw)
To: Lars Hjemli; +Cc: git
In-Reply-To: <8c5c35580612101616g179715ecyd02fcbb023246ecc@mail.gmail.com>
Lars Hjemli wrote:
> On 12/11/06, Jakub Narebski <jnareb@gmail.com> wrote:
>
>> Hmmm... git has now 4 web interfaces (5 if counting gittracker, which works
>> but gittracker repository shows empty): gitweb in Perl, git-php in PHP, wit
>> in Python (is it actively developed? where it can be downloaded from?),
>> gitarella in Ruby, now CGit in C...
>
> Hmm, it must be a popular scm :-D
Miscalculation: it is 5 with yours (6 counting gittracker).
--
Jakub Narebski
^ permalink raw reply
* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Linus Torvalds @ 2006-12-11 0:51 UTC (permalink / raw)
To: Marco Costalba
Cc: Git Mailing List, Junio C Hamano, Alex Riesen, Shawn Pearce
In-Reply-To: <e5bfff550612101615u5f588513n499e3b88ce14a6f6@mail.gmail.com>
On Mon, 11 Dec 2006, Marco Costalba wrote:
>
> But it's still slow. Almost one second (985ms) to read the little qgit repo:
Right. Because every time you sleep, you sleep for 100 ms.
That's why I was saying that you need to add polling to the thing. I don't
know what the QT interfaces to asynchronous polling file descriptors are,
but as long as you just blindly wait for 100ms whenever you run out of
data, things will always suck.
Using "fread()" hid this problem, because the thing would block in
fread(), and thus you'd nor see as many of these events.
> As a compare the temporary file version needs a mere 105ms (1030 revs).
How about you just compare something simpler:
git-rev-list | cat > /dev/null
vs
git-rev-list > tmpfile ; cat tmpfile > /dev/null
and see which one works better.
If the pipe works better, that means that it's your code that is buggy and
broken.
Which gets us back to the basic issue: you're asking for a bad interface.
This is your problem:
> guiUpdateTimer.start(100, true);
rather than just blindly starting a timer, you should ask it to wait until
more data is available.
^ permalink raw reply
* Re: [ANNOUNCE] CGit v0.1-pre
From: Linus Torvalds @ 2006-12-11 1:04 UTC (permalink / raw)
To: Lars Hjemli; +Cc: git
In-Reply-To: <8c5c35580612101542n72d300c7o106e53e219670510@mail.gmail.com>
On Mon, 11 Dec 2006, Lars Hjemli wrote:
>
> For a quick summary of the cache algorithm, the project README is here:
>
> http://hjemli.net/git/cgit/view/?id=5917c37ce30b3f0a374c9fa376955f51f1d7bfbf
Your pseudo-algorithm is dubious:
name = generate_cache_name(request);
top:
if (!exists(name)) {
if (lock_cache(name)) {
generate_cache(request, name);
unlock_cache(name);
} else {
sched_yield();
goto top;
}
} else if (expired(name)) {
if (lock_cache(name)) {
generate_cache(request, name);
unlock_cache(name);
}
}
print_file(name);
You really should have:
if (!exists) {
if (!lock)
delay-and-repeat;
/* RETEST exists _after_ getting the lock */
if (!exists) {
generate into lock-file
mv lockfile exists;
} else {
rm lockfile
}
}
because you really want to re-check the existence after you got the lock,
otherwise you would race with somebody else that got the lock, generated
the data, and then unlocked (and you got the lock _after_ the data was
generated, so now you generate it unnecessarily).
As a side note: how do you release your caches?
^ permalink raw reply
* Re: kernel.org mirroring (Re: [GIT PULL] MMC update)
From: Martin Langhoff @ 2006-12-11 2:16 UTC (permalink / raw)
To: Jakub Narebski
Cc: Jeff Garzik, Git Mailing List, Linus Torvalds, H. Peter Anvin,
Rogan Dawes, Kernel Org Admin
In-Reply-To: <200612102359.20083.jnareb@gmail.com>
On 12/11/06, Jakub Narebski <jnareb@gmail.com> wrote:
> Even if Apache does execute CGI script to completion every time, it might
> not send the output of the script, but HTTP 304 Not Modified reply. Might.
> I don't know if it does.
It is up to the script (CGI or via mod_perl) to set the status to 304
and finish execution. Just setting the status to 304 does not
forcefully end execution as you may want to cleanup, log, etc.
cheers,
^ permalink raw reply
* Re: [PATCH] remove "[PATCH]" prefix from shortlog output
From: Nicolas Pitre @ 2006-12-11 3:17 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612110040260.1471@wbgn013.biozentrum.uni-wuerzburg.de>
On Mon, 11 Dec 2006, Johannes Schindelin wrote:
> Hi,
>
> On Sun, 10 Dec 2006, Junio C Hamano wrote:
>
> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> >
> > > It tries not only to strip "[PATCH]", but also "[PATCH 0/n]" and basically
> > > every prefix beginning with "[PATCH" and ending in "]". I do not remember
> > > if I really tested that code, but it should work.
Hmmm well, right. And of course I failed to notice that code was there.
I think I was corrupted by the dark side and failed to properly "use the
source" twice on that tool this week.
> > The problem is that you forgot that the lines are indented when
> > acting as a filter.
Which was indeed my use case.
> Of course!
>
> And your patch looks correct to me.
Confirmed.
^ permalink raw reply
* asciidoc, docbook, "book" doctype
From: J. Bruce Fields @ 2006-12-11 3:20 UTC (permalink / raw)
To: git
I've been fooling around with producing a longer piece of documentation
using material from the tutorials, etc., using the docbook backend and
"book" doctype. It's not working quite the way I'd expect. For
example, it doesn't format the literal blocks correctly, and man page
links aren't producing useful clickable links. Should I be going about
this some other way?
All I really want is automatically generated tables of contents and
cross-references.
^ permalink raw reply
* Re: kernel.org mirroring (Re: [GIT PULL] MMC update)
From: linux @ 2006-12-11 3:40 UTC (permalink / raw)
To: koreth; +Cc: git
>>> I posted separately about those. And I've been mulling about whether
>>> the thundering herd is really such a big problem that we need to
>>> address it head-on.
>>
>> Uhm... yes it is.
>
> Got some more info, discussion points or links to stuff I should read
> to appreciate why that is? I am trying to articulate why I consider it
> is not a high-payoff task, as well as describing how to tackle it.
>
> To recap, the reasons it is not high payoff is that:
>
> - the main benefit comes from being cacheable and able to revalidate
> the cache cheaply (with the ETags-based strategy discussed above)
> - highly distributed caches/proxies means we'll seldom see a true
> cold cache situation
> - we have a huge set of URLs which are seldom hit, and will never see
> a thundering anything
> - we have a tiny set of very popular URLs that are the key target for
> the thundering herd - (projects page, summary page, shortlog, fulllog)
> - but those are in the clear as soon as the caches are populated
>
> Why do we have to take it head-on? :-)
I think I agree with you, but not as strongly. Certainly, having any
kind of effective cacheing (heck, just comparing the timestamp of the
relevant ref(s) with the If-Modified-Since: header) will help kernel.org
enormously.
But as soon as there's a push, particularly a release push, that
invalidates *all* of the popular pages *and* the thindering herd arrives.
The result is that all of the popular "what's new?" summary pages get
fetched 15 times in parallel and, because the front end doesn't serialize
them, populating the caches can be a painful process involving a lot of
repeated work.
I tend to agree that for the basic project summary pages, generating them
preemptively as static pages out of the push script seems best.
("find /usr/src/linux -type d -print | wc -l" is 1492. Dear me.
Oh! There is no per-directory shortlog page; that simplifies things.
But there *should* be.)
The only tricky thing is the "n minutes/hours/days ago" timestamps.
Basically, you want to generate a half-formatted, indefinitely-cacheable
page that contains them as absolute timestamps, and a have system for
regenerating the fully-formatted page from that (and the current time).
The ideas that people have been posting seem excellent. Give a page
two timeouts. If a GET arrives before the first timestamp, and no
prerequisites have changes, it's served directly from cache. If it
arrives after the second timeout, or the prerequisites have changed,
it blocks until the page is regenerated. But if it arrives between
those two times, it serves the stale data and starts generating fresh
data in the background.
So for the fully-formed timestamps, the first timeout is when the next
human-readable timestamp on the page ticks over. But the second timeout
can be past that by, say, 5% of the timeout value. It's okay to display
"3 hours ago" until 12 minutes past the 4 hour mark.
It might be okay to allow even the prerequisites to be slightly stale when
serving old data; it's okay if it takes 30 seconds for the kernel.org
web page to notice that Linus pushed. But on my office gitweb, I'm not
sure that it's okay to take 30 seconds to notice that *I* just pushed.
(I'm also not sure about consistency issues. If I link from one page
that shows the new release to another, it would be a bit disconcerting
if it disappeared.)
The nasty problem with built-in cacheing is that you need a whole cache
reclaim infrastructure; it would be so much nicer to let Squid deal
with that whole mess. But it can't deal with anything other than fully
^ permalink raw reply
* Re: [RFC \ WISH] Add -o option to git-rev-list
From: Marco Costalba @ 2006-12-11 7:17 UTC (permalink / raw)
To: Linus Torvalds
Cc: Git Mailing List, Junio C Hamano, Alex Riesen, Shawn Pearce
In-Reply-To: <Pine.LNX.4.64.0612101647310.12500@woody.osdl.org>
On 12/11/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
> How about you just compare something simpler:
>
> git-rev-list | cat > /dev/null
>
> vs
>
> git-rev-list > tmpfile ; cat tmpfile > /dev/null
>
> and see which one works better.
>
These are tipical values (warm cache):
$ time git rev-list --header --boundary --parents --topo-order HEAD /dev/null
3.04user 0.05system 0:03.09elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+10141minor)pagefaults 0swaps
$ time git rev-list --header --boundary --parents --topo-order HEAD |
cat > /dev/null
3.67user 0.36system 0:04.29elapsed 93%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+18033minor)pagefaults 0swaps
$ time git rev-list --header --boundary --parents --topo-order HEAD >
/tmp/tmp.txt; cat /tmp/tmp.txt > /dev/null
3.44user 0.28system 0:03.74elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+18033minor)pagefaults 0swaps
For some reason the CPU *never* goes up 93% with pipe (while it's easy
in the other two cases) and I repeated that test at lest 10 times
consecutively. Is it perhaps the signature of some blocking around? Or
too much high frequency of receiver's read call (see below) ?
>
> This is your problem:
>
> > guiUpdateTimer.start(100, true);
>
> rather than just blindly starting a timer, you should ask it to wait until
> more data is available.
>
OK. I just don't understand how after waiting 100ms I get only 60KB
and stay in the loop only one cycle instead of reading, for many
cycles, much more then 60KB and then wait another 100ms and found
another big (about 1MB) amount of data ready to be read as with the
file case.
Perhaps the pipe buffers are small and block the writer when full. In
the file case when I come back in the loop after 100ms I found _a lot_
of data to be read and I stay in the loop for much more then 1 cycle
before to wait again 100ms.
On the other hand, going to read each say less then 10ms is exactly
what QProcess (socket based) was doing and I ended up with my read
function being called at furious pace slowing down everything.
Experimenting with QProcess I found that, for performance reasons,
it's better to read big chunks few times then small chunks a lot of
times.
Marco
P.S: 30MB for 64KB each chunk it's 468, in 3.67s it's 1 call each
7.8ms. If the pipe calls the receiver for data ready after each 4KB
(old kernels) then we should have 7.500 calls. Impossible to read in
3.67s, it would be a theoretical 1 call each 0.48ms average.
So IMHO bigger buffers for each read call could be the way to get
^ permalink raw reply
* [PATCH] no need to install manpages as executable
From: Chris Wright @ 2006-12-11 7:39 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
No need to install manpages as executable. Noticed by Ville Skyttä.
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
---
Applies cleanly to maint and master.
Documentation/Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index c00f5f6..d68bc4a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -56,8 +56,8 @@ man7: $(DOC_MAN7)
install: man
$(INSTALL) -d -m755 $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir)
- $(INSTALL) $(DOC_MAN1) $(DESTDIR)$(man1dir)
- $(INSTALL) $(DOC_MAN7) $(DESTDIR)$(man7dir)
+ $(INSTALL) -m644 $(DOC_MAN1) $(DESTDIR)$(man1dir)
+ $(INSTALL) -m644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
^ permalink raw reply related
* error: Can't lock ref
From: Jon Masters @ 2006-12-11 7:58 UTC (permalink / raw)
To: git
Hi folks,
I've just pushed up a packed git repo:
http://www.kerneltools.org/pub/downloads/module-init-tools/devel/module-init-tools.git
Attempting to clone this repo using http generates the error in
$subject. Brief searching via Google suggests this is an appache
permissions problem - anyone got a trivially obvious apache config fix
before I go trawling through to figure out what's up?
^ permalink raw reply
* Re: [ANNOUNCE] CGit v0.1-pre
From: Lars Hjemli @ 2006-12-11 8:33 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0612101653420.12500@woody.osdl.org>
On 12/11/06, Linus Torvalds <torvalds@osdl.org> wrote:
> you really want to re-check the existence after you got the lock,
> otherwise you would race with somebody else that got the lock, generated
> the data, and then unlocked (and you got the lock _after_ the data was
> generated, so now you generate it unnecessarily).
Yes, you're right. Thanks for noticing.
But this also applies to the case where the cachefile has expired,
right? In that case, after getting the lock, I have to recheck that
the cachefile is _still_ expired.
Anyway, I must say I find it rather unlikely for these cases to occur
(frequently) in real life. That would seem to imply that the caching
isn't really needed at all.
>
> As a side note: how do you release your caches?
>
Simple timeouts (time()-stat.st_mtime), depending on what kind of page
was requested. If anyone cares about invalid cache content (branch
head moving), relevant cachefiles can be deleted with an update-hook.
--
^ 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