* Re: question on merges
From: Linus Torvalds @ 2005-05-02 15:56 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: git
In-Reply-To: <20050502151200.GA4592@xi.wantstofly.org>
On Mon, 2 May 2005, Lennert Buytenhek wrote:
>
> If a git user has X as his most recent local commit, and merges in a
> commit Y from someone else to create commit Z, shouldn't commit Z have
> both commit X and Y as parents? Or is is the other way round and is it
> perfectly well possible that a 'merge commit' only has one parent?
There are two classes of git merges:
- the "totally trivial one", where one side is fully contained within the
other (ie one side has not done any development at all)
In this case, the "merge" ends up being a no-op, and just ends up being
a trivial "update" to the bigger set of objects. There are no two
parents, because the merge never even creates a new commit - it just
takes the top commit from the other side.
- a real merge, where both repositories have had concurrent development,
and then you see a new merge commit that has two parents (and they'll
be the two HEAD commits of the repositories).
So I assume you're just seeing the trivial case, but if what you're seeing
doesn't seem to match that pattern, then holler.
NOTE! There's a real reason why the trivial merge _has_ to be just a plain
"fast-forward the history to the new state", namely the fact that if you
create a new merge-node for that, then you can never ever "stabilize":
people merging back and forth will always get new nodes, and you end up
with this run-away situation where you can never get the same tree on both
sides.
Linus
^ permalink raw reply
* Re: question on merges
From: Sean @ 2005-05-02 15:47 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: git
In-Reply-To: <20050502151200.GA4592@xi.wantstofly.org>
On Mon, May 2, 2005 11:12 am, Lennert Buytenhek said:
> Hi,
>
> If a git user has X as his most recent local commit, and merges in a
> commit Y from someone else to create commit Z, shouldn't commit Z have
> both commit X and Y as parents? Or is is the other way round and is it
> perfectly well possible that a 'merge commit' only has one parent?
>
> In the current linux-2.6 git tree, gregkh clones torvalds'
> 7f907d7486f2519c2ff1493bfbcdc36dcacd85b7 and creates a chain of commits
> starting with ac21e9ff08db3d6fac41d356c77fcb531c2e03e1 and ending in
> e838a0d4d5260bce452c96914a6e86b217c53c55. torvalds merges this chain
> back into his version in a9e4820c4c170b3df0d2185f7b4130b0b2daed2c, but
> that commit has as parents e838a0d4d5260bce452c96914a6e86b217c53c55
> (gregkh's last commit), and c0698f2f6e4839ce9463ce731c892993215ea067,
> one of jejb's intermediate commits. But now why is
> 7f907d7486f2519c2ff1493bfbcdc36dcacd85b7 not a parent of
> a9e4820c4c170b3df0d2185f7b4130b0b2daed2c? I would expect it to be,
> since it is linus' most recent local commit when he merges in gregkh's
> tree.
>
> This pattern happens a few more times:
> - davem creates c4d541106bc5d0a2134aaf9e8735eee3c70b0db2 from torvalds'
> 561bbe3235da614562fb26bb14042af684971a2d, and torvalds merges davem's
> tree back in at a2755a80f40e5794ddc20e00f781af9d6320fafb (v2.6.12-rc3),
> but that commit only has one parent (even though it's a merge.)
>
> See this image:
> http://www.liacs.nl/~buytenh/graph_2cacb3da620a4a93f3a77e1d2c8c06bb3c74bcb0.png
Hi Lennert,
Nice work, the labelled vectors are a nice touch. How hard would it be to
add a format where all linear commits on a single branch were listed in a
single bubble? That would reduce the size of the graphic considerably
with no loss of info.
As for your question the top of Linus' tree at that merge was actually
commit c0698f2f6e4839ce9463ce731c892993215ea067 :
tree b05fc8a950ace937460212e996441e4c05a227f6
parent cb624029cab62e5415287d15b2ec907b8f322ff5
parent 7f907d7486f2519c2ff1493bfbcdc36dcacd85b7
author James Bottomley <jejb@titanic> 1113875709 -0500
committer James Bottomley <jejb@titanic> 1113875709 -0500
fully merge up to scsi-misc-2.6
-----
Which includes the 7f90* parent for a9e4* you were expecting. The graph
kind of hides the fact that c069* actually originated in his tree and was
actually his most recent local commit when he merged with gregkh.
Sean
^ permalink raw reply
* question on merges
From: Lennert Buytenhek @ 2005-05-02 15:12 UTC (permalink / raw)
To: git
Hi,
If a git user has X as his most recent local commit, and merges in a
commit Y from someone else to create commit Z, shouldn't commit Z have
both commit X and Y as parents? Or is is the other way round and is it
perfectly well possible that a 'merge commit' only has one parent?
In the current linux-2.6 git tree, gregkh clones torvalds'
7f907d7486f2519c2ff1493bfbcdc36dcacd85b7 and creates a chain of commits
starting with ac21e9ff08db3d6fac41d356c77fcb531c2e03e1 and ending in
e838a0d4d5260bce452c96914a6e86b217c53c55. torvalds merges this chain
back into his version in a9e4820c4c170b3df0d2185f7b4130b0b2daed2c, but
that commit has as parents e838a0d4d5260bce452c96914a6e86b217c53c55
(gregkh's last commit), and c0698f2f6e4839ce9463ce731c892993215ea067,
one of jejb's intermediate commits. But now why is
7f907d7486f2519c2ff1493bfbcdc36dcacd85b7 not a parent of
a9e4820c4c170b3df0d2185f7b4130b0b2daed2c? I would expect it to be,
since it is linus' most recent local commit when he merges in gregkh's
tree.
This pattern happens a few more times:
- davem creates c4d541106bc5d0a2134aaf9e8735eee3c70b0db2 from torvalds'
561bbe3235da614562fb26bb14042af684971a2d, and torvalds merges davem's
tree back in at a2755a80f40e5794ddc20e00f781af9d6320fafb (v2.6.12-rc3),
but that commit only has one parent (even though it's a merge.)
See this image:
http://www.liacs.nl/~buytenh/graph_2cacb3da620a4a93f3a77e1d2c8c06bb3c74bcb0.png
cheers,
Lennert
^ permalink raw reply
* Re: [PATCH] add git.spec and adapt Makefile for RPM build
From: Kay Sievers @ 2005-05-02 14:52 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
In-Reply-To: <20050502102303.GA22630@vrfy.org>
On Mon, May 02, 2005 at 12:23:03PM +0200, Kay Sievers wrote:
> Add support for building the rpm package directly from the git tree.
This version creates the git.spec from a git.spec.in with the version
number from the Makefile.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
---
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,12 @@
# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
# break unless your underlying filesystem supports those sub-second times
# (my ext3 doesn't).
+
+VERSION = 0.7
+
+prefix=$(HOME)
+bindir=$(prefix)/bin
+
CFLAGS=-g -O2 -Wall
CC=gcc
@@ -25,8 +31,15 @@ PROG= git-update-cache git-diff-files
all: $(PROG)
+git.spec: git.spec.in Makefile
+ sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@
+
install: $(PROG) $(SCRIPTS)
- install $(PROG) $(SCRIPTS) $(HOME)/bin/
+ install -m755 -d $(DESTDIR)$(bindir)
+ install $(PROG) $(SCRIPTS) $(DESTDIR)$(bindir)
+
+uninstall:
+ cd $(DESTDIR)$(bindir) && rm $(PROG) $(SCRIPTS)
LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
tag.o date.o
@@ -110,7 +123,7 @@ diff.o: $(LIB_H)
strbuf.o: $(LIB_H)
clean:
- rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(LIB_FILE)
+ rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(LIB_FILE) git.spec
backup: clean
cd .. ; tar czvf dircache.tar.gz dir-cache
Created: git.spec.in (mode:100644)
--- /dev/null
+++ b/git.spec.in
@@ -0,0 +1,44 @@
+Name: git
+Version: @@VERSION@@
+Release: 1
+Vendor: Linus Torvalds <torvalds@osdl.org>
+Summary: git
+License: GPL
+Group: Development/Tools
+URL: http://www.kernel.org/pub/software/scm/git/
+Source: http://www.kernel.org/pub/software/scm/git/%{name}-%{version}.tar.bz2
+Provides: git = %{version}
+BuildRequires: zlib-devel openssl-devel curl-devel
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Prereq: sh-utils diffutils
+
+%description
+git is an fast and flexible filesystem-based database designed to store directory
+trees with regard to their history. It is the base for SCM tools bild on top of
+git like cogito.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT prefix=/usr install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+/usr/bin/*
+#%{_mandir}/*/*
+
+%changelog
+* Thu May 2 2005 Kay Sievers <kay.sievers@vrfy.org> 0.7-1
+- rpm build for core git
+
+* Thu Apr 21 2005 Chris Wright <chrisw@osdl.org> 0.6.3-1
+- Initial rpm build
^ permalink raw reply
* [PATCH] add git.spec and adapt Makefile for RPM build
From: Kay Sievers @ 2005-05-02 10:23 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds
Add support for building the rpm package directly from the git tree.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
---
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,10 @@
# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
# break unless your underlying filesystem supports those sub-second times
# (my ext3 doesn't).
+
+prefix=$(HOME)
+bindir=$(prefix)/bin
+
CFLAGS=-g -O2 -Wall
CC=gcc
@@ -26,7 +30,11 @@ PROG= git-update-cache git-diff-files
all: $(PROG)
install: $(PROG) $(SCRIPTS)
- install $(PROG) $(SCRIPTS) $(HOME)/bin/
+ install -m755 -d $(DESTDIR)$(bindir)
+ install $(PROG) $(SCRIPTS) $(DESTDIR)$(bindir)
+
+uninstall:
+ cd $(DESTDIR)$(bindir) && rm $(PROG) $(SCRIPTS)
LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
tag.o date.o
Created: git.spec (mode:100644)
--- /dev/null
+++ b/git.spec
@@ -0,0 +1,44 @@
+Name: git
+Version: 0.7
+Release: 1
+Vendor: Linus Torvalds <torvalds@osdl.org>
+Summary: git
+License: GPL
+Group: Development/Tools
+URL: http://www.kernel.org/pub/software/scm/git/
+Source: http://www.kernel.org/pub/software/scm/git/%{name}-%{version}.tar.bz2
+Provides: git = %{version}
+BuildRequires: zlib-devel openssl-devel curl-devel
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Prereq: sh-utils diffutils
+
+%description
+git is an fast and flexible filesystem-based database designed to store directory
+trees with regard to their history. It is the base for SCM tools bild on top of
+git like cogito.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT prefix=/usr install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+/usr/bin/*
+#%{_mandir}/*/*
+
+%changelog
+* Thu May 2 2005 Kay Sievers <kay.sievers@vrfy.org> 0.7-1
+- rpm build for core git
+
+* Thu Apr 21 2005 Chris Wright <chrisw@osdl.org> 0.6.3-1
+- Initial rpm build
^ permalink raw reply
* Re: gitweb.pl on kernel.org non-functional
From: H. Peter Anvin @ 2005-05-02 7:00 UTC (permalink / raw)
To: Rene Scharfe; +Cc: Kay Sievers, git
In-Reply-To: <4275C582.7020602@lsrfire.ath.cx>
Rene Scharfe wrote:
> Hi,
>
> none of the projects linked on http://www.kernel.org/git/ seem to list
> their commits anymore. The repositories are still there, so it looks
> like a glitch in gitweb.cgi.
>
Indeed. I have reverted the update.
-hpa
^ permalink raw reply
* gitweb.pl on kernel.org non-functional
From: Rene Scharfe @ 2005-05-02 6:15 UTC (permalink / raw)
To: H. Peter Anvin, Kay Sievers; +Cc: git
Hi,
none of the projects linked on http://www.kernel.org/git/ seem to list
their commits anymore. The repositories are still there, so it looks
like a glitch in gitweb.cgi.
Rene
^ permalink raw reply
* Colorize "Acked-by:" like "Signed-off-by:" in cg-log
From: Frank Sorenson @ 2005-05-02 6:01 UTC (permalink / raw)
To: git, Petr Baudis
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This patch adds color to "Acked-by:" lines in cg-log
Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
Colorize "Acked-by:" in cg-log
- ---
commit 3da886f11c286089586596e01e03aec1df5eab7f
tree afec725c306afc453ef4cbfd4a3e657016a745f2
parent f9be53a0dd1594f39b2e166ca064b781546f4c46
author sorenson <sorenson@moebius.cs.byu.edu> 1115013121 -0600
committer sorenson <sorenson@moebius.cs.byu.edu> 1115013121 -0600
Index: cg-log
===================================================================
- --- 320ae30b42c144f8970bf8e9fae3ef6b91cab5b9/cg-log (mode:100755 sha1:b0e109f36609878ad91020811ea0aa5cde9c1138)
+++ afec725c306afc453ef4cbfd4a3e657016a745f2/cg-log (mode:100755 sha1:b10bc72715319e536ec591a7bfd788f2de4c7017)
@@ -74,6 +74,7 @@
~ "")
~ echo; sed -re '
~ / *Signed-off-by:.*/Is//'$colsignoff'&'$coldefault'/
+ / *Acked-by:.*/Is//'$colsignoff'&'$coldefault'/
~ s/./ &/
~ '
~ ;;
Frank
- --
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
frank@tuxrocks.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFCdcIlaI0dwg4A47wRAgZYAJ94qxTw9ttKKY0YYYK6w0gElIp39wCfXg1S
qidz2hXjOvcjpLjaDMoQ7J0=
=r6sB
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: PATCH[2/4]: Allow tree-id to return the ID of a tree object
From: Philip Pokorny @ 2005-05-02 5:46 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <42708D8E.10003@mindspring.com>
Philip Pokorny wrote:
> Convert commit-id to use the new cg-Xnormid internal script
>
> Signed-off-by: Philip Pokorny <ppokorny@mindspring.com>
Were these patches accepted?? I ask because while I do seem to see the
addition of the new cg-Xnormid, I don't see that tree-id and friends
have been updated to use the new file.
But then again, I seem to be having trouble getting my git working
directory to track or match the current head. That would be:
49612c471eebd26efe926a71752e254c1cdc382d
right?
Wait... Perhaps I'm seeing cg-Xnormid because it was an "other" file
and therefore left in my directory. But that still doesn't explain why
my checkedout cache doesn't show the results of the latest changes to
cg-help... Even after running 'cg-update origin'
I'm so confused. It seems difficult to know exactly what the state of
your cache actually *is* at any given time. Shouldn't cg-status tell
you that you have modified, but uncommited files in your cache? Is
there any way to know what the tree-id/commit-id your cache is an
instance of? Do you have to 'cat .git/blocked' and 'ls -l .git/HEAD' to
know?
In clearcase, I could 'ct lsview' and 'ct catcs' to see what my current
view/cache was. I can't find the equivalent in cogito...
:v)
^ permalink raw reply
* semi-useful git perl file
From: Joshua T. Corbin @ 2005-05-02 5:33 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 607 bytes --]
I've been playing around with driving git from perl land. The attached
allows you to easily access git objects from perl as:
tie %git, 'GIT::ObjectDB';
print Dumper( $git{ $commit_id } );
Looks like:
{
type => 'commit',
sha => $commit_id,
tree => '0000000000000000000000000000000000000000',
parents => [ ... ],
mess => "\nbla bla bla\n"
}
And corresponding for trees, tags, and blobs.
If you want to see use of this in action, you can pull my (incomplete)
translation of cogito into perl from:
http://node1.wunjo.org/~jcorbin/yagf.git
or
rsync://node1.wunjo.org/yagf.git
Josh
[-- Attachment #2: GIT.pm --]
[-- Type: text/x-perl, Size: 9467 bytes --]
package GIT;
use strict;
our %cmd;
sub cmdpath {
my $cmd = shift;
unless ( defined $cmd{$cmd} ) {
local $/ = "\n";
chomp( $cmd{$cmd} = `which $cmd` );
return undef if $cmd{$cmd} eq '';
}
return $cmd{$cmd};
}
sub cmd {
my $cmd = shift;
cmdpath( $cmd ) || die "command '$cmd' not found\n";
my $r = system( $cmd{$cmd}, @_ );
die "$cmd failed: " . cmderrmsg( $cmd ) . "\n"
if $r != 0;
return 1;
}
sub cmdinout {
my $infh = shift;
my $cmd = shift;
cmdpath( $cmd ) || die "command '$cmd' not found\n";
my ( $r, $w );
pipe( $r, $w ) || die "Failed to pipe: $!";
my $pid = fork();
die "Failed to fork: $!" unless defined $pid;
if ( $pid ) {
close $w;
my $kid = waitpid( $pid, 0 );
die "Hmm, auto reaping in place?" if $kid == -1;
die "$cmd failed: " . cmderrmsg( $cmd ) . "\n"
if $? & 127 || $? >> 8 != 0;
local $/;
local $_ = <$r>;
close $r;
if ( wantarray ) {
return split( "\n", $_ );
} else {
return $_;
}
} else {
close $r;
close STDOUT;
close STDIN;
open STDIN, '<&', $infh || die "Failed to rediret STDIN";
open STDOUT, '>&', $w || die "Failed to redirect STDOUT";
exec( $cmd{$cmd}, @_ );
}
}
sub cmdout {
my $callback = shift if ref $_[0] eq 'CODE';
my $cmd = shift;
cmdpath( $cmd ) || die "command '$cmd' not found\n";
my ( $r, $w );
pipe( $r, $w ) || die "Failed to pipe: $!";
my $pid = fork();
die "Failed to fork: $!" unless defined $pid;
if ( $pid ) {
close $w;
if ( defined $callback ) {
local $_;
while ( <$r> ) {
if ( &$callback() ) {
kill 15, $pid;
last;
}
}
close $r;
waitpid( $pid, 0 );
return 1;
} else {
my $kid = waitpid( $pid, 0 );
die "Hmm, auto reaping in place?" if $kid == -1;
die "$cmd failed: " . cmderrmsg( $cmd ) . "\n"
if $? & 127 || $? >> 8 != 0;
if ( wantarray ) {
my @r = <$r>;
close $r;
chomp @r;
return @r;
} else {
local $/;
my $r = <$r>;
close $r;
return $r;
}
}
} else {
close $r;
close STDOUT;
open STDOUT, '>&', $w || die "Failed to redirect STDOUT";
exec( $cmd{$cmd}, @_ );
}
}
sub cmderrmsg {
my $cmd = shift;
my $e;
if ( $? == -1 ) {
$e = "failed to execute $cmd{$cmd}: $!";
} elsif ( $? & 127 ) {
$e = sprintf( 'child died from signal %d', ( $? & 127 ) );
$e .= ' (with coredump)' if $? & 128;
} else {
$e = sprintf( 'child exit value: %d', $? >> 8 );
}
return $e;
}
package GIT::ObjectDB;
use strict;
# Cache this many commit/tree/tag objects, blobs are not cached because they are (possibly) huge.
our $CacheMax = 20;
our $MissingFatal;
use Carp qw( croak );
sub TIEHASH {
my ( $class, $dir ) = @_;
$dir ||= $ENV{SHA1_FILE_DIRECTORY} || '.git/objects';
$ENV{SHA1_FILE_DIRECTORY} = $dir
if $dir ne '.git/objects';
( -d $dir ) || croak "No such directory $dir";
bless my $self = {
dir => $dir,
types => {},
cache => {}, # What we're caching
cachea => [] # The order we cached it in so
} => $class;
return $self;
}
sub FETCH {
my ( $self, $key ) = @_;
croak "Invalid sha1 key '$key'" unless $key =~ /^[A-Za-z0-9]{40}$/;
return $self->{ cache }->{ $key }
if defined $self->{ cache }->{ $key };
my $type = $self->objectType( $key );
unless ( defined $type ) {
die "no such object $key" if $MissingFatal;
return undef;
}
if ( $type eq 'blob' ) {
return new GIT::ObjectDB::Blob( $key );
} else {
if ( $type eq 'tree' ) {
$self->{ cache }->{ $key } =
GIT::ObjectDB::Tree->new_fromkey( $key );
} elsif ( $type eq 'commit' ) {
$self->{ cache }->{ $key } =
GIT::ObjectDB::Commit->new_fromkey( $key );
} elsif ( $type eq 'tag' ) {
$self->{ cache }->{ $key } =
GIT::ObjectDB::Tag->new_fromkey( $key );
} else {
croak "Unrecognized object($key) type '$type'";
}
push @{ $self->{ cachea } }, $key;
while ( scalar @{ $self->{ cachea } } > $CacheMax ) {
my $k = shift @{ $self->{ cachea } };
delete $self->{ cache }->{ $k };
}
return $self->{ cache }->{ $key };
}
}
sub STORE {
my ( $self, $key, $value ) = @_;
croak "Will not overwrite an object"
if defined $self->objectType( $key );
if ( UNIVERSAL::isa( $value, 'GIT::ObjectDB::Commit' ) ) {
my $mess = $value->{ mess };
$mess =~ /^\s*$/s && croak "Won't commit an empty message";
my $fh;
open $fh, '<', \$mess;
chomp( $value->{ sha } = GIT::cmdinout( $fh,
'git-commit-tree', $value->{ tree },
map { ( '-p', $_ ) } @{ $value->{ parents } }
) );
close $fh;
} elsif ( UNIVERSAL::isa( $value, 'GIT::ObjectDB::Tag' ) ) {
my $type = $self->objectType( $value->{ object } ) ||
croak "No such object $value->{object}";
croak "Tagging a tag?" if $type eq 'tag';
my $tag =
"object $value->{object}\n" .
"type $type\n" .
"tag $value-{tag}\n" .
$value->{ sig };
my $fh;
open $fh, '<', \$tag;
chomp( $value->{ sha } = GIT::cmdinout( $fh, 'git-mktag' ) );
close $fh;
} else {
croak "Only support storing commits and tags";
}
push @{ $self->{ cachea } },
$self->{ cache }->{ $value->{ sha } } = $value;
while ( scalar @{ $self->{ cachea } } > $CacheMax ) {
my $k = shift @{ $self->{ cachea } };
delete $self->{ cache }->{ $k };
}
}
sub EXISTS {
my ( $self, $key ) = @_;
return defined( $self->objectType( $key ) ) ? 1 : 0;
}
sub FIRSTKEY {
my ( $self ) = @_;
if ( defined $self->{ dh } ) {
closedir $self->{ dh };
delete $self->{ dh };
}
$self->{ i } = -1;
return $self->NEXTKEY;
}
sub NEXTKEY {
my ( $self ) = @_;
my $r;
until ( defined $r ) {
if ( defined $self->{ dh } ) {
$r = readdir $self->{ dh };
unless ( defined $r ) {
closedir $self->{ dh };
delete $self->{ dh };
next;
}
$r = undef if $r !~ /^[A-Za-z0-9]{38}$/;
$r = sprintf( '%02x%s', $self->{ i }, $r ) if defined $r;
} else {
$self->{ i }++;
last if $self->{ i } > 0xff;
my $dh;
my $dir = sprintf( '%s/%02x', $self->{ dir }, $self->{ i } );
opendir $dh, $dir ||
die "Failed to opendir $dir: $!";
$self->{ dh } = $dh;
next;
}
}
return $r;
}
sub SCALAR {
my ( $self ) = @_;
return $self->{ dir };
}
sub UNTIE {
my ( $self ) = @_;
closedir $self->{ dh } if defined $self->{ dh };
}
sub objectType {
my ( $self, $key ) = @_;
eval {
chomp(
( $self->{ types }->{ $key } ) =
GIT::cmdout( 'git-cat-file', '-t', $key )
) unless defined $self->{ types }->{ $key };
};
return undef if $@;
return $self->{ types }->{ $key };
}
package GIT::ObjectDB::Blob;
use strict;
sub new {
my ( $class, $key ) = @_;
bless {
type => 'blob',
sha => $key
} => $class;
}
sub contents {
my ( $self ) = @_;
return GIT::cmdout( 'git-cat-file', 'blob', $self->{ sha } );
}
sub write_to_filehandle {
my ( $self, $fh ) = @_;
GIT::cmdout( sub {
print $fh $_;
return 0;
}, 'git-cat-file', 'blob', $self->{ sha } );
return 1;
}
package GIT::ObjectDB::Commit;
use strict;
use Carp qw( croak );
sub new {
my $class = shift;
my $mess = shift || croak "Missing message";
my $tree = shift || croak "Missing tree";
$tree =~ /^[A-Za-z0-9]{40}$/ || croak "Invalid tree id";
my @parents = @_ or croak "Missing parent(s)";
for my $parent ( @parents ) {
$parent =~ /^[A-Za-z0-9]{40}$/ || croak "Invalid parent id '$parent'";
}
return bless {
type => 'commit',
parents => \@parents,
tree => $tree,
mess => $mess
} => $class;
}
sub new_fromkey {
my ( $class, $key ) = @_;
bless my $self = {
type => 'commit',
sha => $key,
parents => [],
mess => ''
} => $class;
local $/ = "\n";
my $no_more_parents;
GIT::cmdout( sub {
chomp;
if ( ! defined $self->{ tree } && /^tree ([A-Za-z0-9]{40})$/ ) {
$self->{ tree } = $1;
} elsif ( ! $no_more_parents && /^parent ([A-Za-z0-9]{40})$/ ) {
push @{ $self->{ parents } }, $1;
} else {
$no_more_parents = 1;
if ( ! defined $self->{ author } && /^author (.+) (\d+ [-+]\d{4})$/ ) {
$self->{ author } = [ $1, $2 ];
} elsif ( ! defined $self->{ committer } && /^committer (.+) (\d+ [-+]\d{4})$/ ) {
$self->{ committer } = [ $1, $2 ];
} else {
$self->{ mess } .= "$_\n";
}
}
return 0;
}, 'git-cat-file', 'commit', $key );
return $self;
}
package GIT::ObjectDB::Tree;
use strict;
sub new_fromkey {
my ( $class, $key ) = @_;
bless my $self = {
type => 'tree',
sha => $key,
ent => []
} => $class;
my $raw = GIT::cmdout( 'git-cat-file', 'tree', $key );
my @raw = unpack( '(Z*H40)*', $raw );
$raw = undef;
while ( @raw ) {
push @{ $self->{ ent } },
[ split( ' ', shift @raw, 2 ), shift @raw ];
}
return $self;
}
package GIT::ObjectDB::Tag;
use strict;
use Carp qw( croak );
sub new {
my $class = shift;
my $object = shift || croak "Missing object";
$object =~ /^[A-Za-z0-9]{40}$/ || croak "Invalid object id";
my $tag = shift || croak "Missing tag";
my $sig = shift || croak "Missing signature";
return bless {
type => 'tag',
object => $object,
tag => $tag,
sig => $sig
} => $class;
}
sub new_fromkey {
my ( $class, $key ) = @_;
bless my $self = {
type => 'tag',
sha => $key,
sig => ''
} => $class;
local $/ = "\n";
GIT::cmdout( sub {
if ( /^object ([A-Za-z0-9]{40})$/ ) {
$self->{ object } = $1;
} elsif ( /^type (.+)$/ ) {
$self->{ object_type } = $1;
} elsif ( /^tag (.+)$/ ) {
$self->{ tag } = $1;
} else {
$self->{ sig } .= $_;
}
return 0;
}, 'git-cat-file', 'tag', $key );
return $self;
}
^ permalink raw reply
* [PATCH] git-export complains about mising cat-file
From: Alexey Nezhdanov @ 2005-05-02 4:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git, snake
Fixes bits leaved during name change.
Signed-off-by: Alexey Nezhdanov <snake@penza-gsm.ru>
---
--- k/cat-file.c
+++ l/cat-file.c
@@ -13,7 +13,7 @@ int main(int argc, char **argv)
unsigned long size;
if (argc != 3 || get_sha1(argv[2], sha1))
- usage("cat-file [-t | tagname] <sha1>");
+ usage("git-cat-file [-t | tagname] <sha1>");
if (!strcmp("-t", argv[1])) {
buf = read_sha1_file(sha1, type, &size);
@@ -28,7 +28,7 @@ int main(int argc, char **argv)
}
if (!buf)
- die("cat-file %s: bad file", argv[2]);
+ die("git-cat-file %s: bad file", argv[2]);
while (size > 0) {
long ret = write(1, buf, size);
@@ -38,9 +38,9 @@ int main(int argc, char **argv)
/* Ignore epipe */
if (errno == EPIPE)
break;
- die("cat-file: %s", strerror(errno));
+ die("git-cat-file: %s", strerror(errno));
} else if (!ret) {
- die("cat-file: disk full?");
+ die("git-cat-file: disk full?");
}
size -= ret;
buf += ret;
--- k/export.c
+++ l/export.c
@@ -12,7 +12,7 @@ void show_commit(struct commit *commit)
strcpy(hex, sha1_to_hex(commit->object.sha1));
printf("Id: %s\n", hex);
fflush(NULL);
- sprintf(cmdline, "cat-file commit %s", hex);
+ sprintf(cmdline, "git-cat-file commit %s", hex);
system(cmdline);
if (commit->parents) {
char *against = sha1_to_hex(commit->parents->item->object.sha1);
^ permalink raw reply
* [PATCH] git-local-pull updates
From: Junio C Hamano @ 2005-05-02 3:41 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This is to be applied on top of the previous patch to add
git-local-pull command. In addition to the '-l' (attempt
hardlink before anything else) and the '-s' (then attempt
symlink) flags, it adds '-n' (do not fall back to file copy)
flag. Also it updates the comments.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
local-pull.c | 65 +++++++++++++++++++++++++++++++++++++----------------------
1 files changed, 41 insertions(+), 24 deletions(-)
# jit-diff -1:
# - Roll-up patches missing from Linus tree.
# + working-tree
--- k/local-pull.c
+++ l/local-pull.c
@@ -1,3 +1,6 @@
+/*
+ * Copyright (C) 2005 Junio C Hamano
+ */
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
@@ -10,6 +13,7 @@
static int use_link = 0;
static int use_symlink = 0;
+static int use_filecopy = 1;
static int verbose = 0;
static char *path;
@@ -25,9 +29,6 @@ int fetch(unsigned char *sha1)
static char filename[PATH_MAX];
char *hex = sha1_to_hex(sha1);
const char *dest_filename = sha1_file_name(sha1);
- int ifd, ofd, status;
- struct stat st;
- void *map;
if (object_name_start < 0) {
strcpy(filename, path); /* e.g. git.git */
@@ -46,33 +47,47 @@ int fetch(unsigned char *sha1)
say("Symlinked %s.\n", hex);
return 0;
}
- ifd = open(filename, O_RDONLY);
- if (ifd < 0 || fstat(ifd, &st) < 0) {
+ if (use_filecopy) {
+ int ifd, ofd, status;
+ struct stat st;
+ void *map;
+ ifd = open(filename, O_RDONLY);
+ if (ifd < 0 || fstat(ifd, &st) < 0) {
+ close(ifd);
+ fprintf(stderr, "Cannot open %s\n", filename);
+ return -1;
+ }
+ map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
close(ifd);
- fprintf(stderr, "Cannot open %s\n", filename);
- return -1;
- }
- map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
- close(ifd);
- if (-1 == (int)(long)map) {
- fprintf(stderr, "Cannot mmap %s\n", filename);
- return -1;
+ if (-1 == (int)(long)map) {
+ fprintf(stderr, "Cannot mmap %s\n", filename);
+ return -1;
+ }
+ ofd = open(dest_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ status = ((ofd < 0) ||
+ (write(ofd, map, st.st_size) != st.st_size));
+ munmap(map, st.st_size);
+ close(ofd);
+ if (status)
+ fprintf(stderr, "Cannot write %s (%ld bytes)\n",
+ dest_filename, st.st_size);
+ else
+ say("Copied %s.\n", hex);
+ return status;
}
- ofd = open(dest_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
- status = ((ofd < 0) || (write(ofd, map, st.st_size) != st.st_size));
- munmap(map, st.st_size);
- close(ofd);
- if (status)
- fprintf(stderr, "Cannot write %s (%ld bytes)\n",
- dest_filename, st.st_size);
- else
- say("Copied %s.\n", hex);
- return status;
+ fprintf(stderr, "No copy method was provided to copy %s.\n", hex);
+ return -1;
}
static const char *local_pull_usage =
-"git-local-pull [-c] [-t] [-a] [-l] [-s] [-v] commit-id path";
+"git-local-pull [-c] [-t] [-a] [-l] [-s] [-n] [-v] commit-id path";
+/*
+ * By default we only use file copy.
+ * If -l is specified, a hard link is attempted.
+ * If -s is specified, then a symlink is attempted.
+ * If -n is _not_ specified, then a regular file-to-file copy is done.
+ */
int main(int argc, char **argv)
{
char *commit_id;
@@ -92,6 +107,8 @@ int main(int argc, char **argv)
use_link = 1;
else if (argv[arg][1] == 's')
use_symlink = 1;
+ else if (argv[arg][1] == 'n')
+ use_filecopy = 0;
else if (argv[arg][1] == 'v')
verbose = 1;
else
^ permalink raw reply
* [PATCH] typo fixes to git-apply-patch-script
From: Junio C Hamano @ 2005-05-02 3:19 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
When git-apply-patch-script creates a new file without
executable mode set, a typo caused it not to report that
activity to the user. Also it was mistakenly running
git-update-cache twice for newly created or deleted paths. This
patch fixes these problems.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
****************************************************************
Linus, please do not forget to make this script EXECUTABLE this
time.
****************************************************************
jit-diff linus-mirror: git-apply-patch-script
# - Fix missing '\n' at end of git-cat-file -t output.
# + working-tree
Mode changed: git-apply-patch-script (100644->100755)
--- k/git-apply-patch-script
+++ l/git-apply-patch-script
@@ -31,7 +31,7 @@ test -f "$name.rej" || {
echo >&2 "created $name with mode +x."
chmod "$mode2" "$name"
;;
- -)
+ -x)
echo >&2 "created $name."
;;
esac
@@ -52,9 +52,7 @@ test -f "$name.rej" || {
chmod "$mode2" "$name"
;;
esac
+ git-update-cache -- "$name"
esac
- # This bit is debatable---the SCM may not want to keep
- # cache in sync with the work tree (JIT does want to).
- git-update-cache -- "$name"
}
exit 0
^ permalink raw reply
* Re: Just a note: .git/refs/snap/ is not standard
From: Daniel Barkalow @ 2005-05-02 3:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vacneqtn8.fsf@assigned-by-dhcp.cox.net>
On Sun, 1 May 2005, Junio C Hamano wrote:
> Linus,
>
> not that there is any "de facto" or any standard there, but
> the name .git/refs/snap/ you lifted from the vicinity thing is
> not something Cogito folks have. My understanding is of their
> concensus is that .git/refs have single level subdirectories
> like 'heads' and 'tags', and there will be little 41-byte text
> files that look like .git/HEAD.
I was intending this to be a more general concensus (and you seem to have
followed it with your "snap" subdirectory).
> So you probably would want to either (1) readdir in .git/refs (to future
> proof) or (2) drop refs/snap from the vicinity list for now (to not give
> special treatment to JIT, which I myself do not mind ;-)). Also if you
> go route (2) drop "refs" itself as well.
Actually, my code was intended to take things like "heads/master" or
"tags/linux-2.6.13", which are found under "refs/" (although I also check
that they don't start with "." and have exactly one "/", to enforce the
naming system). Making it "heads/linus" rather than "linus" is important
for writing the files, since you can't guess reliably what subdirectory
the user means; also, it is easier for dealing with HTTP servers, where
you don't know what to ask for.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Just a note: .git/refs/snap/ is not standard
From: Junio C Hamano @ 2005-05-02 1:54 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus,
not that there is any "de facto" or any standard there, but
the name .git/refs/snap/ you lifted from the vicinity thing is
not something Cogito folks have. My understanding is of their
concensus is that .git/refs have single level subdirectories
like 'heads' and 'tags', and there will be little 41-byte text
files that look like .git/HEAD. So you probably would want to
either (1) readdir in .git/refs (to future proof) or (2) drop
refs/snap from the vicinity list for now (to not give special
treatment to JIT, which I myself do not mind ;-)). Also if you
go route (2) drop "refs" itself as well.
^ permalink raw reply
* Re: description
From: Kay Sievers @ 2005-05-02 2:42 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Git Mailing List
In-Reply-To: <20050430124327.GA8942@vrfy.org>
On Sat, 2005-04-30 at 14:43 +0200, Kay Sievers wrote:
> Here is a new gitweb.cgi version that integrates with that page. The
> own project browser is removed now and the top-link points now to your
> link-list.
>
> !! It already uses the new binaries with the git-* prepended. !!
>
> See it working here:
> http://ehlo.org/~kay/git/
>
> Get the cgi from here:
> ftp://ehlo.org/git/gitweb.cgi
>
> !! Just remove lines 26-30, which are the settings to run on my box. !!
We've put a new version online. It's almost complete for a first basic
version and Christian and me can go back to "real" work now. :)
The version running on kernel.org shows a broken commit time, so it
would be nice, if it can be replaced.
Thanks,
Kay
^ permalink raw reply
* Re: Complete http-pull; where should it go?
From: Linus Torvalds @ 2005-05-02 2:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Daniel Barkalow, git, Petr Baudis
In-Reply-To: <7v4qdmqt8v.fsf@assigned-by-dhcp.cox.net>
On Sun, 1 May 2005, Junio C Hamano wrote:
>
> That's why I said I do not think this belongs to the Plumbing.
I've removed the ugly parent format, but to make it easier to script the
thing I removed, I just pushed out an improvement to "cat-file" which
makes it use the "read_object_with_reference()" helper to cat the object.
That means that if you use "git-cat-file tree" on a tag object, then it
will first look up the tag object, then the commit object and finally the
tree obejct, and it will cat that tree object. Of course, normally you'd
use it with a "commit" object and get the pleasure of having it "just
work" with tags too.
So for example, to get the parent of a commit (whether a tag that points
to a commit, or a real commit), you'd script something like
git-cat-file commit v2.6.12-rc3 | sed -n '/^parent /{s/parent //;p;q}'
which gets the first parent of the commit that was pointed to by the
"v2.6.12-rc3" tag.
If you want to see the tag itself, you'd just do
git-cat-file tag v2.6.12-rc3
like before, of course.
And "git-cat-file -t" always gives the top-level tag, so if you ask the
type of "v2.6.12-rc3" it will say "tag".
Linus
^ permalink raw reply
* Re: Complete http-pull; where should it go?
From: Daniel Barkalow @ 2005-05-02 2:31 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git, Petr Baudis
In-Reply-To: <Pine.LNX.4.58.0505011840590.2162@ppc970.osdl.org>
On Sun, 1 May 2005, Linus Torvalds wrote:
> That said, I end up still using the raw plumbing, so it's actually nice to
> have some simple shorthand. I just don't know if the parent thing ends up
> being all that useful.
I still prefer having get_sha1() handle just hex, refs, and files in
.git. Actually, just having it handle hex would probably be sufficient,
since the Porcelain can patch it cleanly with whatever is locally useful.
Any thoughts on my patches, which actually barely overlap with this
functionality?
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: Complete http-pull; where should it go?
From: Junio C Hamano @ 2005-05-02 2:03 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Daniel Barkalow, git, Petr Baudis
In-Reply-To: <Pine.LNX.4.58.0505011840590.2162@ppc970.osdl.org>
>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:
LT> Hmm.. I actually implemented it, because it's simple to
LT> implement, but now that I've tried using it, I just find it
LT> to be too much like line noise to do
LT> git-diff-tree -p 0-HEAD HEAD
LT> for "parent to current". The notation "-HEAD" also works,
LT> but since that looks like a command line flag, it's usually
LT> not useful, except when combined with other stuff, ie
LT> "0---HEAD" is "three parents up".
That's why I said I do not think this belongs to the Plumbing.
JIT command-line would do just "jit-diff" to get the diff
between the work tree and the commit (or snapshot) it is based
upon, without parameter. Fully spelled out, it would be
"jit-diff -1:1". This kind of syntax, although is quite useful
in JIT context (e.g. saying "jit-patch --2" to mean "apply
changes between snnapshot 2 and two parents up of it to my
current work tree"), I tend to agree that it is a bit too weird
for the core Plumbing layer, for which Unixy syntax is more
suitable.
^ permalink raw reply
* Re: Complete http-pull; where should it go?
From: Linus Torvalds @ 2005-05-02 1:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Daniel Barkalow, git, Petr Baudis
In-Reply-To: <7vsm16qyia.fsf@assigned-by-dhcp.cox.net>
On Sun, 1 May 2005, Junio C Hamano wrote:
>
> Shameless plug but could you take a look at how my JIT does it,
> at <http://members.cox.net/junkio/JITNotes.txt>, especially
> scroll down to near the bottom "Syntax to naming a snapshot or a
> commit" section?
Hmm.. I actually implemented it, because it's simple to implement, but now
that I've tried using it, I just find it to be too much like line noise to
do
git-diff-tree -p 0-HEAD HEAD
for "parent to current". The notation "-HEAD" also works, but since that
looks like a command line flag, it's usually not useful, except when
combined with other stuff, ie "0---HEAD" is "three parents up".
> I still think this kind of thing belongs to Porcelain not
> Plumbing, though.
I don't entirely disagree, and I suspect that Porcelain ends up using the
pure hex numbers which are always unambiguous.
That said, I end up still using the raw plumbing, so it's actually nice to
have some simple shorthand. I just don't know if the parent thing ends up
being all that useful.
Anyway, it's there. I don't love the parent syntax, but on the other hand,
I don't know how often I'd even end up using it (while the tag and HEAD
names are _very_ useful), so maybe it just doesn't matter.
Linus
^ permalink raw reply
* Anyone working on a CVS->git converter?
From: H. Peter Anvin @ 2005-05-02 1:42 UTC (permalink / raw)
To: Git Mailing List
Anyone working on a CVS->git converter? I'd like to move klibc
development into git.
-hpa
^ permalink raw reply
* Re: Current git archive location
From: H. Peter Anvin @ 2005-05-02 1:36 UTC (permalink / raw)
To: Sean; +Cc: git
In-Reply-To: <3860.10.10.10.24.1114996194.squirrel@linux1>
Sean wrote:
> rsync://www.kernel.org/pub/linux/kernel/people/torvalds/git.git doesn't
> seem to work anymore, where's the new location? Even looking at
> http://www.kernel.org/git/ it's not obvious where to pull it from.
rsync://rsync.kernel.org/pub/scm/git/git.git
-hpa
^ permalink raw reply
* Re: Current git archive location
From: Randy.Dunlap @ 2005-05-02 1:16 UTC (permalink / raw)
To: Sean; +Cc: git
In-Reply-To: <3860.10.10.10.24.1114996194.squirrel@linux1>
On Sun, 1 May 2005 21:09:54 -0400 (EDT) Sean wrote:
|
| rsync://www.kernel.org/pub/linux/kernel/people/torvalds/git.git doesn't
| seem to work anymore, where's the new location? Even looking at
| http://www.kernel.org/git/ it's not obvious where to pull it from.
http://www.kernel.org/pub/scm/* contains multiple project gits.
---
~Randy
^ permalink raw reply
* Current git archive location
From: Sean @ 2005-05-02 1:09 UTC (permalink / raw)
To: git
rsync://www.kernel.org/pub/linux/kernel/people/torvalds/git.git doesn't
seem to work anymore, where's the new location? Even looking at
http://www.kernel.org/git/ it's not obvious where to pull it from.
Thanks,
Sean
^ permalink raw reply
* Re: cg-log -r?
From: Alexander Beyn @ 2005-05-02 0:16 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20050502000447.GF974@pasky.ji.cz>
On Mon, May 02, 2005 at 02:04:47AM +0200, Petr Baudis wrote:
> Dear diary, on Mon, May 02, 2005 at 02:00:19AM CEST, I got a letter
> where Alexander Beyn <malex-git@fatelectrons.org> told me that...
> > I created it because I could never remember if cg-log or cg-diff requires
> > the -r before the revs.
>
> Actually, would you people hate me / Cogito / Richard Stallman if I
> added -r to cg-log and cg-mkpatch, for the sake of consistency?
> Extending cg-log to work on individual files would be then obvious.
>
I'd welcome this change, but I still like the ubiquitous -h and --help
on all the commands
Alexander
^ 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