Git development
 help / color / mirror / Atom feed
* Re: print errors from git-update-ref
From: Shawn Pearce @ 2006-07-28  6:27 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, Alex Riesen, Git Mailing List
In-Reply-To: <Pine.LNX.4.63.0607271302150.29667@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Hi,
> 
> On Wed, 26 Jul 2006, Shawn Pearce wrote:
> 
> > This change adds a test for trying to create a ref within a directory
> > that is actually currently a file, and adds error printing within
> > the ref locking routine should the resolve operation fail.
> 
> Why not just print an error message when the resolve operation fails, 
> instead of special casing this obscure corner case? It is way shorter, 
> too. The test should stay, though.

Did you read the patch?  If resolve_ref returns NULL then this
change prints an error (from errno) no matter what.  If errno is
ENOTDIR then it tries to figure out what part of the ref path wasn't
a directory (but was attempted to be used as such) and prints an
ENOTDIR error about that path instead of the one actually given
to the ref lock function

So I think I'm doing what you are suggesting...

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-07-28  5:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, alp
In-Reply-To: <20060728054341.15864.35862.stgit@machine>

Dear diary, on Fri, Jul 28, 2006 at 07:44:21AM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> So, you need some kind of porcelain for this. The idea is that instead of
> telling git-fetch-pack a single repository, you pass multiple --repo=
> parameters and refs always "belong" to the latest mentioned repository;
> when outputting the new ref values, the appropriate repo is mentioned near
> each ref. In order for this to be useful, on your local side you should
> share the objects database in some way - either using alternates (then
> you must fetch to an object database reachable from everywhere) or symlinked
> object databases.
> 
> You still need to pass git-fetch-pack some URL in addition to the
> repositories - it is used only for git_connect(), the purpose is that
> repositories must be local directories so if you want to talk remote, you
> need to do something like
> 
> 	git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master

This is a simple "porcelain" for it:

-->8--

#!/usr/bin/perl
use warnings;
use strict;

# Remember that you must ensure the obj database is shared - either symlink it
# or setup alternates!
#my $remoteurl = 'git://git.kernel.org/pub/scm/git/git.git';
#my %config = (
#	'/pub/scm/git/git.git' => {
#		'next' => {
#			'/home/xpasky/q/gg' => 'origin'
#		},
#		'master' => {
#			'/home/xpasky/q/gg' => 'origin2',
#			'/home/xpasky/q/gg2' => 'origin'
#		}
#	},
#	'/pub/scm/cogito/cogito-doc.git' => {
#		master => {
#			'/home/xpasky/q/gg2' => 'origin2'
#		}
#	}
#);
my $remoteurl = 'puturlofremotehosthere';
my %config = (
	'remoterepo1' => {
		branch1 => {
			'localrepo1' => 'origin'
		},
		branch2 => {
			'localrepo1' => 'origin2',
			'localrepo2' => 'origin'
		}
	},
	'remoterepo2' => {
		master => {
			'localrepo2' => 'origin2'
		}
	}
);

my @args = ($remoteurl);
foreach my $repo (keys %config) {
	push (@args, '--repo='.$repo);
	foreach my $branch (keys %{$config{$repo}}) {
		push (@args, $branch);
	}
}

open (F, '-|', 'git-fetch-pack', @args) or die "$!";
while (<F>) {
	chomp;
	split / /, $_;
	my ($sha, $ref, $repo) = @_;
	$ref =~ s#^refs/heads/##;
	foreach my $lrepo (keys %{$config{$repo}->{$ref}}) {
		system("GIT_DIR=$lrepo git-update-ref $config{$repo}->{$ref}->{$lrepo} $sha");
	}
}
close (F);

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* [PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-07-28  5:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, alp

This patch enables fetching multiple repositories at once over the Git
protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
there). This is done especially for the xorg people who have tons of
repositories and dislike pulls much slower than they were used to with CVS.
I'm eager to hear how this affects the situation.

It's kind of "superproject" thing, basically, taking reverse approach than
the subproject ideas. However, in practice I think it can be used for
subprojects quite well and perhaps if I find some spare time during the day
I will add the lightweight subproject support to Cogito, using this.

So, you need some kind of porcelain for this. The idea is that instead of
telling git-fetch-pack a single repository, you pass multiple --repo=
parameters and refs always "belong" to the latest mentioned repository;
when outputting the new ref values, the appropriate repo is mentioned near
each ref. In order for this to be useful, on your local side you should
share the objects database in some way - either using alternates (then
you must fetch to an object database reachable from everywhere) or symlinked
object databases.

You still need to pass git-fetch-pack some URL in addition to the
repositories - it is used only for git_connect(), the purpose is that
repositories must be local directories so if you want to talk remote, you
need to do something like

	git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master

The implementation is, well... rather hackish to say the least. :-)
We can do something nicer if it turns out to be a boost huge enough
in reality too.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 cache.h       |    7 ++++--
 connect.c     |   11 ++++++---
 daemon.c      |    9 +++++---
 fetch-pack.c  |   58 +++++++++++++++++++++++++++++++++----------------
 path.c        |    5 ++++
 peek-remote.c |    4 ++-
 send-pack.c   |    4 ++-
 sha1_file.c   |    6 +++--
 upload-pack.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 9 files changed, 127 insertions(+), 45 deletions(-)

diff --git a/cache.h b/cache.h
index 457d1d0..ea2f5e8 100644
--- a/cache.h
+++ b/cache.h
@@ -225,6 +225,7 @@ int git_config_perm(const char *var, con
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 char *enter_repo(char *path, int strict);
+int security_repo_check(int export_all_trees);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, char *, unsigned long *);
@@ -298,6 +299,7 @@ extern struct alternate_object_database 
 	char base[FLEX_ARRAY]; /* more */
 } *alt_odb_list;
 extern void prepare_alt_odb(void);
+extern int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self);
 
 extern struct packed_git {
 	struct packed_git *next;
@@ -325,6 +327,7 @@ struct ref {
 	unsigned char new_sha1[20];
 	unsigned char force;
 	struct ref *peer_ref; /* when renaming */
+	char *repo; /* when doing multi-repo operations */
 	char name[FLEX_ARRAY]; /* more */
 };
 
@@ -334,11 +337,11 @@ #define REF_TAGS	(1u << 2)
 
 extern int git_connect(int fd[2], char *url, const char *prog);
 extern int finish_connect(pid_t pid);
-extern int path_match(const char *path, int nr, char **match);
+extern int path_match(const char *path, const char *repo, int nr, char **match, char **match_repo);
 extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
 		      int nr_refspec, char **refspec, int all);
 extern int get_ack(int fd, unsigned char *result_sha1);
-extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
+extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, char *repo, unsigned int flags);
 extern int server_supports(const char *feature);
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1);
diff --git a/connect.c b/connect.c
index 4422a0d..63f095c 100644
--- a/connect.c
+++ b/connect.c
@@ -45,9 +45,8 @@ static int check_ref(const char *name, i
  */
 struct ref **get_remote_heads(int in, struct ref **list,
 			      int nr_match, char **match,
-			      unsigned int flags)
+			      char *repo, unsigned int flags)
 {
-	*list = NULL;
 	for (;;) {
 		struct ref *ref;
 		unsigned char old_sha1[20];
@@ -74,11 +73,12 @@ struct ref **get_remote_heads(int in, st
 
 		if (!check_ref(name, name_len, flags))
 			continue;
-		if (nr_match && !path_match(name, nr_match, match))
+		if (nr_match && !path_match(name, NULL, nr_match, match, NULL))
 			continue;
 		ref = xcalloc(1, sizeof(*ref) + len - 40);
 		memcpy(ref->old_sha1, old_sha1, 20);
 		memcpy(ref->name, buffer + 41, len - 40);
+		ref->repo = repo;
 		*list = ref;
 		list = &ref->next;
 	}
@@ -112,7 +112,8 @@ int get_ack(int fd, unsigned char *resul
 	die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
 }
 
-int path_match(const char *path, int nr, char **match)
+int path_match(const char *path, const char *repo, int nr, char **match,
+               char **match_repo)
 {
 	int i;
 	int pathlen = strlen(path);
@@ -121,6 +122,8 @@ int path_match(const char *path, int nr,
 		char *s = match[i];
 		int len = strlen(s);
 
+		if (match_repo && repo != match_repo[i])
+			continue;
 		if (!len || len > pathlen)
 			continue;
 		if (memcmp(path + pathlen - len, s, len))
diff --git a/daemon.c b/daemon.c
index e4ec676..179f2fe 100644
--- a/daemon.c
+++ b/daemon.c
@@ -233,6 +233,7 @@ static int upload(char *dir)
 {
 	/* Timeout as string */
 	char timeout_buf[64];
+	char checkexport_buf[64];
 	const char *path;
 
 	loginfo("Request for '%s'", dir);
@@ -250,8 +251,7 @@ static int upload(char *dir)
 	 * path_ok() uses enter_repo() and does whitelist checking.
 	 * We only need to make sure the repository is exported.
 	 */
-
-	if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
+	if (!security_repo_check(export_all_trees)) {
 		logerror("'%s': repository not exported.", path);
 		errno = EACCES;
 		return -1;
@@ -265,8 +265,11 @@ static int upload(char *dir)
 
 	snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
 
+	strcpy(checkexport_buf, "--check-export");
+	if (export_all_trees) checkexport_buf[1] = '\0'; /* XXX */
+
 	/* git-upload-pack only ever reads stuff, so this is safe */
-	execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
+	execl_git_cmd("upload-pack", "--strict", timeout_buf, checkexport_buf, ".", NULL);
 	return -1;
 }
 
diff --git a/fetch-pack.c b/fetch-pack.c
index b7824db..2b02d0f 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -281,7 +281,8 @@ static void mark_recent_complete_commits
 	}
 }
 
-static void filter_refs(struct ref **refs, int nr_match, char **match)
+static void filter_refs(struct ref **refs, int nr_match, char **match,
+                        char **match_repo)
 {
 	struct ref **return_refs;
 	struct ref *newlist = NULL;
@@ -312,7 +313,7 @@ static void filter_refs(struct ref **ref
 			continue;
 		}
 		else {
-			int order = path_match(ref->name, nr_match, match);
+			int order = path_match(ref->name, ref->repo, nr_match, match, match_repo);
 			if (order) {
 				return_refs[order-1] = ref;
 				continue; /* we will link it later */
@@ -337,7 +338,8 @@ static void filter_refs(struct ref **ref
 	*refs = newlist;
 }
 
-static int everything_local(struct ref **refs, int nr_match, char **match)
+static int everything_local(struct ref **refs, int nr_match, char **match,
+                            char **match_repo)
 {
 	struct ref *ref;
 	int retval;
@@ -386,7 +388,7 @@ static int everything_local(struct ref *
 		}
 	}
 
-	filter_refs(refs, nr_match, match);
+	filter_refs(refs, nr_match, match, match_repo);
 
 	for (retval = 1, ref = *refs; ref ; ref = ref->next) {
 		const unsigned char *remote = ref->old_sha1;
@@ -414,13 +416,15 @@ static int everything_local(struct ref *
 	return retval;
 }
 
-static int fetch_pack(int fd[2], int nr_match, char **match)
+static int fetch_pack(int fd[2], int nr_repo, char **repo,
+                      int nr_match, char **match, char **match_repo)
 {
-	struct ref *ref;
+	struct ref *ref = NULL, **refn;
 	unsigned char sha1[20];
 	int status;
+	int i;
 
-	get_remote_heads(fd[0], &ref, 0, NULL, 0);
+	refn = get_remote_heads(fd[0], &ref, 0, NULL, nr_repo ? repo[0] : NULL, 0);
 	if (server_supports("multi_ack")) {
 		if (verbose)
 			fprintf(stderr, "Server supports multi_ack\n");
@@ -431,11 +435,19 @@ static int fetch_pack(int fd[2], int nr_
 			fprintf(stderr, "Server supports side-band\n");
 		use_sideband = 1;
 	}
+	if (!server_supports("switch-repo") && nr_repo > 1)
+		die("server does not support fetching multiple repositories at once");
+
+	for (i = 1; i < nr_repo; i++) {
+		packet_write(fd[1], "switch-repo %s", repo[i]);
+		refn = get_remote_heads(fd[0], refn, 0, NULL, repo[i], 0);
+	}
+
 	if (!ref) {
 		packet_flush(fd[1]);
 		die("no matching remote head");
 	}
-	if (everything_local(&ref, nr_match, match)) {
+	if (everything_local(&ref, nr_match, match, match_repo)) {
 		packet_flush(fd[1]);
 		goto all_done;
 	}
@@ -456,8 +468,9 @@ static int fetch_pack(int fd[2], int nr_
 
  all_done:
 	while (ref) {
-		printf("%s %s\n",
-		       sha1_to_hex(ref->old_sha1), ref->name);
+		printf("%s %s%s%s\n",
+		       sha1_to_hex(ref->old_sha1), ref->name,
+		       ref->repo ? " " : "", ref->repo ? : "");
 		ref = ref->next;
 	}
 	return 0;
@@ -465,15 +478,16 @@ static int fetch_pack(int fd[2], int nr_
 
 int main(int argc, char **argv)
 {
-	int i, ret, nr_heads;
-	char *dest = NULL, **heads;
+	int i, ret, nr_repo = 0, nr_heads = 0;
+	char *dest = NULL;
+	char **repo = xmalloc(argc * sizeof(*repo));
+	char **heads = xmalloc(argc * sizeof(*heads));
+	char **heads_repo = xmalloc(argc * sizeof(*heads_repo));
 	int fd[2];
 	pid_t pid;
 
 	setup_git_directory();
 
-	nr_heads = 0;
-	heads = NULL;
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
 
@@ -498,16 +512,22 @@ int main(int argc, char **argv)
 				fetch_all = 1;
 				continue;
 			}
+			if (!strncmp("--repo=", arg, 7)) {
+				repo[nr_repo++] = arg + 7;
+				continue;
+			}
 			if (!strcmp("-v", arg)) {
 				verbose = 1;
 				continue;
 			}
 			usage(fetch_pack_usage);
 		}
-		dest = arg;
-		heads = argv + i + 1;
-		nr_heads = argc - i - 1;
-		break;
+		if (!dest) {
+			dest = arg;
+			continue;
+		}
+		heads_repo[nr_heads] = nr_repo ? repo[nr_repo - 1] : NULL;
+		heads[nr_heads++] = arg;
 	}
 	if (!dest)
 		usage(fetch_pack_usage);
@@ -516,7 +536,7 @@ int main(int argc, char **argv)
 	pid = git_connect(fd, dest, exec);
 	if (pid < 0)
 		return 1;
-	ret = fetch_pack(fd, nr_heads, heads);
+	ret = fetch_pack(fd, nr_repo, repo, nr_heads, heads, heads_repo);
 	close(fd[0]);
 	close(fd[1]);
 	finish_connect(pid);
diff --git a/path.c b/path.c
index db8905f..3021164 100644
--- a/path.c
+++ b/path.c
@@ -243,6 +243,11 @@ char *enter_repo(char *path, int strict)
 	return NULL;
 }
 
+int security_repo_check(int export_all_trees)
+{
+	return (export_all_trees || access("git-daemon-export-ok", F_OK));
+}
+
 int adjust_shared_perm(const char *path)
 {
 	struct stat st;
diff --git a/peek-remote.c b/peek-remote.c
index 2b30980..7d8ae3c 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -9,9 +9,9 @@ static const char *exec = "git-upload-pa
 
 static int peek_remote(int fd[2], unsigned flags)
 {
-	struct ref *ref;
+	struct ref *ref = NULL;
 
-	get_remote_heads(fd[0], &ref, 0, NULL, flags);
+	get_remote_heads(fd[0], &ref, 0, NULL, NULL, flags);
 	packet_flush(fd[1]);
 
 	while (ref) {
diff --git a/send-pack.c b/send-pack.c
index 10bc8bc..24c47c9 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -232,14 +232,14 @@ static int receive_status(int in)
 
 static int send_pack(int in, int out, int nr_refspec, char **refspec)
 {
-	struct ref *ref;
+	struct ref *ref = NULL;
 	int new_refs;
 	int ret = 0;
 	int ask_for_status_report = 0;
 	int expect_status_report = 0;
 
 	/* No funny business with the matcher */
-	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
+	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, NULL, REF_NORMAL);
 	get_local_heads();
 
 	/* Does the other end support the reporting? */
diff --git a/sha1_file.c b/sha1_file.c
index 8f279d8..1ca39e1 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -229,7 +229,7 @@ static void read_info_alternates(const c
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
+int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self)
 {
 	struct stat st;
 	const char *objdir = get_object_directory();
@@ -279,7 +279,7 @@ static int link_alt_odb_entry(const char
 			return -1;
 		}
 	}
-	if (!memcmp(ent->base, objdir, pfxlen)) {
+	if (!allow_self && !memcmp(ent->base, objdir, pfxlen)) {
 		free(ent);
 		return -1;
 	}
@@ -325,7 +325,7 @@ static void link_alt_odb_entries(const c
 						relative_base, last);
 			} else {
 				link_alt_odb_entry(last, cp - last,
-						relative_base, depth);
+						relative_base, depth, 0);
 			}
 		}
 		while (cp < ep && *cp == sep)
diff --git a/upload-pack.c b/upload-pack.c
index bbd6bd6..3440978 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -9,7 +9,7 @@ #include "object.h"
 #include "commit.h"
 #include "exec_cmd.h"
 
-static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
+static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] [--check-export] <dir>";
 
 #define THEY_HAVE (1U << 0)
 #define OUR_REF (1U << 1)
@@ -20,6 +20,8 @@ static struct object_array have_obj;
 static struct object_array want_obj;
 static unsigned int timeout = 0;
 static int use_sideband = 0;
+static int check_export = 0;
+static int strict = 0;
 
 static void reset_timeout(void)
 {
@@ -392,7 +394,7 @@ static int get_common_commits(void)
 	}
 }
 
-static void receive_needs(void)
+static char *receive_needs(void)
 {
 	static char line[1000];
 	int len;
@@ -403,8 +405,10 @@ static void receive_needs(void)
 		len = packet_read_line(0, line, sizeof(line));
 		reset_timeout();
 		if (!len)
-			return;
+			return NULL;
 
+		if (!strncmp("switch-repo ", line, 12))
+			return line+12;
 		if (strncmp("want ", line, 5) ||
 		    get_sha1_hex(line+5, sha1_buf))
 			die("git-upload-pack: protocol error, "
@@ -436,7 +440,7 @@ static void receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
-	static const char *capabilities = "multi_ack thin-pack side-band";
+	static const char *capabilities = "multi_ack thin-pack side-band switch-repo";
 	struct object *o = parse_object(sha1);
 
 	if (!o)
@@ -461,11 +465,52 @@ static int send_ref(const char *refname,
 
 static int upload_pack(void)
 {
-	reset_timeout();
-	head_ref(send_ref);
-	for_each_ref(send_ref);
-	packet_flush(1);
-	receive_needs();
+	int multirepo = 0;
+
+	while (1) {
+		char *repo;
+		char cwd[PATH_MAX];
+
+		reset_timeout();
+		head_ref(send_ref);
+		for_each_ref(send_ref);
+		packet_flush(1);
+		repo = receive_needs();
+		if (!repo)
+			break;
+		multirepo++;
+
+		fprintf(stderr, "git-upload-pack: switching to repo %s", repo);
+
+		/* So that we still find objects of the original repository... */
+		getcwd(cwd, PATH_MAX);
+		if (strlen(cwd) < PATH_MAX - 8)
+			strcat(cwd, "/objects");
+		link_alt_odb_entry(cwd, strlen(cwd), NULL, 0, 1);
+
+		if (!enter_repo(repo, strict) || !security_repo_check(!check_export))
+			die("git-upload-pack: security violation");
+	}
+
+	if (multirepo) {
+#define ALTENV_SIZE 65536
+		/* Propagate all the repositories to the children */
+		char altenv[ALTENV_SIZE], *p = altenv;
+		struct alternate_object_database *alt;
+		strcpy(p, ALTERNATE_DB_ENVIRONMENT "=");
+		p += sizeof(ALTERNATE_DB_ENVIRONMENT);
+		for (alt = alt_odb_list; alt; alt = alt->next) {
+			strncpy(p, alt->base, alt->name - alt->base);
+			p += alt->name - alt->base;
+			if (p - altenv < ALTENV_SIZE)
+				*p++ = ':';
+			if (p - altenv >= ALTENV_SIZE)
+				die("fetching too many repositories");
+		}
+		p[-1] = '\0';
+		putenv(altenv);
+	}
+
 	if (!want_obj.nr)
 		return 0;
 	get_common_commits();
@@ -477,7 +522,6 @@ int main(int argc, char **argv)
 {
 	char *dir;
 	int i;
-	int strict = 0;
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
@@ -492,6 +536,10 @@ int main(int argc, char **argv)
 			timeout = atoi(arg+10);
 			continue;
 		}
+		if (!strcmp(arg, "--check-export")) {
+			check_export = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--")) {
 			i++;
 			break;

^ permalink raw reply related

* Re: Licensing and the library version of git
From: Shawn Pearce @ 2006-07-28  5:04 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: Jon Smirl, git
In-Reply-To: <20060727195614.7EDAE353B04@atlas.denx.de>

Wolfgang Denk <wd@denx.de> wrote:
> In message <9e4733910607270554p5622ee20ida8c264cf3122500@mail.gmail.com> you wrote:
> >
> > I see that someone is already writing a pure Java version which will
> > work around the GPL problem assuming the Java version is released
> > under a compatible license.
> 
> ... and assuming it is a clean-room  implementation  which  does  not
> borrow from the GPL code.

Heh.  This is actually possibly a problem.

I'm the person developing the Java implementation.

I've seen some of the core GIT code.  The reflog implementation is my
most notable contribution, but I've seen other things in there too.

Most of the Java code is quite different from the C code; the
largest common component is the pack delta decompressor.  I ran it
past Nico as he wrote the C version. He didn't seem to think that
the Java version was derived from the C version.

The issue there really was that the pack file format wasn't
completely documented external from the code (I actually found a
bug in the docs and submitted a patch to correct it) and the delta
format is definately not documented so I had to dig around in the
C code to figure it out.  On the other hand the commit format,
tree format and the loose object header were all clearly self
describing so I didn't need to go digging through the source to
figure out how to parse (or generate) them.

So yes, the Java implementation is derived from the C
(GPL'd!) implementation, but also no, its not...

I think its going to really just come down to a list consensus.
If Linus, Junio, Nico, et.al. think that my Java version is too
derived from the C GPL'd implementation to be released under any
license other than the GPL then I'll probably just abandon the code
line entirely, as the GPL is incompatible with the Sun JRE runtime
lirbary.  On the other hand its probably going to be released under
the IBM Common Public License or the Apache License.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Junio C Hamano @ 2006-07-28  4:48 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060728025619.GK13776@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> Dear diary, on Fri, Jul 28, 2006 at 04:41:04AM CEST, I got a letter
> where Junio C Hamano <junkio@cox.net> said that...
>> Petr Baudis <pasky@suse.cz> writes:
>> >   (iv) I need git-apply to add/remove to/from index new/gone files,
>> > while at the same time...
>> >
>> >   (v) I want to allow applying of patches to working copy that is not
>> > completely clean, even on top of modified files
>> 
>> You probably should be able to talk me into doing these, but
>> doesn't it already do (iv) and (v)?
>
> Well, at once? I can do (iv) by adding --index but that contradicts (v).
> But maybe I'm missing something.

What should the semantics of such operation be?  Apply to index
on paths that are clean while leave the index entries untouched
for paths that are dirty?  What should happen on renamed paths
that are dirty?

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Petr Baudis @ 2006-07-28  2:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vvepimoxr.fsf@assigned-by-dhcp.cox.net>

Dear diary, on Fri, Jul 28, 2006 at 04:41:04AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@suse.cz> writes:
> >   (iv) I need git-apply to add/remove to/from index new/gone files,
> > while at the same time...
> >
> >   (v) I want to allow applying of patches to working copy that is not
> > completely clean, even on top of modified files
> 
> You probably should be able to talk me into doing these, but
> doesn't it already do (iv) and (v)?

Well, at once? I can do (iv) by adding --index but that contradicts (v).
But maybe I'm missing something.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Junio C Hamano @ 2006-07-28  2:41 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060728013038.GH13776@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

>   (i) No git-apply -R - well, it seems to me that I revert patches all
> the time, don't you?
>
>   (ii) I'd like git-apply to be as verbose as patch is, that is list
> the files it touches as it goes
>
>   (iii) There's no reject handling besides "panic" right now - it should
> be able to create .rej files so that the user can fix things up
>
>   (iv) I need git-apply to add/remove to/from index new/gone files,
> while at the same time...
>
>   (v) I want to allow applying of patches to working copy that is not
> completely clean, even on top of modified files

You probably should be able to talk me into doing these, but
doesn't it already do (iv) and (v)?

^ permalink raw reply

* Re: [PATCH 3/4] Teach git-local-fetch the --stdin switch
From: Petr Baudis @ 2006-07-28  1:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215619.24240.39537.stgit@machine>

Dear diary, on Thu, Jul 27, 2006 at 11:56:19PM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> +--stdin::
> +	Instead of a commit id on the commandline (which is not expected in this
> +	case), 'git-local-fetch' excepts lines on stdin in the format
                                 ^^^^^^^

Oops, should read "expects" in both patches - thanks, alp!

I blame all those tiny bugs lured into the room by light and then, well,
bugging you. (Real-world bugs, but they can transform.)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: Moving a directory into another fails
From: Petr Baudis @ 2006-07-28  1:43 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Nicolas Vilz, git
In-Reply-To: <9e4733910607261603m6772602cr333d8c58f555edaa@mail.gmail.com>

Dear diary, on Thu, Jul 27, 2006 at 01:03:30AM CEST, I got a letter
where Jon Smirl <jonsmirl@gmail.com> said that...
> This is a simpler sequence
> 
> cg clone git foo
> cg clone git foo1
> cd foo
> mkdir zzz
> git mv gitweb zzz
> cg diff >patch
> cg ../foo1
> cg patch <../foo/patch

Even simpler one:

	mkdir zzz
	cg-mv gitweb zzz
	cg-diff | cg-patch -R

(which would even undo the mess supposing that it worked properly)

> [jonsmirl@jonsmirl foo1]$ cg patch <../foo/patch
> mv: cannot move `gitweb/README' to `zzz/gitweb/README': No such file
> or directory

Oops. Thanks, fixed with this:

diff --git a/cg-patch b/cg-patch
index cc82f1f..923df0e 100755
--- a/cg-patch
+++ b/cg-patch
@@ -145,6 +145,8 @@ redzone_border()
 			echo "$file1: rename destination $file2 already exists, NOT RENAMING" >&2
 			return
 		fi
+		# FIXME: Remove stale empty directories related to $mvfrom
+		case $mvto in */*) mkdir -p "${mvto%/*}";; esac
 		mv "$mvfrom" "$mvto"
 	fi
 	if [ "$op" = "delete" -o "$op" = "rename" ]; then

> mv: cannot stat `"gitweb/test/M\\303\\244rchen"': No such file or directory

Junio, how am I supposed to unmangle this *censored* stuff?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply related

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Petr Baudis @ 2006-07-28  1:30 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Johannes Schindelin, Jon Smirl, git, junkio
In-Reply-To: <200607262039.25155.Josef.Weidendorfer@gmx.de>

Dear diary, on Wed, Jul 26, 2006 at 08:39:24PM CEST, I got a letter
where Josef Weidendorfer <Josef.Weidendorfer@gmx.de> said that...
> On Wednesday 26 July 2006 19:41, Johannes Schindelin wrote:
> > 
> > If dir2 already exists, git-mv should move dir1 _into_dir2/.
> > Noticed by Jon Smirl.
> 
> Thanks for adding this test.
> BTW, the original PERL script passes it quite fine.
> 
> I just looked at Jon's problem. Doesn't seem to be related to
> git-mv or git at all, but more a cogito problem.
> I have some cogito-0.18pre installed, and cg-patch is patching
> the stuff all itself, not using git for this. Pasky?

Unfortunately, git-apply is still quite unusable for Cogito. It can do
fuzzy merging now, but here's some random list of more issues I still
have with it (I'm leaving for some two weeks or so of holiday soon so I
won't have to fix them soon personally; it'd be nice if someone did,
though ;) :

  (i) No git-apply -R - well, it seems to me that I revert patches all
the time, don't you?

  (ii) I'd like git-apply to be as verbose as patch is, that is list
the files it touches as it goes

  (iii) There's no reject handling besides "panic" right now - it should
be able to create .rej files so that the user can fix things up

  (iv) I need git-apply to add/remove to/from index new/gone files,
while at the same time...

  (v) I want to allow applying of patches to working copy that is not
completely clean, even on top of modified files

But yes, I'd like cg-patch to move to use git-apply. It's currently
_way_ too scary.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: Licensing and the library version of git
From: Jon Smirl @ 2006-07-28  0:43 UTC (permalink / raw)
  To: Anand Kumria; +Cc: git
In-Reply-To: <eablgn$c6a$1@sea.gmane.org>

On 7/27/06, Anand Kumria <wildfire@progsoc.org> wrote:
> On Thu, 27 Jul 2006 12:11:00 -0400, Jon Smirl wrote:
>
> > On 7/27/06, Petr Baudis <pasky@suse.cz> wrote:
> >> > You may like trying to force GPL onto the app but many apps are
> >> > stuck with the license they have and can't be changed since there is
> >> > no way to contact the original developers.
> >>
> >> At this point, git-shortlog lists exactly 200 people (at least entries
> >> like Unknown or No name are all linux@horizon.com ;-).
> >
> > Inability to integrate with Microsoft Visual Studio is going to have a
> > lot of impact on the cross platform use of git.
>
> Could you stop with the histrionics please?

It is usually wise not to make comments like this, they don't help in
building the community.

> > Is a conscious
> > decision being made to stop this integration or is this just unplanned
> > side effect of the original license? If this is an unplanned side
> > effect, the quicker we move, the easier it is to fix.
>
> So, using CVSNT (a GPL'd SCCI provider) and git-cvsserver would be a way
> to continue.  I'm assuming that the primary functionality they want via
> their IDE is checkout/diff/commit/log.

Now, that's a great strategy. Tell the large project you are
interested in switching off from CVS to git that they need to run a
CVS emulation gateway forever. I don't think a switch has much of a
chance of happening.


> Quite a lot of Windows developers have no problems using multiple tools
> for things, I'd assume they would also be able to use any existent port
> of git (to Windows) to do the esoteric things like branching/bisect/etc.
>
> Anand
>
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: Licensing and the library version of git
From: Anand Kumria @ 2006-07-28  0:25 UTC (permalink / raw)
  To: git
In-Reply-To: <9e4733910607271047r57fe0aa3hf29b4b9244c02f2c@mail.gmail.com>

On Thu, 27 Jul 2006 13:47:24 -0400, Jon Smirl wrote:

> On 7/27/06, Linus Torvalds <torvalds@osdl.org> wrote:
>> I seriously doubt that Eclipse or Visual Stupido could ever actually
>> _understand_ what git does, so the only parts you actually would want to
>> use for those is literally the trivial stuff - the "look up objects" and
>> "generate commits" part.
> 
> Typically an integrated IDE can move, delete, rename directories and
> files. Get a log. Push, pull and commit. Revert a change. Generate
> diffs to previous versions.

Kind of what you can do via CVSNT and git-cvsserver, no?

Anand

^ permalink raw reply

* Re: Licensing and the library version of git
From: Anand Kumria @ 2006-07-28  0:24 UTC (permalink / raw)
  To: git
In-Reply-To: <9e4733910607270911p50d25d97w1a898fc7a9119e7d@mail.gmail.com>

On Thu, 27 Jul 2006 12:11:00 -0400, Jon Smirl wrote:

> On 7/27/06, Petr Baudis <pasky@suse.cz> wrote:
>> > You may like trying to force GPL onto the app but many apps are
>> > stuck with the license they have and can't be changed since there is
>> > no way to contact the original developers.
>>
>> At this point, git-shortlog lists exactly 200 people (at least entries
>> like Unknown or No name are all linux@horizon.com ;-).
> 
> Inability to integrate with Microsoft Visual Studio is going to have a
> lot of impact on the cross platform use of git.  

Could you stop with the histrionics please?

> Is a conscious
> decision being made to stop this integration or is this just unplanned
> side effect of the original license? If this is an unplanned side
> effect, the quicker we move, the easier it is to fix.

So, using CVSNT (a GPL'd SCCI provider) and git-cvsserver would be a way
to continue.  I'm assuming that the primary functionality they want via
their IDE is checkout/diff/commit/log.

Quite a lot of Windows developers have no problems using multiple tools
for things, I'd assume they would also be able to use any existent port
of git (to Windows) to do the esoteric things like branching/bisect/etc.

Anand

^ permalink raw reply

* Re: [PATCH 0/4] Fetching mass of objects at once
From: Petr Baudis @ 2006-07-27 21:57 UTC (permalink / raw)
  To: git; +Cc: jonsmirl
In-Reply-To: <20060727215326.24240.20118.stgit@machine>

Dear diary, on Thu, Jul 27, 2006 at 11:53:26PM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
>   I will followup with a patch for Cogito to take advantage of this. It's
> now roughly on par with Git in cloning speed.

diff --git a/cg-Xfetchprogress b/cg-Xfetchprogress
index 53bcbd3..4a272db 100755
--- a/cg-Xfetchprogress
+++ b/cg-Xfetchprogress
@@ -67,7 +67,7 @@ sub getline {
 	if (m#^(link|symlink|copy|got) ([a-f0-9]{2})([a-f0-9]{38})#) {
 		$object = "$2/$3";
 
-	} elsif (m#^(walk) ([a-f0-9]{2})([a-f0-9]{38})#) {
+	} elsif (m#^(ref|walk) ([a-f0-9]{2})([a-f0-9]{38})#) {
 		return 1; # redundant information
 
 	# rsync
diff --git a/cg-fetch b/cg-fetch
index a6e6959..9277f99 100755
--- a/cg-fetch
+++ b/cg-fetch
@@ -124,16 +124,10 @@ get_rsync()
 	return ${PIPESTATUS[0]}
 }
 
-fetch_rsync()
+fetch_rsync_save()
 {
-	if [ $verbose -ge 2 ]; then
-		# We must not pipe to prevent buffered I/O
-		get_rsync -s -d "$2/objects" "$_git_objects"
-	else
-		get_rsync -s -d "$2/objects" "$_git_objects" | fetch_progress
-	fi
 	ret=${PIPESTATUS[0]}
-	if [ "$3" ] && [ "$ret" -eq "0" ]; then
+	if [ "$1" ] && [ "$ret" -eq "0" ]; then
 		if [ "$orig_head" ]; then
 			git-rev-list --objects $new_head ^$orig_head |
 				while read obj type; do
@@ -141,12 +135,29 @@ fetch_rsync()
 				done ||
 			die "rsync fetch incomplete, some objects missing"
 		fi
-		cat "$_git/refs/${3%/*}/.${3##*/}-fetching" > "$_git/refs/$3"
+		cat "$_git/refs/${3%/*}/.${3##*/}-fetching" > "$_git/refs/$1"
 	fi
 	return $ret
 }
 
 
+fetch_rsync()
+{
+	if [ $verbose -ge 2 ]; then
+		# We must not pipe to prevent buffered I/O
+		get_rsync -s -d "$2/objects" "$_git_objects"
+	else
+		get_rsync -s -d "$2/objects" "$_git_objects" | fetch_progress
+	fi
+	if [ x"$1" = x"--stdin" ]; then
+		while read c w; do
+			echo "$c" >"$_git/refs/$w"
+		done
+	else
+		fetch_rsync_save "$3"
+	fi
+}
+
 get_http()
 {
 	[ "$1" = "-b" ] && shift
@@ -229,21 +240,13 @@ fetch_tags()
 
 			# if so, fetch the tag -- which should be
 			# a cheap operation -- to complete the chain.
-			echo -n "Missing tag ${tagname#tags/}... "
-			if $fetch "$tagname" "$uri" "$tagname" 2>/dev/null >&2; then
-				echo "retrieved"
-			else
-				# 17 is code from packed transport, which
-				# will grab all of them en masse later
-				if [ "$?" -ne "17" ]; then
-					echo "unable to retrieve"
-				else
-					echo ""
-				fi
-			fi
-		done
-	[ "${PIPESTATUS[0]}" -eq "0" ] ||
-		echo "unable to get tags list (non-fatal)" >&2
+			echo "Missing tag ${tagname#tags/}..." >&2
+			echo -e "$tagname"\\t"$tagname"
+		done |
+		sort | uniq | $fetch --stdin "$uri"
+	if [ "${PIPESTATUS[0]}" -ne 0 -o "$?" -ne 0 ]; then
+		echo "unable to fetch tags (non-fatal)" >&2
+	fi
 	return 0
 }
 
@@ -364,21 +367,15 @@ if [ "$packed_transport" ]; then
 		fetch_pack_recorder "refs/heads/$name" "fetching pack failed" ||
 		exit
 
-	export _cg_taglist="$(mktemp -t gitfetch.XXXXXX)"
 	record_tags_to_fetch () {
-		echo "refs/$1" >>"$_cg_taglist"
-		return 17
-	}
-	fetch=record_tags_to_fetch
-	fetch_tags
-	if [ -s "$_cg_taglist" ]; then
-		( cat "$_cg_taglist" | tr '\n' '\0' |
+		( cut -f 1 | tr '\n' '\0' |
 			xargs -0 git-fetch-pack $cloneorfetch "$uri" ||
 		  echo "failed" "$rembranch" ) |
 
 		fetch_pack_recorder "" "unable to retrieve tags (non-fatal)"
-	fi
-	rm "$_cg_taglist"
+	}
+	fetch=record_tags_to_fetch
+	fetch_tags
 
 	rm "$dirtyfile"
 	show_changes_summary "$orig_head" "$(cg-object-id "$name")"

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply related

* [PATCH 4/4] Teach git-http-fetch the --stdin switch
From: Petr Baudis @ 2006-07-27 21:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215326.24240.20118.stgit@machine>

Speeds up things quite a lot when fetching tags with Cogito.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Documentation/git-http-fetch.txt |    8 ++++++-
 http-fetch.c                     |   45 ++++++++++++++++++++++++--------------
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt
index bc1a132..bea522e 100644
--- a/Documentation/git-http-fetch.txt
+++ b/Documentation/git-http-fetch.txt
@@ -8,7 +8,7 @@ git-http-fetch - downloads a remote git 
 
 SYNOPSIS
 --------
-'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] <commit> <url>
+'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>
 
 DESCRIPTION
 -----------
@@ -32,6 +32,12 @@ commit-id::
 -w <filename>::
         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
         the local end after the transfer is complete.
+ 
+--stdin::
+	Instead of a commit id on the commandline (which is not expected in this
+	case), 'git-http-fetch' excepts lines on stdin in the format
+
+		<commit-id>['\t'<filename-as-in--w>]
 
 Author
 ------
diff --git a/http-fetch.c b/http-fetch.c
index bc67db1..1aad39b 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -36,6 +36,8 @@ #endif
 #define PREV_BUF_SIZE 4096
 #define RANGE_HEADER_SIZE 30
 
+static int commits_on_stdin = 0;
+
 static int got_alternates = -1;
 static int corrupt_object_found = 0;
 
@@ -43,7 +45,7 @@ static struct curl_slist *no_pragma_head
 
 struct alt_base
 {
-	char *base;
+	const char *base;
 	int path_len;
 	int got_indices;
 	struct packed_git *packs;
@@ -81,7 +83,7 @@ struct object_request
 };
 
 struct alternates_request {
-	char *base;
+	const char *base;
 	char *url;
 	struct buffer *buffer;
 	struct active_request_slot *slot;
@@ -142,7 +144,7 @@ static size_t fwrite_sha1_file(void *ptr
 	return size;
 }
 
-static void fetch_alternates(char *base);
+static void fetch_alternates(const char *base);
 
 static void process_object_response(void *callback_data);
 
@@ -507,7 +509,7 @@ static void process_alternates_response(
 		(struct alternates_request *)callback_data;
 	struct active_request_slot *slot = alt_req->slot;
 	struct alt_base *tail = alt;
-	char *base = alt_req->base;
+	const char *base = alt_req->base;
 	static const char null_byte = '\0';
 	char *data;
 	int i = 0;
@@ -612,7 +614,7 @@ static void process_alternates_response(
 	got_alternates = 1;
 }
 
-static void fetch_alternates(char *base)
+static void fetch_alternates(const char *base)
 {
 	struct buffer buffer;
 	char *url;
@@ -1185,7 +1187,7 @@ int fetch_ref(char *ref, unsigned char *
         char *url;
         char hex[42];
         struct buffer buffer;
-	char *base = alt->base;
+	const char *base = alt->base;
 	struct active_request_slot *slot;
 	struct slot_results results;
         buffer.size = 41;
@@ -1214,11 +1216,12 @@ int fetch_ref(char *ref, unsigned char *
         return 0;
 }
 
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
 {
-	const char *write_ref = NULL;
-	char *commit_id;
-	char *url;
+	int commits;
+	const char **write_ref = NULL;
+	char **commit_id;
+	const char *url;
 	char *path;
 	int arg = 1;
 	int rc = 0;
@@ -1238,19 +1241,26 @@ int main(int argc, char **argv)
 		} else if (argv[arg][1] == 'v') {
 			get_verbosely = 1;
 		} else if (argv[arg][1] == 'w') {
-			write_ref = argv[arg + 1];
+			write_ref = &argv[arg + 1];
 			arg++;
 		} else if (!strcmp(argv[arg], "--recover")) {
 			get_recover = 1;
+		} else if (!strcmp(argv[arg], "--stdin")) {
+			commits_on_stdin = 1;
 		}
 		arg++;
 	}
-	if (argc < arg + 2) {
-		usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url");
+	if (argc < arg + 2 - commits_on_stdin) {
+		usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url");
 		return 1;
 	}
-	commit_id = argv[arg];
-	url = argv[arg + 1];
+	if (commits_on_stdin) {
+		commits = pull_targets_stdin(&commit_id, &write_ref);
+	} else {
+		commit_id = (char **) &argv[arg++];
+		commits = 1;
+	}
+	url = argv[arg];
 
 	http_init();
 
@@ -1268,13 +1278,16 @@ int main(int argc, char **argv)
 			alt->path_len = strlen(path);
 	}
 
-	if (pull(1, &commit_id, &write_ref, url))
+	if (pull(commits, commit_id, write_ref, url))
 		rc = 1;
 
 	http_cleanup();
 
 	curl_slist_free_all(no_pragma_header);
 
+	if (commits_on_stdin)
+		pull_targets_free(commits, commit_id, write_ref);
+
 	if (corrupt_object_found) {
 		fprintf(stderr,
 "Some loose object were found to be corrupt, but they might be just\n"

^ permalink raw reply related

* [PATCH 3/4] Teach git-local-fetch the --stdin switch
From: Petr Baudis @ 2006-07-27 21:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215326.24240.20118.stgit@machine>

This makes it possible to fetch many commits (refs) at once, greatly
speeding up cg-clone.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Documentation/git-local-fetch.txt |    6 ++++++
 fetch.c                           |   40 +++++++++++++++++++++++++++++++++++++
 fetch.h                           |    6 ++++++
 local-fetch.c                     |   32 ++++++++++++++++++++----------
 4 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt
index 87abec1..bd19820 100644
--- a/Documentation/git-local-fetch.txt
+++ b/Documentation/git-local-fetch.txt
@@ -29,6 +29,12 @@ OPTIONS
         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
         the local end after the transfer is complete.
 
+--stdin::
+	Instead of a commit id on the commandline (which is not expected in this
+	case), 'git-local-fetch' excepts lines on stdin in the format
+
+		<commit-id>['\t'<filename-as-in--w>]
+
 Author
 ------
 Written by Junio C Hamano <junkio@cox.net>
diff --git a/fetch.c b/fetch.c
index 281df61..2151c7b 100644
--- a/fetch.c
+++ b/fetch.c
@@ -7,6 +7,7 @@ #include "tree-walk.h"
 #include "tag.h"
 #include "blob.h"
 #include "refs.h"
+#include "strbuf.h"
 
 int get_tree = 0;
 int get_history = 0;
@@ -210,6 +211,45 @@ static int mark_complete(const char *pat
 	return 0;
 }
 
+int pull_targets_stdin(char ***target, const char ***write_ref)
+{
+	int targets = 0, targets_alloc = 0;
+	struct strbuf buf;
+	*target = NULL; *write_ref = NULL;
+	strbuf_init(&buf);
+	while (1) {
+		char *rf_one = NULL;
+		char *tg_one;
+
+		read_line(&buf, stdin, '\n');
+		if (buf.eof)
+			break;
+		tg_one = buf.buf;
+		rf_one = strchr(tg_one, '\t');
+		if (rf_one)
+			*rf_one++ = 0;
+
+		if (targets >= targets_alloc) {
+			targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
+			*target = xrealloc(*target, targets_alloc * sizeof(**target));
+			*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
+		}
+		(*target)[targets] = strdup(tg_one);
+		(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;
+		targets++;
+	}
+	return targets;
+}
+
+void pull_targets_free(int targets, char **target, const char **write_ref)
+{
+	while (targets--) {
+		free(target[targets]);
+		if (write_ref[targets])
+			free((char *) write_ref[targets]);
+	}
+}
+
 int pull(int targets, char **target, const char **write_ref,
          const char *write_ref_log_details)
 {
diff --git a/fetch.h b/fetch.h
index 75e48af..be48c6f 100644
--- a/fetch.h
+++ b/fetch.h
@@ -40,6 +40,12 @@ extern int get_recover;
 /* Report what we got under get_verbosely */
 extern void pull_say(const char *, const char *);
 
+/* Load pull targets from stdin */
+extern int pull_targets_stdin(char ***target, const char ***write_ref);
+
+/* Free up loaded targets */
+extern void pull_targets_free(int targets, char **target, const char **write_ref);
+
 /* If write_ref is set, the ref filename to write the target value to. */
 /* If write_ref_log_details is set, additional text will appear in the ref log. */
 extern int pull(int targets, char **target, const char **write_ref,
diff --git a/local-fetch.c b/local-fetch.c
index eb19f1a..84b68a6 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -8,8 +8,9 @@ #include "fetch.h"
 static int use_link = 0;
 static int use_symlink = 0;
 static int use_filecopy = 1;
+static int commits_on_stdin = 0;
 
-static char *path; /* "Remote" git repository */
+static const char *path; /* "Remote" git repository */
 
 void prefetch(unsigned char *sha1)
 {
@@ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *
 }
 
 static const char local_pull_usage[] =
-"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path";
+"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path";
 
 /* 
  * By default we only use file copy.
@@ -202,10 +203,11 @@ static const char local_pull_usage[] =
  * 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)
+int main(int argc, const char **argv)
 {
-	const char *write_ref = NULL;
-	char *commit_id;
+	int commits;
+	const char **write_ref = NULL;
+	char **commit_id;
 	int arg = 1;
 
 	setup_git_directory();
@@ -230,20 +232,30 @@ int main(int argc, char **argv)
 		else if (argv[arg][1] == 'v')
 			get_verbosely = 1;
 		else if (argv[arg][1] == 'w')
-			write_ref = argv[++arg];
+			write_ref = &argv[++arg];
 		else if (!strcmp(argv[arg], "--recover"))
 			get_recover = 1;
+		else if (!strcmp(argv[arg], "--stdin"))
+			commits_on_stdin = 1;
 		else
 			usage(local_pull_usage);
 		arg++;
 	}
-	if (argc < arg + 2)
+	if (argc < arg + 2 - commits_on_stdin)
 		usage(local_pull_usage);
-	commit_id = argv[arg];
-	path = argv[arg + 1];
+	if (commits_on_stdin) {
+		commits = pull_targets_stdin(&commit_id, &write_ref);
+	} else {
+		commit_id = (char **) &argv[arg++];
+		commits = 1;
+	}
+	path = argv[arg];
 
-	if (pull(1, &commit_id, &write_ref, path))
+	if (pull(commits, commit_id, write_ref, path))
 		return 1;
 
+	if (commits_on_stdin)
+		pull_targets_free(commits, commit_id, write_ref);
+
 	return 0;
 }

^ permalink raw reply related

* [PATCH 2/4] Make pull() support fetching multiple targets at once
From: Petr Baudis @ 2006-07-27 21:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215326.24240.20118.stgit@machine>

pull() now takes an array of arguments instead of just one of each kind.
Currently, no users use the new capability, but that'll change.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 fetch.c       |   78 +++++++++++++++++++++++++++++++++------------------------
 fetch.h       |    2 +
 http-fetch.c  |    2 +
 local-fetch.c |    2 +
 ssh-fetch.c   |    2 +
 5 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/fetch.c b/fetch.c
index 3255cc6..281df61 100644
--- a/fetch.c
+++ b/fetch.c
@@ -210,55 +210,67 @@ static int mark_complete(const char *pat
 	return 0;
 }
 
-int pull(char *target, const char *write_ref,
+int pull(int targets, char **target, const char **write_ref,
          const char *write_ref_log_details)
 {
-	struct ref_lock *lock = NULL;
-	unsigned char sha1[20];
+	struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));
+	unsigned char *sha1 = xmalloc(targets * 20);
 	char *msg;
 	int ret;
+	int i;
 
 	save_commit_buffer = 0;
 	track_object_refs = 0;
-	if (write_ref) {
-		lock = lock_ref_sha1(write_ref, NULL, 0);
-		if (!lock) {
-			error("Can't lock ref %s", write_ref);
-			return -1;
+
+	for (i = 0; i < targets; i++) {
+		if (!write_ref[i])
+			continue;
+
+		lock[i] = lock_ref_sha1(write_ref[i], NULL, 0);
+		if (!lock[i]) {
+			error("Can't lock ref %s", write_ref[i]);
+			goto unlock_and_fail;
 		}
 	}
 
 	if (!get_recover)
 		for_each_ref(mark_complete);
 
-	if (interpret_target(target, sha1)) {
-		error("Could not interpret %s as something to pull", target);
-		if (lock)
-			unlock_ref(lock);
-		return -1;
+	for (i = 0; i < targets; i++) {
+		if (interpret_target(target[i], &sha1[20 * i])) {
+			error("Could not interpret %s as something to pull", target[i]);
+			goto unlock_and_fail;
+		}
+		if (process(lookup_unknown_object(&sha1[20 * i])))
+			goto unlock_and_fail;
 	}
-	if (process(lookup_unknown_object(sha1))) {
-		if (lock)
-			unlock_ref(lock);
-		return -1;
+
+	if (loop())
+		goto unlock_and_fail;
+
+	if (write_ref_log_details) {
+		msg = xmalloc(strlen(write_ref_log_details) + 12);
+		sprintf(msg, "fetch from %s", write_ref_log_details);
+	} else {
+		msg = NULL;
 	}
-	if (loop()) {
-		if (lock)
-			unlock_ref(lock);
-		return -1;
+	for (i = 0; i < targets; i++) {
+		if (!write_ref[i])
+			continue;
+		ret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : "fetch (unknown)");
+		lock[i] = NULL;
+		if (ret)
+			goto unlock_and_fail;
 	}
+	if (msg)
+		free(msg);
 
-	if (write_ref) {
-		if (write_ref_log_details) {
-			msg = xmalloc(strlen(write_ref_log_details) + 12);
-			sprintf(msg, "fetch from %s", write_ref_log_details);
-		}
-		else
-			msg = NULL;
-		ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
-		if (msg)
-			free(msg);
-		return ret;
-	}
 	return 0;
+
+
+unlock_and_fail:
+	for (i = 0; i < targets; i++)
+		if (lock[i])
+			unlock_ref(lock[i]);
+	return -1;
 }
diff --git a/fetch.h b/fetch.h
index 7bda355..75e48af 100644
--- a/fetch.h
+++ b/fetch.h
@@ -42,7 +42,7 @@ extern void pull_say(const char *, const
 
 /* If write_ref is set, the ref filename to write the target value to. */
 /* If write_ref_log_details is set, additional text will appear in the ref log. */
-extern int pull(char *target, const char *write_ref,
+extern int pull(int targets, char **target, const char **write_ref,
 		const char *write_ref_log_details);
 
 #endif /* PULL_H */
diff --git a/http-fetch.c b/http-fetch.c
index 963d439..bc67db1 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -1268,7 +1268,7 @@ int main(int argc, char **argv)
 			alt->path_len = strlen(path);
 	}
 
-	if (pull(commit_id, write_ref, url))
+	if (pull(1, &commit_id, &write_ref, url))
 		rc = 1;
 
 	http_cleanup();
diff --git a/local-fetch.c b/local-fetch.c
index 308ed00..eb19f1a 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -242,7 +242,7 @@ int main(int argc, char **argv)
 	commit_id = argv[arg];
 	path = argv[arg + 1];
 
-	if (pull(commit_id, write_ref, path))
+	if (pull(1, &commit_id, &write_ref, path))
 		return 1;
 
 	return 0;
diff --git a/ssh-fetch.c b/ssh-fetch.c
index aef3aa4..6e16568 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -167,7 +167,7 @@ int main(int argc, char **argv)
 	if (get_version())
 		return 1;
 
-	if (pull(commit_id, write_ref, url))
+	if (pull(1, &commit_id, &write_ref, url))
 		return 1;
 
 	return 0;

^ permalink raw reply related

* [PATCH 1/4] Make pull() take some implicit data as explicit arguments
From: Petr Baudis @ 2006-07-27 21:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215326.24240.20118.stgit@machine>

Currently it's a bit weird that pull() takes a single argument
describing the commit but takes the write_ref from a global variable.
This makes it take that as a parameter as well, which might be nicer
for the libification in the future, but especially it will make for
nicer code when we implement pull()ing multiple commits at once.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 fetch.c       |    6 ++----
 fetch.h       |   11 ++++-------
 http-fetch.c  |    4 ++--
 local-fetch.c |    4 ++--
 ssh-fetch.c   |    4 ++--
 5 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/fetch.c b/fetch.c
index 989d7a4..3255cc6 100644
--- a/fetch.c
+++ b/fetch.c
@@ -8,9 +8,6 @@ #include "tag.h"
 #include "blob.h"
 #include "refs.h"
 
-const char *write_ref = NULL;
-const char *write_ref_log_details = NULL;
-
 int get_tree = 0;
 int get_history = 0;
 int get_all = 0;
@@ -213,7 +210,8 @@ static int mark_complete(const char *pat
 	return 0;
 }
 
-int pull(char *target)
+int pull(char *target, const char *write_ref,
+         const char *write_ref_log_details)
 {
 	struct ref_lock *lock = NULL;
 	unsigned char sha1[20];
diff --git a/fetch.h b/fetch.h
index 841bb1a..7bda355 100644
--- a/fetch.h
+++ b/fetch.h
@@ -22,12 +22,6 @@ extern void prefetch(unsigned char *sha1
  */
 extern int fetch_ref(char *ref, unsigned char *sha1);
 
-/* If set, the ref filename to write the target value to. */
-extern const char *write_ref;
-
-/* If set additional text will appear in the ref log. */
-extern const char *write_ref_log_details;
-
 /* Set to fetch the target tree. */
 extern int get_tree;
 
@@ -46,6 +40,9 @@ extern int get_recover;
 /* Report what we got under get_verbosely */
 extern void pull_say(const char *, const char *);
 
-extern int pull(char *target);
+/* If write_ref is set, the ref filename to write the target value to. */
+/* If write_ref_log_details is set, additional text will appear in the ref log. */
+extern int pull(char *target, const char *write_ref,
+		const char *write_ref_log_details);
 
 #endif /* PULL_H */
diff --git a/http-fetch.c b/http-fetch.c
index dc286b7..963d439 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -1216,6 +1216,7 @@ int fetch_ref(char *ref, unsigned char *
 
 int main(int argc, char **argv)
 {
+	const char *write_ref = NULL;
 	char *commit_id;
 	char *url;
 	char *path;
@@ -1250,7 +1251,6 @@ int main(int argc, char **argv)
 	}
 	commit_id = argv[arg];
 	url = argv[arg + 1];
-	write_ref_log_details = url;
 
 	http_init();
 
@@ -1268,7 +1268,7 @@ int main(int argc, char **argv)
 			alt->path_len = strlen(path);
 	}
 
-	if (pull(commit_id))
+	if (pull(commit_id, write_ref, url))
 		rc = 1;
 
 	http_cleanup();
diff --git a/local-fetch.c b/local-fetch.c
index 65a803a..308ed00 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -204,6 +204,7 @@ static const char local_pull_usage[] =
  */
 int main(int argc, char **argv)
 {
+	const char *write_ref = NULL;
 	char *commit_id;
 	int arg = 1;
 
@@ -240,9 +241,8 @@ int main(int argc, char **argv)
 		usage(local_pull_usage);
 	commit_id = argv[arg];
 	path = argv[arg + 1];
-	write_ref_log_details = path;
 
-	if (pull(commit_id))
+	if (pull(commit_id, write_ref, path))
 		return 1;
 
 	return 0;
diff --git a/ssh-fetch.c b/ssh-fetch.c
index a8a6cfb..aef3aa4 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -123,6 +123,7 @@ static const char ssh_fetch_usage[] =
   " [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url";
 int main(int argc, char **argv)
 {
+	const char *write_ref = NULL;
 	char *commit_id;
 	char *url;
 	int arg = 1;
@@ -159,7 +160,6 @@ int main(int argc, char **argv)
 	}
 	commit_id = argv[arg];
 	url = argv[arg + 1];
-	write_ref_log_details = url;
 
 	if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
 		return 1;
@@ -167,7 +167,7 @@ int main(int argc, char **argv)
 	if (get_version())
 		return 1;
 
-	if (pull(commit_id))
+	if (pull(commit_id, write_ref, url))
 		return 1;
 
 	return 0;

^ permalink raw reply related

* [PATCH 0/4] Fetching mass of objects at once
From: Petr Baudis @ 2006-07-27 21:53 UTC (permalink / raw)
  To: git; +Cc: jonsmirl

  Hi,

  this series implements support for fetching many objects at once with
git-local-fetch and git-http-fetch, greatly helping Cogito's performance.  It
would be of course nice to have this in Git 1.4.2, but it's probably too late
for that.

  I didn't bother to convert git-ssh-fetch since I think noone uses that
anymore anyway (why would they...), or only some legacy users do.

  I will followup with a patch for Cogito to take advantage of this. It's
now roughly on par with Git in cloning speed.

^ permalink raw reply

* Re: [PATCH] mailinfo: accept >From in message header
From: Michael S. Tsirkin @ 2006-07-27 21:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqraoi9s.fsf@assigned-by-dhcp.cox.net>

Quoting r. Junio C Hamano <junkio@cox.net>:
> Subject: Re: [PATCH] mailinfo: accept >From in message header
> 
> "Michael S. Tsirkin" <mst@mellanox.co.il> writes:
> 
> > From Majordomo@vger.kernel.org  Thu Jul 27 16:39:36 2006
> >>From mtsirkin  Thu Jul 27 16:39:36 2006
> > Received: from yok.mtl.com [10.0.8.11]
> > ....
> >
> > which confuses git-mailinfo since that does not recognize >From
> > as a valid header line. The following patch makes git-applymbox
> > work for me:
> 
> Wouldn't that kind of breakage confuse git-mailsplit as well?
> 

Hmm - I normally don't use it - just pipe stiff from mutt into git-applymbox.
A quick test seems to indicate git-mailsplit works fine.

But why should it - mailsplit just needs ^From to match new mail,
correct? So the escaped >From is good for it.

-- 
MST

^ permalink raw reply

* Re: [PATCH] mailinfo: accept >From in message header
From: Junio C Hamano @ 2006-07-27 21:22 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: git
In-Reply-To: <20060727140343.GS9411@mellanox.co.il>

"Michael S. Tsirkin" <mst@mellanox.co.il> writes:

> From Majordomo@vger.kernel.org  Thu Jul 27 16:39:36 2006
>>From mtsirkin  Thu Jul 27 16:39:36 2006
> Received: from yok.mtl.com [10.0.8.11]
> ....
>
> which confuses git-mailinfo since that does not recognize >From
> as a valid header line. The following patch makes git-applymbox
> work for me:

Wouldn't that kind of breakage confuse git-mailsplit as well?

^ permalink raw reply

* Re: Licensing and the library version of git
From: Johannes Schindelin @ 2006-07-27 21:19 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Wolfgang Denk, Jon Smirl, git
In-Reply-To: <Pine.LNX.4.64.0607271402230.4168@g5.osdl.org>

Hi,

On Thu, 27 Jul 2006, Linus Torvalds wrote:

> And as usual, tech people talking legal issues is not very sane. So talk 
> to a lawyer if you really care.

Amen.

And I will not talk to a lawyer today: I had a lovely day, and I don't 
want to spoil it.

Ciao,
Dscho

^ permalink raw reply

* Re: Licensing and the library version of git
From: Johannes Schindelin @ 2006-07-27 21:16 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: git
In-Reply-To: <20060727211046.C9FD5352625@atlas.denx.de>

Hi,

On Thu, 27 Jul 2006, Wolfgang Denk wrote:

> In message <Pine.LNX.4.63.0607272239050.29667@wbgn013.biozentrum.uni-wuerzburg.de> you wrote:
> > 
> > > ... and assuming it is a clean-room  implementation  which  does  not
> > > borrow from the GPL code.
> > 
> > >From a standpoint of copyright (which the GPL relies on), this is not 
> > possible: you cannot include C code into Java. And if it is _translated_ 
> > from C into Java, it is not copyrighted any more.
> 
> Gulp. What have  you  been  smoking  lately?

Nothing. I am a non-smoker. Maybe that is my problem?

> Your understanding of copyright (and of the GPL) is fundamentally 
> broken.

You can read an article. And you can publish the contents in your own 
words (you do not violate copyright by that). That is a fact.

And I do not buy into your "(and of the GPL)" thing. Either I get the 
copyright, which the GPL is based on, or I don't get the copyright (but 
still get that the GPL is based on it).

Ciao,
Dscho

^ permalink raw reply

* Re: Licensing and the library version of git
From: Linus Torvalds @ 2006-07-27 21:15 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Wolfgang Denk, Jon Smirl, git
In-Reply-To: <Pine.LNX.4.63.0607272239050.29667@wbgn013.biozentrum.uni-wuerzburg.de>



On Thu, 27 Jul 2006, Johannes Schindelin wrote:
> 
> From a standpoint of copyright (which the GPL relies on), this is not 
> possible: you cannot include C code into Java. And if it is _translated_ 
> from C into Java, it is not copyrighted any more.

That is definitely not true. Translation does not take away anything from 
the copyright. If I write a book in English, and you translate it to 
German, _I_ remain the copyright holder, and you need my permission to 
distribute the result. The fact that you translated it means nothing, and 
you don't own it as a result.

Similarly, the fact that I and others hold the copyright on the source 
code very much means that we also hold the copyright on any binaries you 
"translate" that source code into, and the only thing that gives you a 
right to distribute those binaries is not the translation phase, but the 
fact that the GPLv2 allows you to distribute binaries (with certain 
requirements, of course).

Now, on the other hand it's certainly true that certain elements are 
potentially uncopyrightable. If there is effectively only one sane or 
common way to actually write a git object to disk, the fact that your code 
ends up looking very similar in Java to the way it is done in the original 
C does not imply any copyright problems at all.

But that doesn't mean that you can take the C code and just rewrite it as 
Java - it was still copyright protected. It just means that if your Java 
code ends up looking like the C code, you can explain why it happened.

Now, some things have _no_ copyright protection at all, at least in 
certain areas. Facts and things that did not involve any artistic 
expression at all are simply not copyrightable. So if you list the first 
million digits of PI, you can't complain if somebody copies them, for 
example.

(But in some places, you can apparently claim that you "spent effort" on 
gathering those digits of PI, and that others would have to spend that 
same effort rather than copy your end result. I suspect that's a very weak 
argument, but I suspect that there have been worse arguments made in front 
of a judge in, say, places like Utah, to pick a random one).

And as usual, tech people talking legal issues is not very sane. So talk 
to a lawyer if you really care.

			Linus

^ permalink raw reply

* Re: Licensing and the library version of git
From: Wolfgang Denk @ 2006-07-27 21:10 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0607272239050.29667@wbgn013.biozentrum.uni-wuerzburg.de>

In message <Pine.LNX.4.63.0607272239050.29667@wbgn013.biozentrum.uni-wuerzburg.de> you wrote:
> 
> > ... and assuming it is a clean-room  implementation  which  does  not
> > borrow from the GPL code.
> 
> >From a standpoint of copyright (which the GPL relies on), this is not 
> possible: you cannot include C code into Java. And if it is _translated_ 
> from C into Java, it is not copyrighted any more.

Gulp. What have  you  been  smoking  lately?  Your  understanding  of
copyright (and of the GPL) is fundamentally broken.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Mr. Cole's Axiom:
        The sum of the intelligence on the planet is a constant;
        the population is growing.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox