* [PATCH][Cogito] Let cg-push default to git+ssh on a host:path syntax
From: Josef Weidendorfer @ 2005-11-02 21:27 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Let cg-push default to git+ssh on a host:path syntax
cg-update/cg-fetch fall back to git+ssh protocol for host:path
syntax. cg-push should do the same.
Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
---
cg-push | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
applies-to: 9294c00b9e87de048c0d29f8ad99c0a6d2733b16
1f6693e09a8aa4c02297472764b972a07d1c0d02
diff --git a/cg-push b/cg-push
index 4c29b33..d63fb65 100755
--- a/cg-push
+++ b/cg-push
@@ -51,8 +51,12 @@ if echo "$uri" | grep -q "^http://"; the
die "pushing over HTTP not supported yet"
elif echo "$uri" | grep -q "^git+ssh://"; then
git-send-pack "$(echo "$uri" | sed 's#^git+ssh://\([^/]*\)\(/.*\)$#\1:\2#')" $_git_head$sprembranch "${tags[@]}"
+elif echo "$uri" | grep -q "^rsync://"; then
+ die "pushing over rsync not supported"
elif echo "$uri" | grep -q ":"; then
- die "pushing over rsync not supported"
+ echo "WARNING: I guessed the host:path syntax was used and fell back to the git+ssh protocol."
+ echo "WARNING: The host:path syntax is evil because it is implicit. Please just use a URI."
+ git-send-pack "$uri" $_git_head$sprembranch "${tags[@]}"
else
remgit="$uri"; [ -d "$remgit/.git" ] && remgit="$remgit/.git"
if is_same_repo "$_git_objects" "$remgit/objects"; then
---
0.99.9
^ permalink raw reply related
* Re: [PATCH] Add 'ours' merge strategy.
From: Daniel Barkalow @ 2005-11-02 21:45 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0511021134100.6501@wbgn013.biozentrum.uni-wuerzburg.de>
On Wed, 2 Nov 2005, Johannes Schindelin wrote:
> Hi,
>
> On Tue, 1 Nov 2005, Junio C Hamano wrote:
>
> > This can be used to terminate an old maintenance branch without
> > leaving people's repositories behind.
>
> How about optionally do something similar when git-rebase'ing? Especially
> "pu"?
For that, you'd additionally want to have the parent whose content was
ignored be listed as "optional" in a sense; users shouldn't have to
download all the commits that "pu" went through that have been superceded,
unless they're actually trying to get back from a superceded commit; the
log on that line isn't interesting (because all the useful messages are in
the rebased line, too, in potentially better versions), and so forth.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* [PATCH 3/7] Don't output error when there are changes in the nodes /, /tags or /branches
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
---
git-svnimport.perl | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
applies-to: d711bb120e7c95914069cff4996ddbcfc29c20f6
e5d8e159e80ead8eef0867a3662a83b3948aaa18
diff --git a/git-svnimport.perl b/git-svnimport.perl
index 83b70f9..ea5bbdb 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -336,7 +336,12 @@ sub split_path($$) {
} elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) {
$branch = $1;
} else {
- print STDERR "$rev: Unrecognized path: $path\n";
+ my %no_error = (
+ "/" => 1,
+ "/$tag_name" => 1,
+ "/$branch_name" => 1
+ );
+ print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path});
return ()
}
$path = "/" if $path eq "";
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 1/7] Using svn pools seems to solve the memory leak problem
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
applies-to: b12655de9a371d7d16f7e8318da8c5b0099c39bd
4356b879b425644c436eacb6d43b523bab960704
diff --git a/git-svnimport.perl b/git-svnimport.perl
index 45b6a19..5bf9ef2 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -112,7 +112,9 @@ sub file {
DIR => File::Spec->tmpdir(), UNLINK => 1);
print "... $rev $path ...\n" if $opt_v;
- eval { $self->{'svn'}->get_file($path,$rev,$fh); };
+ my $pool = SVN::Pool->new();
+ eval { $self->{'svn'}->get_file($path,$rev,$fh,$pool); };
+ $pool->clear;
if($@) {
return undef if $@ =~ /Attempted to get checksum/;
die $@;
@@ -674,7 +676,9 @@ sub commit_all {
}
while(++$current_rev <= $svn->{'maxrev'}) {
- $svn->{'svn'}->get_log("/",$current_rev,$current_rev,$current_rev,1,1,\&_commit_all,"");
+ my $pool=SVN::Pool->new;
+ $svn->{'svn'}->get_log("/",$current_rev,$current_rev,1,1,1,\&_commit_all,$pool);
+ $pool->clear;
commit_all();
if($opt_l and not --$opt_l) {
print STDERR "Stopping, because there is a memory leak (in the SVN library).\n";
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 2/7] Add node_kind function to differentiate between file and directory
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
applies-to: e230cf653f1af6412e43f9b527465406bdb76ece
c38f34212ace329637fd87fb11247f6a5733e47f
diff --git a/git-svnimport.perl b/git-svnimport.perl
index 5bf9ef2..83b70f9 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -260,10 +260,17 @@ EOM
open BRANCHES,">>", "$git_dir/svn2git";
-sub get_file($$$) {
- my($rev,$branch,$path) = @_;
+sub node_kind($$$) {
+ my ($branch, $path, $revision) = @_;
+ my $pool=SVN::Pool->new;
+ my $kind = $svn->{'svn'}->check_path(revert_split_path($branch,$path),$revision,$pool);
+ $pool->clear;
+ return $kind;
+}
+
+sub revert_split_path($$) {
+ my($branch,$path) = @_;
- # revert split_path(), below
my $svnpath;
$path = "" if $path eq "/"; # this should not happen, but ...
if($branch eq "/") {
@@ -274,6 +281,14 @@ sub get_file($$$) {
$svnpath = "$branch_name/$branch/$path";
}
+ return $svnpath
+}
+
+sub get_file($$$) {
+ my($rev,$branch,$path) = @_;
+
+ my $svnpath = revert_split_path($branch,$path);
+
# now get it
my $name;
if($opt_d) {
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 4/7] copy_dir becomes copy_path and handles bothe files and directory
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
The A (Add) and R (Replace) actions handling are unified.
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 90 +++++++++++++++++++++++++++++++---------------------
1 files changed, 53 insertions(+), 37 deletions(-)
applies-to: 33a1ca1ccca482b3c467ad4ad10af877b59011f3
0cab115306192e78516588e05045220f96106903
diff --git a/git-svnimport.perl b/git-svnimport.perl
index ea5bbdb..9cee629 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -348,21 +348,42 @@ sub split_path($$) {
return ($branch,$path);
}
-sub copy_subdir($$$$$$) {
+sub branch_rev($$) {
+
+ my ($srcbranch,$uptorev) = @_;
+
+ my $bbranches = $branches{$srcbranch};
+ my @revs = reverse sort { ($a eq 'LAST' ? 0 : $a) <=> ($b eq 'LAST' ? 0 : $b) } keys %$bbranches;
+ my $therev;
+ foreach my $arev(@revs) {
+ next if ($arev eq 'LAST');
+ if ($arev <= $uptorev) {
+ $therev = $arev;
+ last;
+ }
+ }
+ return $therev;
+}
+
+sub copy_path($$$$$$$) {
# Somebody copied a whole subdirectory.
# We need to find the index entries from the old version which the
# SVN log entry points to, and add them to the new place.
- my($newrev,$newbranch,$path,$oldpath,$rev,$new) = @_;
- my($branch,$srcpath) = split_path($rev,$oldpath);
+ my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new) = @_;
- my $gitrev = $branches{$branch}{$rev};
+ my($srcbranch,$srcpath) = split_path($rev,$oldpath);
+ my $therev = branch_rev($srcbranch, $rev);
+ my $gitrev = $branches{$srcbranch}{$therev};
unless($gitrev) {
print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n";
return;
}
- print "$newrev:$newbranch:$path: copying from $branch:$srcpath @ $rev\n" if $opt_v;
- $srcpath =~ s#/*$#/#;
+ print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
+ if ($node_kind eq $SVN::Node::dir) {
+ $srcpath =~ s#/*$#/#;
+ }
+
open my $f,"-|","git-ls-tree","-r","-z",$gitrev,$srcpath;
local $/ = "\0";
while(<$f>) {
@@ -370,9 +391,12 @@ sub copy_subdir($$$$$$) {
my($m,$p) = split(/\t/,$_,2);
my($mode,$type,$sha1) = split(/ /,$m);
next if $type ne "blob";
- $p = substr($p,length($srcpath)-1);
- print "... found $path$p ...\n" if $opt_v;
- push(@$new,[$mode,$sha1,$path.$p]);
+ if ($node_kind eq $SVN::Node::dir) {
+ $p = $path . substr($p,length($srcpath)-1);
+ } else {
+ $p = $path;
+ }
+ push(@$new,[$mode,$sha1,$p]);
}
close($f) or
print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n";
@@ -476,39 +500,31 @@ sub commit {
foreach my $path(@paths) {
my $action = $changed_paths->{$path};
- if ($action->[0] eq "A") {
- my $f = get_file($revision,$branch,$path);
- if($f) {
- push(@new,$f) if $f;
- } elsif($action->[1]) {
- copy_subdir($revision,$branch,$path,$action->[1],$action->[2],\@new);
- } else {
- my $opath = $action->[3];
- print STDERR "$revision: $branch: could not fetch '$opath'\n";
+ if ($action->[0] eq "R") {
+ # refer to a file/tree in an earlier commit
+ push(@old,$path); # remove any old stuff
+ }
+ if(($action->[0] eq "A") || ($action->[0] eq "R")) {
+ my $node_kind = node_kind($branch,$path,$revision);
+ if($action->[1]) {
+ copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new);
+ } elsif ($node_kind eq $SVN::Node::file) {
+ my $f = get_file($revision,$branch,$path);
+ if ($f) {
+ push(@new,$f) if $f;
+ } else {
+ my $opath = $action->[3];
+ print STDERR "$revision: $branch: could not fetch '$opath'\n";
+ }
}
} elsif ($action->[0] eq "D") {
push(@old,$path);
} elsif ($action->[0] eq "M") {
- my $f = get_file($revision,$branch,$path);
- push(@new,$f) if $f;
- } elsif ($action->[0] eq "R") {
- # refer to a file/tree in an earlier commit
- push(@old,$path); # remove any old stuff
-
- # ... and add any new stuff
- my($b,$srcpath) = split_path($revision,$action->[1]);
- $srcpath =~ s#/*$#/#;
- open my $F,"-|","git-ls-tree","-r","-z", $branches{$b}{$action->[2]}, $srcpath;
- local $/ = "\0";
- while(<$F>) {
- chomp;
- my($m,$p) = split(/\t/,$_,2);
- my($mode,$type,$sha1) = split(/ /,$m);
- next if $type ne "blob";
- $p = substr($p,length($srcpath)-1);
- push(@new,[$mode,$sha1,$path.$p]);
+ my $node_kind = node_kind($branch,$path,$revision);
+ if ($node_kind eq $SVN::Node::file) {
+ my $f = get_file($revision,$branch,$path);
+ push(@new,$f) if $f;
}
- close($F);
} else {
die "$revision: unknown action '".$action->[0]."' for $path\n";
}
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 6/7] Fix an error when a svn revision consists only of the creation of a new tag
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
directory (/tags/this_is_a_tag).
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
applies-to: 12064f4a47217c44cc28ffb5977ffcd245179b5f
f8f37463ee4c3b24249192345f81a16c0dd74f66
diff --git a/git-svnimport.perl b/git-svnimport.perl
index ae82a7c..e97f470 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -648,6 +648,10 @@ sub commit {
die "Error running git-commit-tree: $?\n" if $?;
}
+ if (not defined $cid) {
+ $cid = $branches{"/"}{"LAST"};
+ }
+
if(not defined $dest) {
print "... no known parent\n" if $opt_v;
} elsif(not $tag) {
@@ -664,6 +668,7 @@ sub commit {
# the tag was 'complex', i.e. did not refer to a "real" revision
$dest =~ tr/_/\./ if $opt_u;
+ $branch = $dest;
my $pid = open2($in, $out, 'git-mktag');
print $out ("object $cid\n".
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 5/7] When copying files and/or directories from several branches in one single
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
revision, all these branches are used as parents of the commit.
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 22 ++++++++++++++++------
1 files changed, 16 insertions(+), 6 deletions(-)
applies-to: 71ff99dad666ebbb05cb14744df010bf223678c6
7554fc8ad3df5f08a269b4ef0a05acdbc33f2302
diff --git a/git-svnimport.perl b/git-svnimport.perl
index 9cee629..ae82a7c 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -365,12 +365,12 @@ sub branch_rev($$) {
return $therev;
}
-sub copy_path($$$$$$$) {
+sub copy_path($$$$$$$$) {
# Somebody copied a whole subdirectory.
# We need to find the index entries from the old version which the
# SVN log entry points to, and add them to the new place.
- my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new) = @_;
+ my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_;
my($srcbranch,$srcpath) = split_path($rev,$oldpath);
my $therev = branch_rev($srcbranch, $rev);
@@ -379,6 +379,9 @@ sub copy_path($$$$$$$) {
print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n";
return;
}
+ if ($srcbranch ne $newbranch) {
+ push(@$parents, $branches{$srcbranch}{'LAST'});
+ }
print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
if ($node_kind eq $SVN::Node::dir) {
$srcpath =~ s#/*$#/#;
@@ -405,7 +408,7 @@ sub copy_path($$$$$$$) {
sub commit {
my($branch, $changed_paths, $revision, $author, $date, $message) = @_;
my($author_name,$author_email,$dest);
- my(@old,@new);
+ my(@old,@new,@parents);
if (not defined $author) {
$author_name = $author_email = "unknown";
@@ -492,6 +495,8 @@ sub commit {
$last_rev = $rev;
}
+ push (@parents, $rev) if defined $rev;
+
my $cid;
if($tag and not %$changed_paths) {
$cid = $rev;
@@ -507,7 +512,7 @@ sub commit {
if(($action->[0] eq "A") || ($action->[0] eq "R")) {
my $node_kind = node_kind($branch,$path,$revision);
if($action->[1]) {
- copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new);
+ copy_path($revision,$branch,$path,$action->[1],$action->[2],$node_kind,\@new,\@parents);
} elsif ($node_kind eq $SVN::Node::file) {
my $f = get_file($revision,$branch,$path);
if ($f) {
@@ -592,7 +597,6 @@ sub commit {
$pw->close();
my @par = ();
- @par = ("-p",$rev) if defined $rev;
# loose detection of merges
# based on the commit msg
@@ -602,11 +606,17 @@ sub commit {
if ($mparent eq 'HEAD') { $mparent = $opt_o };
if ( -e "$git_dir/refs/heads/$mparent") {
$mparent = get_headref($mparent, $git_dir);
- push @par, '-p', $mparent;
+ push (@parents, $mparent);
print OUT "Merge parent branch: $mparent\n" if $opt_v;
}
}
}
+ my %seen_parents = ();
+ my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
+ foreach my $bparent (@unique_parents) {
+ push @par, '-p', $bparent;
+ print OUT "Merge parent branch: $bparent\n" if $opt_v;
+ }
exec("env",
"GIT_AUTHOR_NAME=$author_name",
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 7/7] Now that the leak is gone, there is by default no limit of revisions to
From: Yaacov Akiba Slama @ 2005-11-02 21:51 UTC (permalink / raw)
import.
No more message about leak when the limit (given by the -l parameter)
is reached.
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
---
git-svnimport.perl | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
applies-to: 339bb970b075dfbbd321dcd817591cb739a29584
7410494b72db4c48a27d707a18168076e1b5a3dc
diff --git a/git-svnimport.perl b/git-svnimport.perl
index e97f470..ab690f3 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -53,7 +53,6 @@ my $branch_name = $opt_b || "branches";
$opt_o ||= "origin";
$opt_s ||= 1;
-$opt_l = 100 unless defined $opt_l;
my $git_tree = $opt_C;
$git_tree ||= ".";
@@ -727,15 +726,16 @@ sub commit_all {
}
while(++$current_rev <= $svn->{'maxrev'}) {
+ if (defined $opt_l) {
+ $opt_l--;
+ if ($opt_l < 0) {
+ last;
+ }
+ }
my $pool=SVN::Pool->new;
$svn->{'svn'}->get_log("/",$current_rev,$current_rev,1,1,1,\&_commit_all,$pool);
$pool->clear;
commit_all();
- if($opt_l and not --$opt_l) {
- print STDERR "Stopping, because there is a memory leak (in the SVN library).\n";
- print STDERR "Please repeat this command; it will continue safely\n";
- last;
- }
}
---
0.99.9.GIT
^ permalink raw reply related
* Re: [PATCH 1/7] Using svn pools seems to solve the memory leak problem
From: Junio C Hamano @ 2005-11-02 22:38 UTC (permalink / raw)
To: Yaacov Akiba Slama; +Cc: git
In-Reply-To: <E1EXQWT-000504-Qw@localhost.localdomain>
I see you are resending the previous round after splitting, but
could you be a bit more careful about the commit log? One liner
title that is self-sufficient (as opposed to just the initial
part of one sentence, cut off at whereever your editor happened
to decide to fold line), which goes to Subject:, and the body of
the message as a separate paragraph.
Especially something like this (5/7) does not make much sense:
From: Yaacov Akiba Slama <ya@slamail.org>
Subject: [PATCH 5/7] When copying files and/or directories from several branches in one single
Date: Wed, 02 Nov 2005 23:51:57 +0200
revision, all these branches are used as parents of the commit.
^ permalink raw reply
* [PATCH] cogito: install cg-admin-setuprepo
From: Pavel Roskin @ 2005-11-02 22:41 UTC (permalink / raw)
To: git, Petr Baudis
Signed-off-by: Pavel Roskin <proski@gnu.org>
diff --git a/Makefile b/Makefile
index 1b61953..c02cfcf 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,8 @@ SCRIPT= cg-object-id cg-add cg-admin-lso
cg-branch-add cg-branch-ls cg-reset cg-clone cg-commit cg-diff \
cg-export cg-help cg-init cg-log cg-merge cg-mkpatch cg-patch \
cg-fetch cg-restore cg-rm cg-seek cg-status cg-tag cg-tag-ls cg-update \
- cg cg-admin-ls cg-push cg-branch-chg cg-admin-cat cg-clean
+ cg cg-admin-ls cg-push cg-branch-chg cg-admin-cat cg-clean \
+ cg-admin-setuprepo
LIB_SCRIPT=cg-Xlib cg-Xmergefile cg-Xfetchprogress
--
Regards,
Pavel Roskin
^ permalink raw reply related
* cogito: missing *.txt files in Documentation/tutorial-script
From: Pavel Roskin @ 2005-11-02 23:07 UTC (permalink / raw)
To: git, Petr Baudis
Hello!
Following files are missing in cogito:
Documentation/tutorial-script/0002-alice-license.txt
Documentation/tutorial-script/0009-alice-README.txt
Documentation/tutorial-script/0020-alice-CONTRIBUTORS.txt
I believe they weren't committed because *.txt is ignored in
Documentation/.gitignore
You may want to add Documentation/tutorial-script/.gitignore and put
following line in it:
!*.txt
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: cogito: missing *.txt files in Documentation/tutorial-script
From: Petr Baudis @ 2005-11-02 23:13 UTC (permalink / raw)
To: Pavel Roskin; +Cc: git
In-Reply-To: <1130972850.23026.11.camel@dv>
Hello,
Dear diary, on Thu, Nov 03, 2005 at 12:07:30AM CET, I got a letter
where Pavel Roskin <proski@gnu.org> told me that...
> Following files are missing in cogito:
>
> Documentation/tutorial-script/0002-alice-license.txt
> Documentation/tutorial-script/0009-alice-README.txt
> Documentation/tutorial-script/0020-alice-CONTRIBUTORS.txt
>
> I believe they weren't committed because *.txt is ignored in
> Documentation/.gitignore
>
> You may want to add Documentation/tutorial-script/.gitignore and put
> following line in it:
>
> !*.txt
thanks, good catch. Fixed, done, pushed out.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply
* Re: [PATCH] Warn when calling deref_tag() on broken tags
From: Junio C Hamano @ 2005-11-02 23:21 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20051102204101.GE1431@pasky.or.cz>
Petr Baudis <pasky@suse.cz> writes:
> Good idea. Not that I would be excited by the awing elegancy of the
> patch...
It turns out to be not so good idea. Some places call deref_tag
just to see if we can unwrap it but not having the referenced
object but having the tag object does not necessarily mean a
corrupt repository.
For example, after a fetch that retrieved and stored a tag
object but was interrupted before retrieving and storing the
object the tag refers to, we do not update the refs of our end
(which is correct). After this, imagine fetching from the same
remote for the same tag. fetch-pack.c::everything_local will
find that we do have the tag object the remote says it has,
hoping that we can mark it one of the common refs, if that tag
is something reachable from our refs (it is not). The caller of
the deref_tag() there is careful not to assume the tag is
complete, but it should not bark -- we should just ignore and
pretend that dangling tag object is something we do not have.
I've done it a slightly differently. Does this look OK to you?
-- >8 -- cut here -- >8 --
Subject: [PATCH] Be careful when dereferencing tags.
One caller of deref_tag() was not careful enough to make sure
what deref_tag() returned was not NULL (i.e. we found a tag
object that points at an object we do not have). Fix it, and
warn about refs that point at such an incomplete tag where
needed.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
commit.c | 2 +-
fetch-pack.c | 7 ++++---
name-rev.c | 2 +-
send-pack.c | 4 ++--
server-info.c | 7 ++++---
sha1_name.c | 2 +-
tag.c | 7 ++++++-
tag.h | 2 +-
upload-pack.c | 2 +-
9 files changed, 21 insertions(+), 14 deletions(-)
applies-to: 003cf1e61da5c5fe13ed574ae3630c1ee8b56cae
30a28f848f666ae6f6641baa2917a8ea15ad3160
diff --git a/commit.c b/commit.c
index 8f40318..a8c9bfc 100644
--- a/commit.c
+++ b/commit.c
@@ -55,7 +55,7 @@ static struct commit *check_commit(struc
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
int quiet)
{
- struct object *obj = deref_tag(parse_object(sha1));
+ struct object *obj = deref_tag(parse_object(sha1), NULL, 0);
if (!obj)
return NULL;
diff --git a/fetch-pack.c b/fetch-pack.c
index 3df9911..cb21715 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -38,9 +38,9 @@ static void rev_list_push(struct commit
static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
{
- struct object *o = deref_tag(parse_object(sha1));
+ struct object *o = deref_tag(parse_object(sha1), path, 0);
- if (o->type == commit_type)
+ if (o && o->type == commit_type)
rev_list_push((struct commit *)o, SEEN);
return 0;
@@ -317,7 +317,8 @@ static int everything_local(struct ref *
* Don't mark them common yet; the server has to be told so first.
*/
for (ref = *refs; ref; ref = ref->next) {
- struct object *o = deref_tag(lookup_object(ref->old_sha1));
+ struct object *o = deref_tag(lookup_object(ref->old_sha1),
+ NULL, 0);
if (!o || o->type != commit_type || !(o->flags & COMPLETE))
continue;
diff --git a/name-rev.c b/name-rev.c
index 21fecdf..59194f1 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -164,7 +164,7 @@ int main(int argc, char **argv)
continue;
}
- o = deref_tag(parse_object(sha1));
+ o = deref_tag(parse_object(sha1), *argv, 0);
if (!o || o->type != commit_type) {
fprintf(stderr, "Could not get commit for %s. Skipping.\n",
*argv);
diff --git a/send-pack.c b/send-pack.c
index 9f9a6e7..3eeb18f 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -126,12 +126,12 @@ static int ref_newer(const unsigned char
/* Both new and old must be commit-ish and new is descendant of
* old. Otherwise we require --force.
*/
- o = deref_tag(parse_object(old_sha1));
+ o = deref_tag(parse_object(old_sha1), NULL, 0);
if (!o || o->type != commit_type)
return 0;
old = (struct commit *) o;
- o = deref_tag(parse_object(new_sha1));
+ o = deref_tag(parse_object(new_sha1), NULL, 0);
if (!o || o->type != commit_type)
return 0;
new = (struct commit *) o;
diff --git a/server-info.c b/server-info.c
index ba53591..0cba8e1 100644
--- a/server-info.c
+++ b/server-info.c
@@ -13,9 +13,10 @@ static int add_info_ref(const char *path
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
if (o->type == tag_type) {
- o = deref_tag(o);
- fprintf(info_ref_fp, "%s %s^{}\n",
- sha1_to_hex(o->sha1), path);
+ o = deref_tag(o, path, 0);
+ if (o)
+ fprintf(info_ref_fp, "%s %s^{}\n",
+ sha1_to_hex(o->sha1), path);
}
return 0;
}
diff --git a/sha1_name.c b/sha1_name.c
index fe409fb..be1755a 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -349,7 +349,7 @@ static int peel_onion(const char *name,
if (!o)
return -1;
if (!type_string) {
- o = deref_tag(o);
+ o = deref_tag(o, name, sp - name - 2);
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
memcpy(sha1, o->sha1, 20);
diff --git a/tag.c b/tag.c
index b1ab75f..e574c4b 100644
--- a/tag.c
+++ b/tag.c
@@ -3,10 +3,15 @@
const char *tag_type = "tag";
-struct object *deref_tag(struct object *o)
+struct object *deref_tag(struct object *o, const char *warn, int warnlen)
{
while (o && o->type == tag_type)
o = parse_object(((struct tag *)o)->tagged->sha1);
+ if (!o && warn) {
+ if (!warnlen)
+ warnlen = strlen(warn);
+ error("missing object referenced by '%.*s'", warnlen, warn);
+ }
return o;
}
diff --git a/tag.h b/tag.h
index 36e5324..7a0cb00 100644
--- a/tag.h
+++ b/tag.h
@@ -15,6 +15,6 @@ struct tag {
extern struct tag *lookup_tag(const unsigned char *sha1);
extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size);
extern int parse_tag(struct tag *item);
-extern struct object *deref_tag(struct object *);
+extern struct object *deref_tag(struct object *, const char *, int);
#endif /* TAG_H */
diff --git a/upload-pack.c b/upload-pack.c
index c5eff21..be63132 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -226,7 +226,7 @@ static int send_ref(const char *refname,
nr_our_refs++;
}
if (o->type == tag_type) {
- o = deref_tag(o);
+ o = deref_tag(o, refname, 0);
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
}
return 0;
---
0.99.9.GIT
^ permalink raw reply related
* New ASCII Art
From: jdl @ 2005-11-02 23:40 UTC (permalink / raw)
To: git
Junio,
I see my name over on the TODO list:
31 Documentation
32 -------------
33
34 * Help Jon Loeliger to find place in the documentation to place
35 his drawing.
So, I have updated drawings for consideration.
See if you buy these. And if so, let's ponder
where they might go. Then I'll patch 'em in...
I now have four ASCII Art drawings:
- Fundamental git operations
- Git merge operations
- Git diff types
- Commit DAG Revision Naming
jdl
Fundamental Git Index Operations
================================
commit-tree
commit obj
+----+
| |
| |
V V
+-----------+
| Object DB |
| Backing |
| Store |
+-----------+
^
write-tree | |
tree obj | |
| | read-tree
| | tree obj
V
+-----------+
| Index |
| "cache" |
+-----------+
update-index ^
blob obj | |
| |
checkout-index -u | | checkout-index
stat | | blob obj
V
+-----------+
| Working |
| Directory |
+-----------+
Git Merge Operations
====================
+-----------+
| Object DB |
| Backing |
| Store | -------+
+-----------+ |
|
read-tree -m |
+-----+ tree obj |
|patch| |
+-----+ +-----------+ |
| | Index | <- - - +
+------------->| "cache" | - - - >+
git-apply --index +-----------+ |
|
|
read-tree -m -u |
+-----+ tree obj |
|patch| |
+-----+ +-----------+ |
| | Working |<-------+
+-------------->| Directory |
git-apply +-----------+
Git Diff Types
==============
diff-tree
+----+
| |
| |
V V
+-----------+
| Object DB |
| Backing |
| Store |
+-----------+
^ ^
| |
| | diff-index --cached
| |
diff-index | V
| +-----------+
| | Index |
| | "cache" |
| +-----------+
| ^
| |
| | diff-files
| |
V V
+-----------+
| Working |
| Directory |
+-----------+
Commit DAG Revision Naming
==========================
Both node B and C are a commit parents of commit node A.
Parent commits are ordered left-to-right.
G H I J
\ / \ /
D E F
\ | /
\ | /
\|/
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2 = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
Fixed-point operations:
A^0 = A^{commit}
A^{tree}
^ permalink raw reply
* Re: [PATCH] Warn when calling deref_tag() on broken tags
From: Petr Baudis @ 2005-11-02 23:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vhdauocv6.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Thu, Nov 03, 2005 at 12:21:01AM CET, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> Petr Baudis <pasky@suse.cz> writes:
>
> > Good idea. Not that I would be excited by the awing elegancy of the
> > patch...
>
> It turns out to be not so good idea. Some places call deref_tag
> just to see if we can unwrap it but not having the referenced
> object but having the tag object does not necessarily mean a
> corrupt repository.
Aha, that didn't occur to me initially. Yes, what you did is fine by me
(not that I would be overly proficient in this part of code).
> diff --git a/tag.c b/tag.c
> index b1ab75f..e574c4b 100644
> --- a/tag.c
> +++ b/tag.c
> @@ -3,10 +3,15 @@
>
> const char *tag_type = "tag";
>
> -struct object *deref_tag(struct object *o)
> +struct object *deref_tag(struct object *o, const char *warn, int warnlen)
> {
> while (o && o->type == tag_type)
> o = parse_object(((struct tag *)o)->tagged->sha1);
> + if (!o && warn) {
> + if (!warnlen)
> + warnlen = strlen(warn);
> + error("missing object referenced by '%.*s'", warnlen, warn);
> + }
> return o;
> }
>
It should still be a warning, not an error, though. I'd also mention the
"tag" keyword in the message.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply
* Three-way merge with the index as one way
From: Petr Baudis @ 2005-11-03 0:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Zack Brown, git
In-Reply-To: <7v8xwummtm.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Sun, Oct 16, 2005 at 12:34:29AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> I suspect cg-Xlib::tree_timewarp, which currently does
> "git-read-tree -m $branch" followed by diff-tree piped to xargs,
> can be taught to use "git-read-tree -m -u $base $branch" (and
> lose the git-checkout-index -f -a immediately after that while
> we are at it), but I do not do Porcelain, so...
This is problematic, since with our current way of tree timewarping,
restoring local changes to files which got deleted will make patch error
out, etc.
I wanted to make tree_timewarp do three-way merge, but didn't figure a
good way to do it. First, what do I want - a two-way merge between two
trees, which will however respect (not die on) local changes in the
working tree.
One approach is to take the working tree, construct a tree object from
it and then run the regular three-way merge on that. But that is a waste
of time and pollutes the database with nonsensical objects. The
advantage is that I can reuse the per-file merge resolution script
without any changes.
However, this seems to be the only way to do this right now. What do you
think about the disadvantages - should we care? A possible alternative I
can imagine is to make a two-way merge mode which somehow records the
conflicts with index back in the index file instead of committing
suicide. Possibly the hex(-1) sha1 might be used for the relevant index
items, meaning "the current working copy". The per-file merge resolution
scripts would have to be tweaked for this then, but it shouldn't be that
hard; what I found hard was actually getting my head 'round the weird
git-read-tree code recording the stages in the index file. ;-)
Opinions?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply
* [PATCH] cogito: make tutorial-script a testsuite
From: Pavel Roskin @ 2005-11-03 1:16 UTC (permalink / raw)
To: git, Petr Baudis; +Cc: Horst H. von Brand
Documentation/tutorial-script/script.sh can be used as a testsuite.
Errors should cause the script to exit. Unexpected success should be
treated like an error. Successful completion should be reported.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
Currently, the last cg-merge invocation doesn't fail as it should, and
the subsequent ed scripts fail for Makefile and rpn.c. I don't have a
fix for that. Most likely, the script in cogito differs from the
original version. Horst, could you please have a look?
diff --git a/Documentation/tutorial-script/script.sh
b/Documentation/tutorial-script/script.sh
index 26adec0..fe43e65 100755
--- a/Documentation/tutorial-script/script.sh
+++ b/Documentation/tutorial-script/script.sh
@@ -1,10 +1,16 @@
-#!/bin/sh
+#!/bin/sh -e
#
# FIXME: This script has many GITisms. Some of them are unnecessary, while
# some stem from missing Cogito features (especially no support for pushing
# tags, and consequently no support for remotes/).
+should_fail () {
+ echo "Expected failure, got success - aborting" >&2
+ exit 1
+}
+
+
### Set up playground
sh 0000-playground.sh
TOP=$(pwd)
@@ -98,7 +104,7 @@ git branch
# Alice needs to register his remote branch
cg-branch-add bobswork $BOB/rpn
# Now try to merge Bob's work to the bob branch
-cg-update bobswork
+cg-update bobswork && should_fail
# There are conflicts in rpn.c. Looking at the file, Alice sees the
# difference between her version and Bob's:
@@ -190,11 +196,12 @@ cd $ALICE/rpn
git checkout master
# Alice tries "git merge" instead of "cg-merge" since she wanted to
# merge both branches at once, which "cg-merge" cannot do.
-git merge "Integrate changes from Bob and Charlie" master bob charlie
+git merge "Integrate changes from Bob and Charlie" master bob charlie \
+ && should_fail
# Automatic 3-way merge fails! Have to do it step by step
-cg-merge bob
+cg-merge bob && should_fail
# Merge fails:
@@ -213,7 +220,7 @@ ed Makefile < $TOP/0017-alice-bob-fixup.
cg-commit -m "Integrate Bob's changes"
-cg-merge charlie
+cg-merge charlie && should_fail
# Merge conflicts!
@@ -282,10 +289,10 @@ cg-fetch
# (Note that originally, rpn-0.4 was signed, but that would require you
# to set up a GPG key before running the script... verify-tag on unsigned
# scripts does not make much sense.)
-git verify-tag rpn-0.4
+git verify-tag rpn-0.4 && should_fail
# Everything's OK, integrate the changes
-echo "Merge with 0.4" | cg-merge
+echo "Merge with 0.4" | cg-merge && should_fail
# Merge conflicts in Makefile, rpn.c
# Mishandled stack.h
@@ -296,3 +303,6 @@ cg-add stack.h
# Now commit the whole
cg-commit -m "Merge with 0.4"
+
+# Great, we are done.
+echo "Script completed successfully!"
--
Regards,
Pavel Roskin
^ permalink raw reply related
* Now What?
From: Jon Loeliger @ 2005-11-03 1:30 UTC (permalink / raw)
To: git
The Other Day, I offered to help write up some parts of
a "Something weird just happened. Now What?" document.
So, I'm now soliciting suggestions and/or tips that can
be thrown together to form the basis of that document.
I have a few ideas and a rough outline up my sleeve, but
I am curious to know what _you_ think needs to be covered.
I think one of the most crucial aspects that needs to be
covered well is the "Merge Failed" problem. So, for starters,
I'd like to get your suggestions on this particular issue.
I know when I see the dreaded "merge by hand" message I
often sit and stare, pondering "Now what?"
I feel that an explanation of all of the behind-the-scripts-
in-.git communication files is needed. In particular these:
FETCH_HEAD
MERGE_HEAD
LAST_MERGE
MERGE_MSG
These need to be mentioned and explained because they
frequently form exactly the critical missing link or
starting point after a failed fetch or merge.
Finally, a procedure or style question. Should this
write-up be in the form of a structured FAQ? A stand-alone
expository document?
Thanks,
jdl
^ permalink raw reply
* Re: Now What?
From: Chris Shoemaker @ 2005-11-03 1:43 UTC (permalink / raw)
To: Jon Loeliger; +Cc: git
In-Reply-To: <E1EXTw5-00063o-Gt@jdl.com>
On Wed, Nov 02, 2005 at 07:30:37PM -0600, Jon Loeliger wrote:
>
> The Other Day, I offered to help write up some parts of
> a "Something weird just happened. Now What?" document.
>
> So, I'm now soliciting suggestions and/or tips that can
> be thrown together to form the basis of that document.
>
> I have a few ideas and a rough outline up my sleeve, but
> I am curious to know what _you_ think needs to be covered.
"I cloned a remote repo. Then I pulled a branch from the remote repo
and it started changing all the these files. I paniced and hit
ctrl-c. Doh! I should have checked out the branch locally before
pulling. Now what? How can I recover without cloning the repo
again?"
In general, for each common operation, it'd be nice to explain how to
"undo".
-chris
^ permalink raw reply
* Re: [PATCH] rev-list: make --max- and --min-age a bit more usable.
From: Linus Torvalds @ 2005-11-03 3:11 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbr12swj3.fsf_-_@assigned-by-dhcp.cox.net>
On Wed, 2 Nov 2005, Junio C Hamano wrote:
>
> > git-whatchanged -p --pretty=short --since="2 weeks ago" v0.99.8..v0.99.9 Makefile
> >
> > is a valid query
>
> Well, it is not a valid query ;-) Nobody implemented --since
> yet, but you could spell it --max-age. It would not grok "2
> weeks ago" though.
Have you tried it?
"--since" _works_.
All the magic is in "git-rev-parse". Try it.
> With the attached patch, you could at least do:
>
> git log --max-age='2005-10-25' v0.99.8..v0.99.9 Makefile
No. Really. _try_ it. You can do
git log --since="September 25"
And ItJustWorks(tm).
No patches needed. Anywhere. It's worked for quite a long time too. Since
commit c1babb1d65e034a058c14379eabec8eb374757ca, to be exact.
[PATCH] Teach "git-rev-parse" about date-based cut-offs
Just use it.
Linus
^ permalink raw reply
* Re: HTTP pushes
From: H. Peter Anvin @ 2005-11-03 4:12 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Nick Hengeveld, git
In-Reply-To: <Pine.LNX.4.64.0511011500580.25300@iabervon.org>
Daniel Barkalow wrote:
>
> You obviously need a bit more than HTTP...
>
Not really, as long as you can GET and POST arbitrary files. Arguably,
that's not how POST is typically used, though.
-hpa
^ permalink raw reply
* Re: [PATCH] rev-list: make --max- and --min-age a bit more usable.
From: Junio C Hamano @ 2005-11-03 7:40 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0511021908220.27915@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> All the magic is in "git-rev-parse". Try it.
Ahhhh. I missed that. Thanks.
-- >8 -- cut here -- >8 --
Document --since and --until options to rev-parse.
The usability magic were hidden in the source code without being
documented, and even the maintainer did not know about them ;-).
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 099db29..8b8068c 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -72,6 +72,14 @@ OPTIONS
path of the current directory relative to the top-level
directory.
+--since=datestring, --after=datestring::
+ Parses the date string, and outputs corresponding
+ --max-age= parameter for git-rev-list command.
+
+--until=datestring, --before=datestring::
+ Parses the date string, and outputs corresponding
+ --min-age= parameter for git-rev-list command.
+
<args>...::
Flags and parameters to be parsed.
^ permalink raw reply related
* Re: Three-way merge with the index as one way
From: Junio C Hamano @ 2005-11-03 8:02 UTC (permalink / raw)
To: Petr Baudis; +Cc: Zack Brown, git
In-Reply-To: <20051103003423.GH1431@pasky.or.cz>
Petr Baudis <pasky@suse.cz> writes:
> One approach is to take the working tree, construct a tree object from
> it and then run the regular three-way merge on that. But that is a waste
> of time and pollutes the database with nonsensical objects. The
> advantage is that I can reuse the per-file merge resolution script
> without any changes.
For a large tree, constructing a full tree just to merge a
couple of potentially conflicting paths might turn out be a
waste of time, but I suspect that is something you could
optimize later. git-am 3-way fallback logic constructs a sparse
temporary tree and uses it for running regular 3-way, and you
may be able to do something similar. Right now git-am takes an
e-mail patch and when it runs all the way it creates a commit,
but the core logic that applies patch and falls back to 3-way
could be separated out for your application. Then you could:
(1) 'git diff HEAD' before tree-warp to preserve the user
changes, (2) clean up the working tree to match HEAD, (3) warp
to the other tree, and (4) fed the user change perserved to
git-am core logic. That might give you something near optimum.
About "nonsensical" objects, I am not so sure how nonsensical
those objects you would record from the working tree
(intermediate state) are. If you find two trees match on a path
that has changed in the working tree, there won't be any
conflict on that paths so it is like the user did an extra
git-update-index on that path when no merge or warp is involved,
from object database pollution POV; I do not personally think
that is such a bad thing.
^ permalink raw reply
* Problem cloning the Linux history tree
From: Marcel Holtmann @ 2005-11-03 8:56 UTC (permalink / raw)
To: git; +Cc: Thomas Gleixner
Hi guys,
I have some problems cloning the Linux history tree from Thomas Gleixner
over the HTTP transport. The rsync transport seems to work.
# cg-clone http://www.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
defaulting to local storage area
09:53:02 URL:http://www.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/HEAD [41/41] -> "refs/heads/.origin-fetching" [1]
Getting alternates list
Getting pack list
error: The requested URL returned error: 404
error: Unable to find e7e173af42dbf37b1d946f9ee00219cb3b2bea6a under http://www.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/
Cannot obtain needed object e7e173af42dbf37b1d946f9ee00219cb3b2bea6a
while processing commit 0000000000000000000000000000000000000000.
cg-fetch: objects fetch failed
cg-clone: fetch failed
Regards
Marcel
^ 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