Git development
 help / color / mirror / Atom feed
* [PATCH] cg-export to tarball
From: Joshua T. Corbin @ 2005-04-26  7:12 UTC (permalink / raw)
  To: git

The following patch to cg-export will simlpy create a tarball if the argument 
ends in .tar.gz, .tar.bz2, or .tar.

Signed-off-by; Joshua T. Corbin <jcorbin@wunjo.org>

Index: cg-export
===================================================================
--- c7eec90959408a71c465b36e728113a2754f99df/cg-export  (mode:100755 
sha1:94d419de48a12f1ea1059451ac4cd489f7008916)
+++ b839b802f91e79ea7b0bb7dcf3e228659bf96a87/cg-export  (mode:100755 
sha1:29834b2749b0a8d7c71a4c67325e4f5ece9d28a0)
@@ -24,8 +24,33 @@
 
 [ -e "$destdir" ] && die "$destdir already exists."
 
+case $destdir in
+  *.tar*)
+    tarfile=$destdir
+    destdir=${destdir%.tar*}
+    ;;
+esac
+
 mkdir -p $destdir || die "cannot create $destdir"
 export GIT_INDEX_FILE="$destdir/.git-index"
 read-tree $id
 checkout-cache "--prefix=$destdir/" -a
 rm $GIT_INDEX_FILE
+
+[ -z "$tarfile" ] && exit 0
+
+case $tarfile in
+  *.tar.gz)
+    tar -cvzf $tarfile $destdir || die "Failed to create $tarfile"
+    ;;
+  *.tar.bz2)
+    tar -cvjf $tarfile $destdir || die "Failed to create $tarfile"
+    ;;
+  *.tar)
+    tar -cvf $tarfile $destdir || die "Failed to create $tarfile"
+    ;;
+  *)
+    die "Don't know how to make a ${tarfile#$destdir} file"
+    ;;
+esac
+rm -fr $destdir

^ permalink raw reply

* Full linux-2.6 history?
From: Petr Baudis @ 2005-04-26  7:17 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: git

  Hello,

  I would like to ask about the status of the project to export the
linux-2.6 history from BitKeeper to GIT repository; it looked very
hopeful about a week or two ago, but got covered in silence soon.
Did Larry come upon you? ;-)

  I kept having people asking about this, so I would like to know.

  Thanks,

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* [PATCH COGITO] Do not make cross device hard links
From: Alexey Nezhdanov @ 2005-04-26  7:30 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 650 bytes --]

cg-clone doesn't work across devices:

cd /tmp # my tmp is on seperate partition
mkdir cg
cd cg
cg-clone /home/snake/cg/
....
`/home/snake/cg/.git/objects/85/eb3d54aeec1d0f4cf3d2de257b8d7e29816147' -> 
`.git/objects/85/eb3d54aeec1d0f4cf3d2de257b8d7e29816147'
cp: cannot create link 
`.git/objects/85/eb3d54aeec1d0f4cf3d2de257b8d7e29816147': Invalid 
cross-device link
-----------

I have decided that problem should be solved by omitting -u flag while 
fetching in cg-pul;:
$fetch -s -d "$uri/objects" ".git/objects" || die "rsync error"

My variant of autodetection is probably very ugly, but it's works for me :)

-- 
Respectfully
Alexey Nezhdanov

[-- Attachment #2: do-not-link-cross-device.patch --]
[-- Type: text/x-diff, Size: 1509 bytes --]

Index: cg-pull
===================================================================
--- f262000f302b749e485f5eb971e6aabefbb85680/cg-pull  (mode:100755 sha1:5cd67519fc5399886f22e8758d6d34e0e3014cbb)
+++ uncommitted/cg-pull  (mode:100755)
@@ -69,11 +69,15 @@
 	cp $cp_flags_l "$src" "$dest"
 }
 
+u_flag="-u"
+
 if echo "$uri" | grep -q ":"; then
 	fetch=fetch_rsync
 else
 	[ -d $uri/.git ] && uri=$uri/.git
 	fetch=fetch_local
+	cp -l $uri/branches/origin .cross-device-test 2>/dev/null || u_flag=""
+	[ -r .cross-device-test ] && rm .cross-device-test
 fi
 
 
@@ -95,17 +99,17 @@
 [ "$rsyncerr" ] && die "unable to get the head pointer of branch $rembranch"
 
 [ -d .git/objects ] || mkdir -p .git/objects
-$fetch -s -u -d "$uri/objects" ".git/objects" || die "rsync error"
+$fetch -s $u_flag -d "$uri/objects" ".git/objects" || die "rsync error"
 
 # FIXME: Warn about conflicting tag names?
 # XXX: We now throw stderr to /dev/null since not all repositories
 # may have tags/ and users were confused by the harmless errors.
 [ -d .git/refs/tags ] || mkdir -p .git/refs/tags
 rsyncerr=
-$fetch -s -u -d "$uri/refs/tags" ".git/refs/tags" 2>/dev/null || rsyncerr=1
+$fetch -s $u_flag -d "$uri/refs/tags" ".git/refs/tags" 2>/dev/null || rsyncerr=1
 if [ "$rsyncerr" ]; then
 	rsyncerr=
-	$fetch -s -u -d "$uri/tags" ".git/refs/tags" 2>/dev/null || rsyncerr=1
+	$fetch -s $u_flag -d "$uri/tags" ".git/refs/tags" 2>/dev/null || rsyncerr=1
 fi
 [ "$rsyncerr" ] && echo "unable to get tags list (non-fatal)" >&2
 

^ permalink raw reply

* Re: [PATCH 0/2] diff-tree/diff-cache helper
From: Junio C Hamano @ 2005-04-26  7:39 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0504251832480.18901@ppc970.osdl.org>

>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:

LT> Good, applied.

LT> This also makes me think that we should just make "show-diff" show the
LT> same format, at which point show-diff actually matches all the other
LT> tools, and it is likely to make show-diff more useful to boot.

Matching is good, ...

LT> Maybe rename the "show-diff" command to be "cache-diff", and if somebody
LT> wants the old "show-diff" thing, just have a script that does

LT> 	#!/bin/sh
LT> 	cache-diff | diff-tree-helper

LT> and nothing more.

Well, great minds do not think alike ;-) I was actually going in
quite the opposite way for the same goal of "matching".  My plan
was to rewrite the external diff interface once more to make it
more generic.  Then to add -p (patch) flag to diff-tree and
diff-cache, so that we do not need diff-tree-helper anymore.  My
ultimate motive for all of this is to make the core GIT useful
enough to render Cogito or any other wrapper layer more or less
irrelevant ;-).  Well type ^W a couple of times and rephrase
that to make things easier for the wrapper layer.

Jokes aside, I have updated the external diff interface and will
be sending you a patch in a separate message.  The existing
external diff interface had a horrible interface to the callers,
and it had a hardcoded knowledge of how to call diff and what
parameters to pass in which order, so the customization the end
user or the scripts could make was quite limited.  The updated
interface allows pretty much arbitrary formatting, so "git diff"
can put SHA1 instead of short-and-sweet 'a' or 'b' as directory
prefix in the patch output, for example.

When an environment variable GIT_EXTERNAL_DIFF exists, it names
a script that takes 7 parameters:

    name file1 sha1-1 mode1 file2 sha1-2 mode2

This is essentially the same idea you used for merge-cache.
Then the named command can use these information to generate and
format the diff any way it wants.  See how it interfaces using
the examples like this:

    GIT_EXTERNAL_DIFF=echo show-diff
    diff-cache $(cat .git/HEAD) | \
    GIT_EXTERNAL_DIFF=./jit-external-diff-script diff-tree-helper

The patch comes with a sample script, jit-external-diff-script,
but it is not much better than the built-in one; I do not expect
it to be used for anything other than starting point for wrapper
writers.

Without the environment variable, it uses a built-in
implementation that behaves exactly like the traditional
show-diff, and it can be customized via GIT_DIFF_CMD and
GIT_DIFF_OPTS as before.


^ permalink raw reply

* [PATCH] Diff-tree-helper take two.
From: Junio C Hamano @ 2005-04-26  7:57 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vll76ouk0.fsf@assigned-by-dhcp.cox.net>

This patch reworks the diff-tree-helper and show-diff to further
make external diff command interface simpler.  These commands
now honor GIT_EXTERNAL_DIFF environment variable which can point
at an arbitrary program that takes 7 parameters:

  name file1 file1-sha1 file1-mode file2 file2-sha1 file2-mode

The parameters for an external diff command are as follows:

  name        this invocation of the command is to emit diff
	      for the named cache/tree entry.

  file1       pathname that holds the contents of the first
	      file.  This can be a file inside the working
	      tree, or a temporary file created from the blob
	      object, or /dev/null.  The command should not
	      attempt to unlink it -- the temporary is
	      unlinked by the caller.

  file1-sha1  sha1 hash if file1 is a blob object, or "."
	      otherwise.

  file1-mode  mode bits for file1, or "." for a deleted file.

If GIT_EXTERNAL_DIFF environment variable is not set, the
default is to invoke diff with the set of parameters old
show-diff used to use.  This built-in implementation honors the
GIT_DIFF_CMD and GIT_DIFF_OPTS environment variables as before.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

diff-tree-helper.c       |  242 +++++++-------------------------------------
diff.c                   |  254 ++++++++++++++++++++++++++++++++++++++---------
diff.h                   |   34 ++++--
jit-external-diff-script |   14 ++
show-diff.c              |   17 ---
5 files changed, 288 insertions(+), 273 deletions(-)

--- k/diff-tree-helper.c
+++ l/diff-tree-helper.c
@@ -1,3 +1,6 @@
+/*
+ * Copyright (C) 2005 Junio C Hamano
+ */
 #include "cache.h"
 #include "strbuf.h"
 #include "diff.h"
@@ -17,15 +20,22 @@ static int matches_pathspec(const char *
 	return 0;
 }
 
-static int parse_oneside_change(const char *cp, unsigned char *sha1,
-				char *path) {
+static int parse_oneside_change(const char *cp, struct diff_spec *one,
+				char *path)
+{
 	int ch;
-	while ((ch = *cp) && '0' <= ch && ch <= '7')
-		cp++; /* skip mode bits */
+
+	one->file_valid = one->sha1_valid = 1;
+	one->mode = 0;
+	while ((ch = *cp) && '0' <= ch && ch <= '7') {
+		one->mode = (one->mode << 3) | (ch - '0');
+		cp++;
+	}
+
 	if (strncmp(cp, "\tblob\t", 6))
 		return -1;
 	cp += 6;
-	if (get_sha1_hex(cp, sha1))
+	if (get_sha1_hex(cp, one->u.sha1))
 		return -1;
 	cp += 40;
 	if (*cp++ != '\t')
@@ -34,31 +44,20 @@ static int parse_oneside_change(const ch
 	return 0;
 }
 
-#define STATUS_CACHED    0 /* cached and sha1 valid */
-#define STATUS_ABSENT    1 /* diff-tree says old removed or new added */
-#define STATUS_UNCACHED  2 /* diff-cache output: read from working tree */
-
 static int parse_diff_tree_output(const char *buf,
-				  unsigned char *old_sha1,
-				  int *old_status,
-				  unsigned char *new_sha1,
-				  int *new_status,
+				  struct diff_spec *old,
+				  struct diff_spec *new,
 				  char *path) {
 	const char *cp = buf;
 	int ch;
-	static unsigned char null_sha[20] = { 0, };
 
 	switch (*cp++) {
 	case '+':
-		*old_status = STATUS_ABSENT;
-		*new_status = (memcmp(new_sha1, null_sha, sizeof(null_sha)) ?
-			       STATUS_CACHED : STATUS_UNCACHED);
-		return parse_oneside_change(cp, new_sha1, path);
+		old->file_valid = 0;
+		return parse_oneside_change(cp, new, path);
 	case '-':
-		*new_status = STATUS_ABSENT;
-		*old_status = (memcmp(old_sha1, null_sha, sizeof(null_sha)) ?
-			       STATUS_CACHED : STATUS_UNCACHED);
-		return parse_oneside_change(cp, old_sha1, path);
+		new->file_valid = 0;
+		return parse_oneside_change(cp, old, path);
 	case '*':
 		break;
 	default:
@@ -66,191 +65,36 @@ static int parse_diff_tree_output(const 
 	}
 	
 	/* This is for '*' entries */
-	while ((ch = *cp) && ('0' <= ch && ch <= '7'))
-		cp++; /* skip mode bits */
+	old->file_valid = old->sha1_valid = 1;
+	new->file_valid = new->sha1_valid = 1;
+
+	old->mode = new->mode = 0;
+	while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
+		old->mode = (old->mode << 3) | (ch - '0');
+		cp++;
+	}
 	if (strncmp(cp, "->", 2))
 		return -1;
 	cp += 2;
-	while ((ch = *cp) && ('0' <= ch && ch <= '7'))
-		cp++; /* skip mode bits */
+	while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
+		new->mode = (new->mode << 3) | (ch - '0');
+		cp++;
+	}
 	if (strncmp(cp, "\tblob\t", 6))
 		return -1;
 	cp += 6;
-	if (get_sha1_hex(cp, old_sha1))
+	if (get_sha1_hex(cp, old->u.sha1))
 		return -1;
 	cp += 40;
 	if (strncmp(cp, "->", 2))
 		return -1;
 	cp += 2;
-	if (get_sha1_hex(cp, new_sha1))
+	if (get_sha1_hex(cp, new->u.sha1))
 		return -1;
 	cp += 40;
 	if (*cp++ != '\t')
 		return -1;
 	strcpy(path, cp);
-	*old_status = (memcmp(old_sha1, null_sha, sizeof(null_sha)) ?
-		       STATUS_CACHED : STATUS_UNCACHED);
-	*new_status = (memcmp(new_sha1, null_sha, sizeof(null_sha)) ?
-		       STATUS_CACHED : STATUS_UNCACHED);
-	return 0;
-}
-
-static int sha1err(const char *path, const unsigned char *sha1)
-{
-	return error("diff-tree-helper: unable to read sha1 file of %s (%s)",
-		     path, sha1_to_hex(sha1));
-}
-
-static int fserr(const char *path)
-{
-	return error("diff-tree-helper: unable to read file %s", path);
-}
-
-static char *map_whole_file(const char *path, unsigned long *size) {
-	int fd;
-	struct stat st;
-	void *buf;
-
-	if ((fd = open(path, O_RDONLY)) < 0) {
-		error("diff-tree-helper: unable to read file %s", path);
-		return 0;
-	}
-	if (fstat(fd, &st) < 0) {
-		close(fd);
-		error("diff-tree-helper: unable to stat file %s", path);
-		return 0;
-	}
-	*size = st.st_size;
-	buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-	close(fd);
-	return buf;
-}
-
-static int show_diff(const unsigned char *old_sha1, int old_status,
-		     const unsigned char *new_sha1, int new_status,
-		     const char *path, int reverse_diff)
-{
-	char other[PATH_MAX];
-	unsigned long size;
-	char type[20];
-	int fd;
-	int reverse;
-	void *blob = 0;
-	const char *fs = 0;
-	int need_unmap = 0;
-	int need_unlink = 0;
-
-
-	switch (old_status) {
-	case STATUS_CACHED:
-		blob = read_sha1_file(old_sha1, type, &size);
-		if (! blob)
-			return sha1err(path, old_sha1);
-			
-		switch (new_status) {
-		case STATUS_CACHED:
-			strcpy(other, ".diff_tree_helper_XXXXXX");
-			fd = mkstemp(other);
-			if (fd < 0)
-				die("unable to create temp-file");
-			if (write(fd, blob, size) != size)
-				die("unable to write temp-file");
-			close(fd);
-			free(blob);
-
-			blob = read_sha1_file(new_sha1, type, &size);
-			if (! blob)
-				return sha1err(path, new_sha1);
-
-			need_unlink = 1;
-			/* new = blob, old = fs */
-			reverse = !reverse_diff;
-			fs = other;
-			break;
-
-		case STATUS_ABSENT:
-		case STATUS_UNCACHED:
-			fs = ((new_status == STATUS_ABSENT) ?
-			      "/dev/null" : path);
-			reverse = reverse_diff;
-			break;
-
-		default:
- 			reverse = reverse_diff;
-		}
-		break;
-
-	case STATUS_ABSENT:
-		switch (new_status) {
-		case STATUS_CACHED:
-			blob = read_sha1_file(new_sha1, type, &size);
-			if (! blob)
-				return sha1err(path, new_sha1);
-			/* old = fs, new = blob */
-			fs = "/dev/null";
-			reverse = !reverse_diff;
-			break;
-
-		case STATUS_ABSENT:
-			return error("diff-tree-helper: absent from both old and new?");
-		case STATUS_UNCACHED:
-			fs = path;
-			blob = strdup("");
-			size = 0;
-			/* old = blob, new = fs */
-			reverse = reverse_diff;
-			break;
-		default:
-			reverse = reverse_diff;
-		}
-		break;
-
-	case STATUS_UNCACHED:
-		fs = path; /* old = fs, new = blob */
-		reverse = !reverse_diff;
-
-		switch (new_status) {
-		case STATUS_CACHED:
-			blob = read_sha1_file(new_sha1, type, &size);
-			if (! blob)
-				return sha1err(path, new_sha1);
-			break;
-
-		case STATUS_ABSENT:
-			blob = strdup("");
-			size = 0;
-			break;
-
-		case STATUS_UNCACHED:
-			/* old = fs */
-			blob = map_whole_file(path, &size);
-			if (! blob)
-				return fserr(path);
-			need_unmap = 1;
-			break;
-		default:
-			reverse = reverse_diff;
-		}
-		break;
-
-	default:
-		reverse = reverse_diff;
-	}
-	
-	if (fs)
-		show_differences(fs,
-				 path, /* label */
-				 blob,
-				 size,
-				 reverse /* 0: diff blob fs
-					    1: diff fs blob */);
-
-	if (need_unlink)
-		unlink(other);
-	if (need_unmap && blob)
-		munmap(blob, size);
-	else
-		free(blob);
 	return 0;
 }
 
@@ -275,28 +119,20 @@ int main(int ac, char **av) {
 	}
 	/* the remaining parameters are paths patterns */
 
-	prepare_diff_cmd();
-
 	while (1) {
-		int old_status, new_status;
-		unsigned char old_sha1[20], new_sha1[20];
+		struct diff_spec old, new;
 		char path[PATH_MAX];
 		read_line(&sb, stdin, line_termination);
 		if (sb.eof)
 			break;
-		if (parse_diff_tree_output(sb.buf,
-					   old_sha1, &old_status,
-					   new_sha1, &new_status,
-					   path)) {
+		if (parse_diff_tree_output(sb.buf, &old, &new, path)) { 
 			fprintf(stderr, "cannot parse %s\n", sb.buf);
 			continue;
 		}
-		if (1 < ac && ! matches_pathspec(path, av+1, ac-1))
+		if (1 < ac && !matches_pathspec(path, av+1, ac-1))
 			continue;
 
-		show_diff(old_sha1, old_status,
-			  new_sha1, new_status,
-			  path, reverse_diff);
+		run_external_diff(path, &old, &new);
 	}
 	return 0;
 }
--- k/diff.c
+++ l/diff.c
@@ -1,13 +1,22 @@
+/*
+ * Copyright (C) 2005 Junio C Hamano
+ */
+#include <sys/types.h>
+#include <sys/wait.h>
 #include "cache.h"
 #include "diff.h"
 
-static char *diff_cmd = "diff -L 'k/%s' -L 'l/%s' ";
-static char *diff_opts = "-p -u";
-static char *diff_arg_forward  = " - '%s'";
-static char *diff_arg_reverse  = " '%s' -";
+static char *diff_cmd = "diff -L'k/%s' -L'l/%s'";
+static char *diff_opts = "-pu";
 
-void prepare_diff_cmd(void)
+static const char *external_diff(void)
 {
+	static char *external_diff_cmd = NULL;
+	static int done_preparing = 0;
+
+	if (done_preparing)
+		return external_diff_cmd;
+
 	/*
 	 * Default values above are meant to match the
 	 * Linux kernel development style.  Examples of
@@ -17,8 +26,15 @@ void prepare_diff_cmd(void)
 	 * GIT_DIFF_CMD="diff -L '%s' -L '%s'"
 	 * GIT_DIFF_OPTS="-c";
 	 */
+	if (getenv("GIT_EXTERNAL_DIFF"))
+		external_diff_cmd = getenv("GIT_EXTERNAL_DIFF");
+
+	/* In case external diff fails... */
 	diff_cmd = getenv("GIT_DIFF_CMD") ? : diff_cmd;
 	diff_opts = getenv("GIT_DIFF_OPTS") ? : diff_opts;
+
+	done_preparing = 1;
+	return external_diff_cmd;
 }
 
 /* Help to copy the thing properly quoted for the shell safety.
@@ -58,49 +74,195 @@ static char *sq_expand(const char *src)
 	return buf;
 }
 
-void show_differences(const char *name, /* filename on the filesystem */
-		      const char *label, /* diff label to use */
-		      void *old_contents, /* contents in core */
-		      unsigned long long old_size, /* size in core */
-		      int reverse /* 0: diff core file
-				     1: diff file core */)
-{
-	FILE *f;
-	char *name_sq = sq_expand(name);
-	const char *label_sq = (name != label) ? sq_expand(label) : name_sq;
-	char *diff_arg = reverse ? diff_arg_reverse : diff_arg_forward;
-	int cmd_size = strlen(name_sq) + strlen(label_sq) * 2 +
-		strlen(diff_cmd) + strlen(diff_opts) + strlen(diff_arg);
+static struct diff_tempfile {
+	const char *name;
+	char hex[41];
+	char mode[10];
+	char tmp_path[50];
+} diff_temp[2];
+
+static void builtin_diff(const char *name,
+			 struct diff_tempfile *temp)
+{
+	static char *diff_arg  = "'%s' '%s'";
+	const char *name_1_sq = sq_expand(temp[0].name);
+	const char *name_2_sq = sq_expand(temp[1].name);
+	const char *name_sq = sq_expand(name);
+
+	/* diff_cmd and diff_arg have 4 %s in total which makes
+	 * the sum of these strings 8 bytes larger than required.
+	 * we use 2 spaces around diff-opts, and we need to count
+	 * terminating NUL, so we subtract 5 here.
+	 */
+	int cmd_size = (strlen(diff_cmd) + 
+			strlen(name_sq) * 2 +
+			strlen(diff_opts) +
+			strlen(diff_arg) +
+			strlen(name_1_sq) + strlen(name_2_sq)
+			- 5);
 	char *cmd = malloc(cmd_size);
-	int next_at;
+	int next_at = 0;
+
+	next_at += snprintf(cmd+next_at, cmd_size-next_at,
+			    diff_cmd, name_sq, name_sq);
+	next_at += snprintf(cmd+next_at, cmd_size-next_at,
+			    " %s ", diff_opts);
+	next_at += snprintf(cmd+next_at, cmd_size-next_at,
+			    diff_arg, name_1_sq, name_2_sq);
+	execlp("/bin/sh","sh", "-c", cmd, NULL);
+}
+
+static void prepare_temp_file(const char *name,
+			      struct diff_tempfile *temp,
+			      struct diff_spec *one)
+{
+	static unsigned char null_sha1[20] = { 0, };
 
-	fflush(stdout);
-	next_at = snprintf(cmd, cmd_size, diff_cmd, label_sq, label_sq);
-	next_at += snprintf(cmd+next_at, cmd_size-next_at, "%s", diff_opts);
-	next_at += snprintf(cmd+next_at, cmd_size-next_at, diff_arg, name_sq);
-	f = popen(cmd, "w");
-	if (old_size)
-		fwrite(old_contents, old_size, 1, f);
-	pclose(f);
-	if (label_sq != name_sq)
-		free((void*)label_sq); /* constness */
-	free(name_sq);
-	free(cmd);
-}
-
-void show_diff_empty(const unsigned char *sha1,
-		     const char *name,
-		     int reverse)
-{
-	char *old;
-	unsigned long int size;
-	unsigned char type[20];
-
-	old = read_sha1_file(sha1, type, &size);
-	if (! old) {
-		error("unable to read blob object for %s (%s)", name,
-		      sha1_to_hex(sha1));
+	if (!one->file_valid) {
+	not_a_valid_file:
+		temp->name = "/dev/null";
+		strcpy(temp->hex, ".");
+		strcpy(temp->mode, ".");
 		return;
 	}
-	show_differences("/dev/null", name, old, size, reverse);
+
+	if (one->sha1_valid &&
+	    !memcmp(one->u.sha1, null_sha1, sizeof(null_sha1))) {
+		one->sha1_valid = 0;
+		one->u.name = name;
+	}
+
+	if (!one->sha1_valid) {
+		struct stat st;
+		temp->name = one->u.name;
+		if (stat(temp->name, &st) < 0) {
+			if (errno == ENOENT)
+				goto not_a_valid_file;
+			die("stat(%s): %s", temp->name, strerror(errno));
+		}
+		strcpy(temp->hex, ".");
+		sprintf(temp->mode, "%06o",
+			S_IFREG |ce_permissions(st.st_mode));
+	}
+	else {
+		int fd;
+		void *blob;
+		char type[20];
+		unsigned long size;
+
+		blob = read_sha1_file(one->u.sha1, type, &size);
+		if (!blob || strcmp(type, "blob"))
+			die("unable to read blob object for %s (%s)",
+			    name, sha1_to_hex(one->u.sha1));
+
+		strcpy(temp->tmp_path, ".diff_XXXXXX");
+		fd = mkstemp(temp->tmp_path);
+		if (fd < 0)
+			die("unable to create temp-file");
+		if (write(fd, blob, size) != size)
+			die("unable to write temp-file");
+		close(fd);
+		free(blob);
+		temp->name = temp->tmp_path;
+		strcpy(temp->hex, sha1_to_hex(one->u.sha1));
+		temp->hex[40] = 0;
+		sprintf(temp->mode, "%06o", one->mode);
+	}
+}
+
+static void remove_tempfile(void)
+{
+	int i;
+
+	for (i = 0; i < 2; i++)
+		if (diff_temp[i].name == diff_temp[i].tmp_path) {
+			unlink(diff_temp[i].name);
+			diff_temp[i].name = NULL;
+		}
+}
+
+/* An external diff command takes:
+ *
+ * diff-cmd name infile1 infile1-sha1 infile1-mode \
+ *               infile2 infile2-sha1 infile2-mode.
+ *
+ */
+void run_external_diff(const char *name,
+		       struct diff_spec *one,
+		       struct diff_spec *two)
+{
+	struct diff_tempfile *temp = diff_temp;
+	int pid, status;
+	static int atexit_asked = 0;
+
+	prepare_temp_file(name, &temp[0], one);
+	prepare_temp_file(name, &temp[1], two);
+	if (! atexit_asked &&
+	    (temp[0].name == temp[0].tmp_path ||
+	     temp[1].name == temp[1].tmp_path)) {
+		atexit_asked = 1;
+		atexit(remove_tempfile);
+	}
+
+	fflush(NULL);
+	pid = fork();
+	if (pid < 0)
+		die("unable to fork");
+	if (!pid) {
+		const char *pgm = external_diff();
+		if (pgm)
+			execlp(pgm, pgm,
+			       name,
+			       temp[0].name, temp[0].hex, temp[0].mode,
+			       temp[1].name, temp[1].hex, temp[1].mode,
+			       NULL);
+		/*
+		 * otherwise we use the built-in one.
+		 */
+		builtin_diff(name, temp);
+		exit(0);
+	}
+	if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status))
+		die("diff program failed");
+
+	remove_tempfile();
+}
+
+void show_diff_empty(const struct cache_entry *ce, int reverse)
+{
+	struct diff_spec spec[2], *one, *two;
+
+	memcpy(spec[0].u.sha1, ce->sha1, 20);
+	spec[0].mode = ntohl(ce->ce_mode);
+	spec[0].sha1_valid = spec[0].file_valid = 1;
+	spec[1].file_valid = 0;
+
+	if (reverse) {
+		one = spec + 1; two = spec;
+	} else {
+		one = spec; two = one + 1;
+	}
+
+	run_external_diff(ce->name, one, two);
+}
+
+void show_differences(const struct cache_entry *ce, int reverse) 
+{
+	struct diff_spec spec[2], *one, *two;
+
+	memcpy(spec[0].u.sha1, ce->sha1, 20);
+	spec[0].mode = ntohl(ce->ce_mode);
+	spec[0].sha1_valid = spec[0].file_valid = 1;
+
+	spec[1].u.name = ce->name; /* the name we stated */
+	spec[1].sha1_valid = 0;
+	spec[1].file_valid = 1;
+
+	if (reverse) {
+		one = spec + 1; two = spec;
+	} else {
+		one = spec; two = one + 1;
+	}
+
+	run_external_diff(ce->name, one, two);
 }
--- k/diff.h
+++ l/diff.h
@@ -1,17 +1,31 @@
+/*
+ * Copyright (C) 2005 Junio C Hamano
+ */
 #ifndef DIFF_H
 #define DIFF_H
 
-extern void prepare_diff_cmd(void);
+/* These two are for backward compatibility with show-diff;
+ * new users should not use them.
+ */
+extern void show_differences(const struct cache_entry *ce, int reverse);
+extern void show_diff_empty(const struct cache_entry *ce, int reverse);
 
-extern void show_differences(const char *name, /* filename on the filesystem */
-			     const char *label, /* diff label to use */
-			     void *old_contents, /* contents in core */
-			     unsigned long long old_size, /* size in core */
-			     int reverse /* 0: diff core file
-					    1: diff file core */);
+struct diff_spec {
+	union {
+		const char *name;       /* path on the filesystem */
+		unsigned char sha1[20]; /* blob object ID */
+	} u;
+	unsigned short mode;	 /* file mode */
+	unsigned sha1_valid : 1; /* if true, use u.sha1 and trust mode.
+				  * (however with a NULL SHA1, read them
+				  * from the file!).
+				  * if false, use u.name and read mode from
+				  * the filesystem.
+				  */
+	unsigned file_valid : 1; /* if false the file does not even exist */
+};
 
-extern void show_diff_empty(const unsigned char *sha1,
-			    const char *name,
-			    int reverse);
+extern void run_external_diff(const char *name,
+			      struct diff_spec *, struct diff_spec *);
 
 #endif /* DIFF_H */
--- k/jit-external-diff-script
+++ l/jit-external-diff-script
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (C) 2005 Junio C Hamano
+#
+
+name="$1" name1="$2" sha11="$3" mode1="$4"
+          name2="$5" sha12="$6" mode2="$7"
+
+case "$sha11" in .) sha11=file-not-in-blob-but-in-the-working-tree ;; esac
+case "$sha12" in .) sha12=file-not-in-blob-but-in-the-working-tree ;; esac
+case "$mode1" in .) mode1=;; *) mode1=" ($mode1)" ;;esac
+case "$mode2" in .) mode2=;; *) mode2=" ($mode2)" ;;esac
+
+diff -pu -L "$sha11/$name$mode1" -L "$sha12/$name$mode2" "$name1" "$name2"
--- k/show-diff.c
+++ l/show-diff.c
@@ -53,14 +53,11 @@ int main(int argc, char **argv)
 		perror("read_cache");
 		exit(1);
 	}
-	prepare_diff_cmd();
+
 	for (i = 0; i < entries; i++) {
 		struct stat st;
 		struct cache_entry *ce = active_cache[i];
 		int changed;
-		unsigned long size;
-		char type[20];
-		void *old;
 
 		if (1 < argc &&
 		    ! matches_pathspec(ce, argv+1, argc-1))
@@ -87,8 +84,7 @@ int main(int argc, char **argv)
 			else {
 				printf("%s: %s\n", ce->name, strerror(errno));
 				if (errno == ENOENT)
-					show_diff_empty(ce->sha1, ce->name,
-							reverse);
+					show_diff_empty(ce, reverse);
 			}
 			continue;
 		}
@@ -104,14 +100,7 @@ int main(int argc, char **argv)
 		if (silent)
 			continue;
 
-		old = read_sha1_file(ce->sha1, type, &size);
-		if (! old)
-			error("unable to read blob object for %s (%s)",
-			      ce->name, sha1_to_hex(ce->sha1));
-		else
-			show_differences(ce->name, ce->name, old, size,
-					 reverse);
-		free(old);
+		show_differences(ce, reverse);
 	}
 	return 0;
 }


^ permalink raw reply

* Re: : Networking
From: Andrew Morton @ 2005-04-26  7:57 UTC (permalink / raw)
  To: David S. Miller; +Cc: torvalds, git
In-Reply-To: <20050425214326.512b006e.davem@davemloft.net>

"David S. Miller" <davem@davemloft.net> wrote:
>
> Linus, please pull from:
> 
>  	rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git

So I tried to apply my new get-mm-patches-from-git methodology on this and
came unstuck.

-mm kernels consist of a series of patches against the most recent release
(2.6.12-rc3 today):

	linus.patch		(Linus' changes since 2.6.12-rc3)
	git-net.patch		(Davem's changes wrt Linus's latest tree)
	etc...

The algorithm is:


a) Set up the git repo

	mkdir git26
	git init rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

	(Futz around in `git log' output to identify the v2.6.12-rc3 commit, do
	 `git tag v2.6.12-rc3 a2755a80f40e5794ddc20e00f781af9d6320fafb')

b) Add davem's repo:

	git addremote git-net rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git

c) To generate -mm's linus.patch (patch against 2.6.12-rc3):

	git pull origin
	git diff -r v2.6.12-rc3 > ../25/patches/linus.patch

d) To generate davem's tree (patch against linus's current tree (ie: patch
   against 2.6.12-rc3+linus.patch)):

	git pull git-net
	MERGE_BASE=$(merge-base $(cat .git/heads/origin ) $(cat .git/heads/git-net))
	git diff -r $MERGE_BASE:$(cat .git/heads/git-net) > ../25/patches/git-net.patch

e) Repeat d) for all known git trees.



But git-net.patch has a bunch of bluetooth stuff in it which is already in
Linus's tree.  And git-net.patch modifies net/sched/simple.c, which doesn't
appear in either 2.6.12-rc3 or in current -linus.


Doing step d) by hand:


	bix:/usr/src/git26> cat .git/heads/origin
	b453257f057b834fdf9f4a6ad6133598b79bd982
	bix:/usr/src/git26> cat .git/heads/git-net
	5523662c4cd585b892811d7bb3e25d9a787e19b3
	bix:/usr/src/git26> merge-base b453257f057b834fdf9f4a6ad6133598b79bd982 5523662c4cd585b892811d7bb3e25d9a787e19b3
	25ee7e3832951cf5896b194f6cd929a44863f419

	bix:/usr/src/git26> cat-file commit 25ee7e3832951cf5896b194f6cd929a44863f419
	tree 5b6486ded5188e41ac9bc81ad4a5e2bd746f7ede
	parent 056de2fa12febe02597f971eb6ea8f2cc9c9b06e
	author Adrian Bunk <bunk@stusta.de> 1114442294 -0700
	committer Linus Torvalds <torvalds@ppc970.osdl.org> 1114442294 -0700

	[PATCH] fs/aio.c: make some code static

	This patch makes some needlessly global code static.

	Signed-off-by: Adrian Bunk <bunk@stusta.de>
	Acked-by: Benjamin LaHaise <bcrl@kvack.org>
	Signed-off-by: Linus Torvalds <torvalds@osdl.org>


That seems to be a reasonable gca.  It's the last thing which Linus added
prior to merging the ARM patches, which presumably weren't in Dave's tree.

So let's try to grab davem's diff wrt that gca:

bix:/usr/src/git26> git diff -r 25ee7e3832951cf5896b194f6cd929a44863f419:5523662c4cd585b892811d7bb3e25d9a787e19b3 | diffstat
 drivers/net/tg3.c                            |   73 ++++++++++++++-------------
 net/bluetooth/af_bluetooth.c                 |    1 
 net/bluetooth/bnep/sock.c                    |    1 
 net/bluetooth/cmtp/capi.c                    |    1 
 net/bluetooth/cmtp/core.c                    |    1 
 net/bluetooth/cmtp/sock.c                    |    1 
 net/bluetooth/hci_conn.c                     |    1 
 net/bluetooth/hci_core.c                     |    1 
 net/bluetooth/hci_event.c                    |    1 
 net/bluetooth/hci_sock.c                     |    1 
 net/bluetooth/hidp/core.c                    |    1 
 net/bluetooth/hidp/sock.c                    |    1 
 net/bluetooth/l2cap.c                        |    1 
 net/bluetooth/rfcomm/sock.c                  |    1 
 net/bluetooth/sco.c                          |    1 
 net/core/rtnetlink.c                         |    1 
 net/core/scm.c                               |    1 
 net/core/sock.c                              |    1 
 net/ipv4/af_inet.c                           |    1 
 net/ipv4/ip_output.c                         |    2 
 net/ipv4/netfilter/ip_conntrack_ftp.c        |    4 -
 net/ipv4/netfilter/ip_conntrack_standalone.c |    7 --
 net/ipv4/tcp_input.c                         |    1 
 net/ipv6/af_inet6.c                          |    1 
 net/netlink/af_netlink.c                     |    1 
 net/sched/simple.c                           |   18 ------
 net/unix/af_unix.c                           |    1 
 27 files changed, 46 insertions(+), 80 deletions(-)

And that's the bad patch.

What did I do wrong?

Can someone suggest a better approach?

Thanks.


^ permalink raw reply

* [PATCH] Convert shortlog to handle cogito (cg-log) output
From: Ryan Anderson @ 2005-04-26  8:39 UTC (permalink / raw)
  To: Matthias Andree; +Cc: Linus Torvalds, git


Convert "shortlog" to understand cogito's cg-log output format instead
of "bk changes" format.

Cogito (and by inference, "git" in general) have a different log output
format than BitKeeper.  This log format seems somewhat simpler to parse.

The following patch is a *bare minimum* conversion to make "shortlog"
provide corrected output the Cogito script "cg-log".

(This is clearly not sufficient, and not intended for application to any
rea tree, as a lot of BitKeeper domain knowledge remains, but this
should be enough for Linus to provide changelogs in the "shortlog"
format again, and hopefully to serve as a template for further
modifications by others.)

Signed-Off-By: Ryan Anderson <ryan@michonline.com>

--- cogito-tools/shortlog	2005-04-26 04:22:01.000000000 -0400
+++ cogito-tools/git-shortlog	2005-04-26 04:36:52.000000000 -0400
@@ -3052,7 +3052,7 @@
       }
 
     if (defined $address and $opt{multi}
-	and m{^[^<[:space:]]} and not m{^ChangeSet@}) {
+	and m{^[^<[:space:]]} and not m{^commit }) {
       # if we are in multi mode, if we encounter a non-address
       # left-justified line, flush all data and print the header. The
       # 'defined $address' trick lets this only trigger to switch back
@@ -3063,13 +3063,14 @@
       @prolog = ($_);
       undef %$log;
       undef $address;
-    } elsif (m{^<([^>]+)>} or m{^ChangeSet@[0-9.]+,\s*[-0-9:+ ]+,\s*(\S+)}) {
+    } elsif (m{^<([^>]+)>} or m{^author (.*) <(.*)>}) {
       # go figure if a line starts with an address, if so, take it
       # resolve the address to a name if possible
       append_item(%$log, @cur); @cur = ();
-      $address = lc($1);
+      $address = lc($2);
       $address =~ s/\[[^]]+\]$//;
       $name = rmap_address($address, 1);
+      $name = $1 if ($name eq $address);
       $author = treat_addr_name($address, $name);
       $first = 1;
       $firstpar = 1;
@@ -3093,25 +3094,28 @@
       } else {
 	  print STDERR " SKIPPED SIGNED-OFF-BY  $author\n" if $debug;
       }
-    } elsif ($first) {
+    } elsif ($first && m/^(?:[[:space:]]{4}|\t)(.*)$/) {
       # we have a "first" line after an address, take it,
       # strip common redundant tags
+      
+      my $comment = $1;
 
       # kill "PATCH" tag
-      s/^\s*\[PATCH\]//;
-      s/^\s*PATCH//;
-      s/^\s*[-:]+\s*//;
+      $comment =~ s/^\s*\[PATCH\]//;
+      $comment =~ s/^\s*PATCH//;
+      $comment =~ s/^\s*[-:]+\s*//;
 
       # strip trailing colon or period, and if we strip one,
       # we don't parse further lines as part of the first paragraph
-      if (s/[:.]+\s*$//) { $firstpar = 0; }
+      if ($comment =~ s/[:.]+\s*$//) { $firstpar = 0; }
 
       # kill leading and trailing whitespace for consistent indentation
-      s/^\s+//; s/\s+$//;
+      $comment =~ s/^\s+//; s/\s+$//;
 
-      push @cur, $_;
+      push @cur, $comment;
       $first = 0;
-    } elsif (defined $address) {
+
+    } elsif (defined $address && m/^(?:[[:space:]]{4}|\t)(.*)$/ ) {
       # second or subsequent lines -- if in first paragraph,
       # append this line to the first log line.
       if (m/^\s*$/) { $firstpar = 0; }
@@ -3124,6 +3128,10 @@
       }
       # we don't parse further lines as part of the first paragraph
       if (s/[:.]+\s*$//) { $firstpar = 0; }
+
+    } elsif (m/^(commit|tree|parent|committer) / || m/^\s*$/) {
+      # Skip unused header lines
+
     } else {
       # store header before a changelog
       push @prolog, $_;


-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* [PATCH] Cogito: do not clobber pre-existing $(bindir)'s mode
From: Sean Neakums @ 2005-04-26 10:23 UTC (permalink / raw)
  To: git


Index: Makefile
===================================================================
--- f262000f302b749e485f5eb971e6aabefbb85680/Makefile  (mode:100644 sha1:4f01bbbbb3fd0e53e9ce968f167b6dae68fcfa92)
+++ uncommitted/Makefile  (mode:100644)
@@ -95,7 +95,7 @@
 	@chmod +x $@
 
 install: $(PROG) $(SCRIPTS) $(SCRIPT) $(GEN_SCRIPT)
-	install -m755 -d $(DESTDIR)$(bindir)
+	[ ! -d $(DESTDIR)$(bindir) ] && install -m755 -d $(DESTDIR)$(bindir)
 	install $(PROG) $(SCRIPTS) $(SCRIPT) $(GEN_SCRIPT) $(DESTDIR)$(bindir)
 
 clean:

-- 
Dag vijandelijk luchtschip de huismeester is dood

^ permalink raw reply

* Re: [PATCH] Cogito: do not clobber pre-existing $(bindir)'s mode
From: Sean Neakums @ 2005-04-26 10:52 UTC (permalink / raw)
  To: git
In-Reply-To: <6uwtqpj0oy.fsf@zork.zork.net>

Here is one that actually works.

That'll teach me to be tricky.  (It won't.)


Index: Makefile
===================================================================
--- f262000f302b749e485f5eb971e6aabefbb85680/Makefile  (mode:100644 sha1:4f01bbbbb3fd0e53e9ce968f167b6dae68fcfa92)
+++ uncommitted/Makefile  (mode:100644)
@@ -95,7 +95,7 @@
 	@chmod +x $@
 
 install: $(PROG) $(SCRIPTS) $(SCRIPT) $(GEN_SCRIPT)
-	install -m755 -d $(DESTDIR)$(bindir)
+	[ -d $(DESTDIR)$(bindir) ] || install -m755 -d $(DESTDIR)$(bindir)
 	install $(PROG) $(SCRIPTS) $(SCRIPT) $(GEN_SCRIPT) $(DESTDIR)$(bindir)
 
 clean:

-- 
Dag vijandelijk luchtschip de huismeester is dood

^ permalink raw reply

* Re: Re: A darcs that can pull from git
From: David Roundy @ 2005-04-26 11:06 UTC (permalink / raw)
  To: Juliusz Chroboczek; +Cc: Git Mailing List, darcs-devel
In-Reply-To: <7i4qdusxdw.fsf@lanthane.pps.jussieu.fr>

On Mon, Apr 25, 2005 at 05:12:59PM +0200, Juliusz Chroboczek wrote:
> > Do you have any plans/ideas for allowing pulls directly from a
> > remote git repository?
> 
> I haven't thought about it yet.  Does anyone have any ideas about how
> to efficiently pull from git without a complete local copy?

I don't think so.  My best thought so far would be to have something like a
~/.gitcache/, which would store the sha1 objects themselves, so at least
we'd only end up with *one* local copy.  I'm actually curious what the true
git people do about this--it would be nice to share a cache.  For darcs'
purposes, we could prune the cache from time to time.  If we're running
with a darcs backend, we really only need the recent versions of files and
trees.

Do the git have any suggestions about how to avoid excess downloads or
excess copies of a git repository? It seems to me like it would make sense
to always download sha1s to ~/.gitcache/, and then hardlink them to the
current git repository, so you wouldn't end up ever downloading the same
sha1 twice.  Or we should use $GITCACHE/, to give the user some
flexibility.  But perhaps this is an already-solved problem, and I've just
not noticed...

As far as other details, currently we can just walk the tree to find out
what files are needed, right?
-- 
David Roundy
http://www.darcs.net

^ permalink raw reply

* Re: Mercurial 0.3 vs git benchmarks
From: Chris Mason @ 2005-04-26 11:13 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Mike Taht, Matt Mackall, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0504252032500.18901@ppc970.osdl.org>

On Tuesday 26 April 2005 00:00, Linus Torvalds wrote:
> On Mon, 25 Apr 2005, Linus Torvalds wrote:
> > The easiest test-case is Andrew's 198-patch patch-bomb on linux-kernel a
> > few weeks ago: they all apply cleanly to 2.6.12-rc2 (in order), and you
> > can use my "dotest" script to automate the test..
>
> Oh, well. That was so trivial that I just did it:
[ ... ]

> ie the "initial add" is almost twice as fast (because it spends most of
> the time compressing _all_ the files), but the difference in applying 198
> patches is not noticeable at all (because the costs are all elsewhere).
>
> That's 198 patches in less than a minute even with the highest
> compression. That rocks.

This agrees with my tests here, the time to apply patches is somewhat disk 
bound, even for the small 100 or 200 patch series.  The io should be coming 
from data=ordered, since the commits are still every 5 seconds or so.

-chris

^ permalink raw reply

* Re: [ANNOUNCE] Cogito-0.8 (former git-pasky, big changes!)
From: Petr Baudis @ 2005-04-26 12:23 UTC (permalink / raw)
  To: Mike Taht; +Cc: git
In-Reply-To: <426DBF94.3010502@timesys.com>

Dear diary, on Tue, Apr 26, 2005 at 06:12:04AM CEST, I got a letter
where Mike Taht <mike.taht@timesys.com> told me that...
> 
> >  Yes, this is a huge change. No, I don't expect any further changes of
> >similar scale. I think the new interface is significantly simpler _and_
> >cleaner than the old one.
> 
> Heh. Another huge change would be moving the top level directories 
> around a bit.
> 
> 
> bindings  COPYING  git.spec  Makefile  programs  README.reference  tests
> contrib   doc      include   po        README    src  VERSION
> 
> Leaving fixing the makefiles aside as an exercise for the interested 
> reader... that's:

Actually, I've been thinking about this, but I think we just don't need
it *yet*.

And by the time we will need to make things more hierarchical, we will
hopefully have some way to deal with renames sensibly. We need something
for that too - either something ultra-smart as Linus describes, or
explicit renames, but merging not working across renames makes them
total nightmare.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* Re: Re: A darcs that can pull from git
From: Petr Baudis @ 2005-04-26 12:34 UTC (permalink / raw)
  To: Juliusz Chroboczek, darcs-devel, Git Mailing List
In-Reply-To: <20050426110613.GB20723@abridgegame.org>

Dear diary, on Tue, Apr 26, 2005 at 01:06:17PM CEST, I got a letter
where David Roundy <droundy@abridgegame.org> told me that...
> On Mon, Apr 25, 2005 at 05:12:59PM +0200, Juliusz Chroboczek wrote:
> > > Do you have any plans/ideas for allowing pulls directly from a
> > > remote git repository?
> > 
> > I haven't thought about it yet.  Does anyone have any ideas about how
> > to efficiently pull from git without a complete local copy?
> 
> I don't think so.  My best thought so far would be to have something like a
> ~/.gitcache/, which would store the sha1 objects themselves, so at least
> we'd only end up with *one* local copy.  I'm actually curious what the true
> git people do about this--it would be nice to share a cache.  For darcs'
> purposes, we could prune the cache from time to time.  If we're running
> with a darcs backend, we really only need the recent versions of files and
> trees.
> 
> Do the git have any suggestions about how to avoid excess downloads or
> excess copies of a git repository? It seems to me like it would make sense
> to always download sha1s to ~/.gitcache/, and then hardlink them to the
> current git repository, so you wouldn't end up ever downloading the same
> sha1 twice.  Or we should use $GITCACHE/, to give the user some
> flexibility.  But perhaps this is an already-solved problem, and I've just
> not noticed...

I'm not sure about the problem you are actually trying to solve, and I
didn't manage to guess it quickly just from the mails themselves;
cg-init /local/path now hardlinks the sha1 objects to the local
.git/objects directory, so you get no space waste. If you are talking
about downloading stuff from remote repositories, http-pull might help.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* Re: [PATCH] cogito recursive cg-add and cg-rm
From: Petr Baudis @ 2005-04-26 12:39 UTC (permalink / raw)
  To: Joshua T. Corbin; +Cc: git
In-Reply-To: <200504260027.03451.jcorbin@wunjo.org>

Dear diary, on Tue, Apr 26, 2005 at 06:27:02AM CEST, I got a letter
where "Joshua T. Corbin" <jcorbin@wunjo.org> told me that...
> This patch adds recursive addition and removal to cg-add and cg-rm, recursion 
> can be disabled with the -n switch.
> 
> Signed-off-by: Joshua T. Corbin <jcorbin@wunjo.org>

I'd actually prefer -r to explicitly turn the recursion on. That is more
consistent with the rest of the UNIX world and I really don't feel
comfortable with cg-rm recursing by default. ;-)

Also please use tabs for indentation.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* Re: [darcs-devel] Re: A darcs that can pull from git
From: David Roundy @ 2005-04-26 12:47 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Juliusz Chroboczek, darcs-devel, Git Mailing List
In-Reply-To: <20050426123445.GE18971@pasky.ji.cz>

On Tue, Apr 26, 2005 at 02:34:45PM +0200, Petr Baudis wrote:
> Dear diary, on Tue, Apr 26, 2005 at 01:06:17PM CEST, I got a letter
> where David Roundy <droundy@abridgegame.org> told me that...
> > Do the git have any suggestions about how to avoid excess downloads or
> > excess copies of a git repository? It seems to me like it would make sense
> > to always download sha1s to ~/.gitcache/, and then hardlink them to the
> > current git repository, so you wouldn't end up ever downloading the same
> > sha1 twice.  Or we should use $GITCACHE/, to give the user some
> > flexibility.  But perhaps this is an already-solved problem, and I've just
> > not noticed...
> 
> I'm not sure about the problem you are actually trying to solve, and I
> didn't manage to guess it quickly just from the mails themselves;
> cg-init /local/path now hardlinks the sha1 objects to the local
> .git/objects directory, so you get no space waste. If you are talking
> about downloading stuff from remote repositories, http-pull might help.

Yeah, what I was wondering about was the scenario where a user does (and
pardon any errors, I haven't actually used cogito) something like

cd foo
cg-init http://remote_repository
cd ../bar
cg-init ../foo

(so far we've only got hard links and everything is great)

http-pull http://remote_repository (downloads a few more commits to bar)
cd ../foo
http-pull http://remote_repository

Does this last pull download the same commits as the previous one? Ideally
it wouldn't.  The whole point of the sha1-named files is that you don't
have to worry about where you got it from.  Ideally the second pull would
get the actual files from ../bar, where they've already been downloaded.

Or perhaps (and this was what I was *really* hoping) all the cogito remote
operations would store a hardlink of their results in a common cache
directory, so that one could actually do

cd foo
cg-init http://remote_repository
cd ../bar
cg-init http://remote_repository

without either downloading anything twice, or wasting any disk space.  In
practice what's more likely in practice is that you'll want to

cd foo
cg-init http://linus_remote_repository
cd ../bar
cg-init http://gregkh_remote_repository

and would like to avoid downloading redundant info.
-- 
David Roundy
http://www.darcs.net

^ permalink raw reply

* Re: [PATCH] cogito recursive cg-add and cg-rm
From: Joshua T. Corbin @ 2005-04-26 13:21 UTC (permalink / raw)
  To: git
In-Reply-To: <20050426123901.GF18971@pasky.ji.cz>

On 26 April 2005 08:39, Petr Baudis wrote:
> Dear diary, on Tue, Apr 26, 2005 at 06:27:02AM CEST, I got a letter
> where "Joshua T. Corbin" <jcorbin@wunjo.org> told me that...
>
> > This patch adds recursive addition and removal to cg-add and cg-rm,
> > recursion can be disabled with the -n switch.
> >
> > Signed-off-by: Joshua T. Corbin <jcorbin@wunjo.org>
>
> I'd actually prefer -r to explicitly turn the recursion on. That is more
> consistent with the rest of the UNIX world and I really don't feel
> comfortable with cg-rm recursing by default. ;-)
Hmm, I guess for it to work the way I was inteding would take a little more 
work; it should bail if any of the files are not in the repository or are 
locally modified.

> Also please use tabs for indentation.
Will do

-- 
Regards,
Joshua T. Corbin <jcorbin@wunjo.org>

^ permalink raw reply

* Re: [ANNOUNCE] Cogito-0.8 (former git-pasky, big changes!)
From: Morten Welinder @ 2005-04-26 13:36 UTC (permalink / raw)
  To: pasky, git
In-Reply-To: <20050426032422.GQ13467@pasky.ji.cz>

> [...] build and install it, [...]

It assumes the presense of .git/HEAD but doesn't actually fail when missing.

...
gcc -g -O2 -Wall '-DSHA1_HEADER=<openssl/sha.h>' -o diff-tree-helper
diff-tree-helper.c libgit.a -lz -lssl
cat: .git/HEAD: No such file or directory
Invalid id: 
Generating cg-version...

Morten

^ permalink raw reply

* [PATCH GIT 0.6.3] Add an uninstall target to Makefile
From: Martin Atukunda @ 2005-04-26 13:48 UTC (permalink / raw)
  To: git

Add an uninstall target to Makefile that removes installed scripts and
programs.

Signed-off-by: Martin Atukunda <matlads@ds.co.ug>

Index: Makefile
===================================================================
--- 0a9ee5a4d947b998a7ce489242800b39f98eeee5/Makefile  (mode:100644 
sha1:2d7e4cf0464c45b7c5b169bff7e5c4e7768c13a1)
+++ uncommitted/Makefile  (mode:100644)
@@ -82,6 +82,9 @@
        install -m755 -d $(DESTDIR)$(bindir)
        install $(PROG) $(SCRIPT) $(GEN_SCRIPT) $(DESTDIR)$(bindir)
 
+uninstall:
+       cd $(DESTDIR)$(bindir) && rm $(PROG) $(SCRIPT) $(GEN_SCRIPT)
+
 clean:
        rm -f *.o mozilla-sha1/*.o $(PROG) $(GEN_SCRIPT) $(LIB_FILE)

^ permalink raw reply

* Re: [PATCH] Add archive-tree, a cpio archive creator
From: Rene Scharfe @ 2005-04-26 14:42 UTC (permalink / raw)
  To: Paul Dickson; +Cc: pasky, git
In-Reply-To: <20050425153011.34c93b38.paul@permanentmail.com>

Paul Dickson schrieb:
> Use the "newc" format.  The "odc" will generate a lot of errors on a
>  large filesystem (which I discovered this past weekend).

How is that?  I can only imagine problems with the size of individual
files inside an archive because the size field in the header is limited
to 33 bits.

In any case, I switched to the tar format.  It's more complicated but it
turned out that creating these things is still easy.  Parsing them might
be more of a challenge, but we already have tar for that. :-)

See my other mail for more on the tar creator.  I also rebased it to
core GIT because it's no helper script.

Rene

^ permalink raw reply

* [PATCH] GIT: Create tar archives of tree on the fly
From: Rene Scharfe @ 2005-04-26 14:42 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git

This patch introduces tar-tree, a tool to generate tar archives out of
git repositories.  Basically I took ls-tree and cat-file and melted them
together.  That means tar-tree doesn't create any temporary files, it
just streams out the archive as it goes.

This could be useful for the web interface(s) to provide a downloadable
tarball for any commit or tree object.  For bigger repositories like the
Linux kernel caching the resulting files might be a good idea,
though. :-P

On my machine it's also a bit faster than directly tarring up the
checked out files.  I only ran a few basic checks to make sure the
performance is in the same ballpark, YMMV.

Example usage:

  $ tar-tree a2755a80f40e5794ddc20e00f781af9d6320fafb linux-2.6.12-rc3 |
        bzip2 -9 > linux-2.6.12-rc3.tar.bz2

tar-tree accepts tree IDs and commit IDs.  In the former case all files
within the archive get the current time set as mtime.  Given a commit ID
tar-tree tries to figure out the commit date and sets mtime of all files
to that instead.

Currently the size of a file within the created archive is limited to
2^33-1.  This could be fixed easily within the archive format (with a
Pax extended header), but size is unsigned long throughout GIT, so this
would need to be fixed first.  OTOH I think putting 4GB+ files into a
GIT archive is insane anyway. :]

Path names are limited to 500 characters at the moment.  This can be
stretched if the need should arise.

Patch is against d1df5743809614241883ecad51876607cf432034.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

diff -Nur a/Makefile b/Makefile
--- a/Makefile	2005-04-26 03:26:45.000000000 +0200
+++ b/Makefile	2005-04-26 08:09:03.000000000 +0200
@@ -18,7 +18,7 @@
 	cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
 	check-files ls-tree merge-base merge-cache unpack-file git-export \
 	diff-cache convert-cache http-pull rpush rpull rev-list git-mktag \
-	diff-tree-helper
+	diff-tree-helper tar-tree
 
 all: $(PROG)
 
diff -Nur a/tar-tree.c b/tar-tree.c
--- a/tar-tree.c	1970-01-01 01:00:00.000000000 +0100
+++ b/tar-tree.c	2005-04-26 08:23:05.000000000 +0200
@@ -0,0 +1,328 @@
+#include <time.h>
+#include "cache.h"
+
+static const char *tar_tree_usage = "tar-tree <key> [basedir]";
+static const char *basedir;
+static time_t archive_time;
+
+struct path_prefix {
+	struct path_prefix *prev;
+	const char *name;
+};
+
+static unsigned long write_out(void *buf, unsigned long size)
+{
+	while (size > 0) {
+		long ret = write(1, buf, size);
+		if (ret < 0) {
+			if (errno == EAGAIN)
+				continue;
+			/* Ignore epipe */
+			if (errno == EPIPE)
+				break;
+			die("tar-tree: %s", strerror(errno));
+		} else if (!ret) {
+			die("tar-tree: disk full?");
+		}
+		size -= ret;
+		buf += ret;
+	}
+	return size;
+}
+
+static unsigned long write_block(void *buf, unsigned long size)
+{
+	unsigned long ret = write_out(buf, size);
+	if (!ret) {
+		unsigned long slack = 512 - size % 512;
+		if (slack % 512) {
+			char padding[511];
+			memset(padding, 0, slack);
+			ret = write_out(padding, slack);
+		}
+	}
+	return ret;
+}
+
+static void append_string(char **p, const char *s)
+{
+	unsigned int len = strlen(s);
+	memcpy(*p, s, len);
+	*p += len;
+}
+
+static void append_char(char **p, char c)
+{
+	**p = c;
+	*p += 1;
+}
+
+static void append_long(char **p, long n)
+{
+	int len = sprintf(*p, "%ld", n);
+	*p += len;
+}
+
+static void append_path_prefix(char **buffer, struct path_prefix *prefix)
+{
+	if (!prefix)
+		return;
+	append_path_prefix(buffer, prefix->prev);
+	append_string(buffer, prefix->name);
+	append_char(buffer, '/');
+}
+
+static unsigned int path_prefix_len(struct path_prefix *prefix)
+{
+	if (!prefix)
+		return 0;
+	return path_prefix_len(prefix->prev) + strlen(prefix->name) + 1;
+}
+
+static void append_path(char **p, int is_dir, const char *basepath,
+			struct path_prefix *prefix, const char *path)
+{
+	if (basepath) {
+		append_string(p, basepath);
+		append_char(p, '/');
+	}
+	append_path_prefix(p, prefix);
+	append_string(p, path);
+	if (is_dir)
+		append_char(p, '/');
+}
+
+static unsigned int path_len(int is_dir, const char *basepath,
+			     struct path_prefix *prefix, const char *path)
+{
+	unsigned int len = 0;
+	if (basepath)
+		len += strlen(basepath) + 1;
+	len += path_prefix_len(prefix) + strlen(path);
+	if (is_dir)
+		len++;
+	return len;
+}
+
+static void append_extended_header_prefix(char **p, const char *keyword,
+					  int valuelen)
+{
+	int reclen = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
+	if (reclen > 9)
+		reclen++;
+	if (reclen > 99)
+		reclen++;
+	if (reclen > 512)
+		die("tar-tree: extended header too big, wtf?");
+	append_long(p, reclen);
+	append_char(p, ' ');
+	append_string(p, keyword);
+	append_char(p, '=');
+}
+
+static long write_header(const char *, const char *, struct path_prefix *,
+			 const char *, unsigned int, unsigned long);
+
+static long write_extended_header(const char *headerfilename, int is_dir,
+				  const char *basepath,
+				  struct path_prefix *prefix,
+				  const char *path, unsigned int namelen)
+{
+	char records[512], *p;
+	unsigned long ret;
+
+	memset(records, 0, sizeof(records));
+	p = records;
+	append_extended_header_prefix(&p, "path", namelen);
+	append_path(&p, is_dir, basepath, prefix, path);
+	append_char(&p, '\n');
+	ret = write_header(NULL, NULL, NULL, headerfilename, 0100600,
+	                   p - records);
+	if (!ret)
+		ret = write_out(records, sizeof(records));
+	return ret;
+}
+
+static long write_header(const char *sha1, const char *basepath,
+			 struct path_prefix *prefix, const char *path,
+			 unsigned int mode, unsigned long size)
+{
+	unsigned int namelen; 
+	char *p, header[512];
+	unsigned int checksum = 0;
+	int i;
+
+	memset(header, 0, sizeof(header));
+
+	namelen = path_len(S_ISDIR(mode), basepath, prefix, path);
+	if (namelen > 500) {
+		fprintf(stderr, "tar-tree: name too log of object %s\n",
+		        sha1_to_hex(sha1));
+		return size;
+	} else if (namelen > 100) {
+		unsigned long ret;
+		char *sha1_hex = sha1_to_hex(sha1);
+		char headerfilename[51];
+
+		sprintf(header, "%s.data", sha1_hex);
+		sprintf(headerfilename, "%s.paxheader", sha1_hex);
+		ret = write_extended_header(headerfilename, S_ISDIR(mode),
+		                            basepath, prefix, path, namelen);
+		if (ret)
+			return ret;
+	} else {
+		p = header;
+		append_path(&p, S_ISDIR(mode), basepath, prefix, path);
+	}
+
+	if (S_ISDIR(mode))
+		mode |= 0755;	/* GIT doesn't store permissions of dirs */
+	sprintf(&header[100], "%07o", mode & 07777);
+
+	/* XXX: should we provide more meaningful info here? */
+	sprintf(&header[108], "%07o", 0);	/* uid */
+	sprintf(&header[116], "%07o", 0);	/* gid */
+	strncpy(&header[265], "git", 31);	/* uname */
+	strncpy(&header[297], "git", 31);	/* gname */
+
+	sprintf(&header[124], "%011lo", S_ISDIR(mode) ? 0 : size);
+	sprintf(&header[136], "%011lo", archive_time);
+
+	/* typeflag */
+	if (!sha1)
+		header[156] = 'x';	/* extended header */
+	else
+		header[156] = S_ISDIR(mode) ? '5' : '0';
+
+	strcpy(&header[257], "ustar");
+	strcpy(&header[263], "00");
+
+	printf(&header[329], "%07o", 0);	/* devmajor */
+	printf(&header[337], "%07o", 0);	/* devminor */
+
+	memset(&header[148], ' ', 8);
+	for (i = 0; i < sizeof(header); i++)
+		checksum += header[i];
+	sprintf(&header[148], "%07o", checksum & 0x1fffff);
+
+	return write_out(header, sizeof(header));
+}
+
+static unsigned long write_trailer(void)
+{
+	char block[1024];
+	memset(block, 0, sizeof(block));
+	return write_out(block, sizeof(block));
+}
+
+static void traverse_tree(void *buffer, unsigned long size,
+			  struct path_prefix *prefix)
+{
+	struct path_prefix this_prefix;
+	this_prefix.prev = prefix;
+
+	while (size) {
+		int namelen = strlen(buffer)+1;
+		void *eltbuf;
+		char elttype[20];
+		unsigned long eltsize;
+		unsigned char *sha1 = buffer + namelen;
+		char *path = strchr(buffer, ' ') + 1;
+		unsigned int mode;
+
+		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
+			die("corrupt 'tree' file");
+		buffer = sha1 + 20;
+		size -= namelen + 20;
+
+		eltbuf = read_sha1_file(sha1, elttype, &eltsize);
+		if (!eltbuf) {
+			error("cannot read %s", sha1_to_hex(sha1));
+			continue;
+		}
+		if (write_header(sha1, basedir, prefix, path, mode, eltsize))
+			exit(0);
+		if (!strcmp(elttype, "tree")) {
+			this_prefix.name = path;
+			traverse_tree(eltbuf, eltsize, &this_prefix);
+		} else if (!strcmp(elttype, "blob")) {
+			if (write_block(eltbuf, eltsize))
+				exit(0);
+		}
+		free(eltbuf);
+	}
+}
+
+time_t commit_time(const unsigned char *sha1)
+{
+	char type[20];
+	void *buffer;
+	unsigned long size;
+	time_t result = 0;
+
+	buffer = read_sha1_file(sha1, type, &size);
+	if (buffer) {
+		char *p = buffer;
+		while (size > 0) {
+			char *endp = memchr(p, '\n', size);
+			if (!endp)
+				break;
+			*endp = '\0';
+			if (endp - p > 10 && !memcmp(p, "committer ", 10)) {
+				char *nump = strrchr(p, ' ');
+				if (!nump)
+					break;
+				*nump = '\0';
+				nump = strrchr(p, ' ');
+				if (!nump)
+					break;
+				result = strtoul(nump, &endp, 10);
+				if (*endp != '\0')
+					result = 0;
+				break;
+			}
+			size -= endp - p - 1;
+			p = endp + 1;
+		}
+	}
+	free(buffer);
+	return result;
+}
+
+int main(int argc, char **argv)
+{
+	unsigned char sha1[20];
+	void *buffer;
+	unsigned long size;
+	unsigned char tree_sha1[20];
+
+	switch (argc) {
+	case 3:
+		basedir = argv[2];
+		/* FALLTHROUGH */
+	case 2:
+		if (get_sha1_hex(argv[1], sha1) < 0)
+			usage(tar_tree_usage);
+		break;
+	default:
+		usage(tar_tree_usage);
+	}
+
+	sha1_file_directory = getenv(DB_ENVIRONMENT);
+	if (!sha1_file_directory)
+		sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
+
+	buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, tree_sha1);
+	if (!buffer)
+		die("unable to read sha1 file");
+	if (memcmp(sha1, tree_sha1, 20))	/* is sha1 a commit object? */
+		archive_time = commit_time(sha1);
+	if (!archive_time)
+		archive_time = time(NULL);
+	if (basedir)
+		write_header("0", NULL, NULL, basedir, 040755, 0);
+	traverse_tree(buffer, size, NULL);
+	free(buffer);
+	write_trailer();
+	return 0;
+}

^ permalink raw reply

* Re: : Networking
From: Linus Torvalds @ 2005-04-26 14:59 UTC (permalink / raw)
  To: Andrew Morton; +Cc: David S. Miller, git
In-Reply-To: <20050426005725.6bfe6135.akpm@osdl.org>



On Tue, 26 Apr 2005, Andrew Morton wrote:
> 
> So I tried to apply my new get-mm-patches-from-git methodology on this and
> came unstuck.

Yes. You cannot just apply patches, since that will inevitably fail if 
there is any overlap. Which there quite often is.

For this to work in general, you really have to merge the different git 
trees, and generate patches from _that_.

> a) Set up the git repo
> 
> 	mkdir git26
> 	git init rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

Yes. In the long run, you really should need to do this just once, since 
if there is one thing git should be good at, it's just keeping tons of 
random collections of objects around.

The only thing you should be a bit careful about is to remember what the 
"heads" at different points were. In particular, you want to remember 
where you merged with me last was. I've started tagging my releases with 
the git tag facility (_not_ the pasky one, but I think pasky will start 
picking up on that soon enough), so finding a specific release will be 
easy, but if you ever do a non-release merge you'll just have to tag it 
yourself.

> b) Add davem's repo:
> 
> 	git addremote git-net rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
> 
> c) To generate -mm's linus.patch (patch against 2.6.12-rc3):
> 
> 	git pull origin
> 	git diff -r v2.6.12-rc3 > ../25/patches/linus.patch

You should now also remember the HEAD at this point. That's your "base" 
for any future patches, since you expect other patches to apply on top of 
that.

I think cogito remembers it in the "origin" thing, but you should check.

Save it away in (for example) .git/last-diff-head:

	cat .git/HEAD > .git/last-diff-head

> d) To generate davem's tree (patch against linus's current tree (ie: patch
>    against 2.6.12-rc3+linus.patch)):
> 
> 	git pull git-net

Yes. This should have merged the two (assuming "git pull" does what I 
think it does).

> 	MERGE_BASE=$(merge-base $(cat .git/heads/origin ) $(cat .git/heads/git-net))
> 	git diff -r $MERGE_BASE:$(cat .git/heads/git-net) > ../25/patches/git-net.patch

No. Now you ended up looking at the last common ancestor of the thing you 
merged, and you _should_ have looked at what the difference was _before_ 
the merge. 

So assuming it does remember it in "origin", you should just have done

	git diff -r $(cat .git/last-diff-head):$(cat .git/HEAD)

which basically says "diff between the tree at the time of my last diff,
and the result of the merge".

Then you just update your last-diff-head to reflect that:

	cat .git/HEAD > .git/last-diff-head

and you go on:

> e) Repeat d) for all known git trees.

Yup.

				Linus

^ permalink raw reply

* Re: Mercurial 0.3 vs git benchmarks
From: Magnus Damm @ 2005-04-26 15:09 UTC (permalink / raw)
  To: Chris Mason; +Cc: Linus Torvalds, Mike Taht, Matt Mackall, linux-kernel, git
In-Reply-To: <200504260713.26020.mason@suse.com>

On 4/26/05, Chris Mason <mason@suse.com> wrote:
> This agrees with my tests here, the time to apply patches is somewhat disk
> bound, even for the small 100 or 200 patch series.  The io should be coming
> from data=ordered, since the commits are still every 5 seconds or so.

Yes, as long as you apply the patches to disk that is. I've hacked up
a small backend tool that applies patches to files kept in memory and
uses a modifed rabin-karp search to match hunks. So you basically read
once and write once per file instead of moving data around for each
applied patch. But it needs two passes.

And no, the source code for the entire Linux kernel is not kept in
memory - you need a smart frontend to manage the file cache. Drop me a
line if you are interested.

/ magnus

^ permalink raw reply

* Re: [ANNOUNCE] Cogito-0.8 (former git-pasky, big changes!)
From: Martin Atukunda @ 2005-04-26 15:15 UTC (permalink / raw)
  To: git
In-Reply-To: <426DBF94.3010502@timesys.com>

On Tuesday 26 April 2005 07:12, Mike Taht wrote:
> >   Yes, this is a huge change. No, I don't expect any further changes of
> > similar scale. I think the new interface is significantly simpler _and_
> > cleaner than the old one.
>
> Heh. Another huge change would be moving the top level directories
> around a bit.
>
>
> bindings  COPYING  git.spec  Makefile  programs  README.reference  tests
> contrib   doc      include   po        README    src  VERSION
>
> Leaving fixing the makefiles aside as an exercise for the interested
> reader... that's:
<snip>
something like:

--- cogito-0.8.orig/Makefile	2005-04-26 06:02:01.000000000 +0300
+++ cogito-0.8/Makefile	2005-04-26 18:10:52.558786968 +0300
@@ -15,7 +15,7 @@
 # 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).
-CFLAGS=-g -O2 -Wall
+CFLAGS=-g -O2 -Wall -Isrc
 
 # Should be changed to /usr/local
 prefix=$(HOME)
@@ -25,19 +25,23 @@
 CC=gcc
 AR=ar
 
-SCRIPTS=git-merge-one-file-script git-prune-script git-pull-script 
git-tag-script
+SCRIPTS=programs/cogito/git-merge-one-file-script 
programs/cogito/git-prune-script \
+	programs/cogito/git-pull-script programs/cogito/git-tag-script
 
-PROG=   update-cache show-diff init-db write-tree read-tree commit-tree \
-	cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
-	check-files ls-tree merge-base merge-cache unpack-file git-export \
-	diff-cache convert-cache http-pull rpush rpull rev-list git-mktag \
-	diff-tree-helper
-
-SCRIPT=	commit-id tree-id parent-id cg-Xdiffdo cg-Xmergefile \
-	cg-add cg-admin-lsobj cg-cancel cg-clone cg-commit cg-diff \
-	cg-export cg-help cg-init cg-log cg-ls cg-merge cg-mkpatch \
-	cg-patch cg-pull cg-branch-add cg-branch-ls cg-rm cg-seek cg-status \
-	cg-tag cg-update cg-Xlib
+PROG=   src/update-cache src/show-diff src/init-db src/write-tree 
src/read-tree src/commit-tree \
+	src/cat-file src/fsck-cache src/checkout-cache src/diff-tree src/rev-tree 
src/show-files \
+	src/check-files src/ls-tree src/merge-base src/merge-cache src/unpack-file 
src/git-export \
+	src/diff-cache src/convert-cache src/http-pull src/rpush src/rpull 
src/rev-list src/git-mktag \
+	src/diff-tree-helper
+
+SCRIPT=	programs/cogito/commit-id programs/cogito/tree-id 
programs/cogito/parent-id programs/cogito/cg-Xdiffdo\
+	programs/cogito/cg-Xmergefile programs/cogito/cg-add 
programs/cogito/cg-admin-lsobj \
+	programs/cogito/cg-cancel programs/cogito/cg-clone programs/cogito/cg-commit 
programs/cogito/cg-diff \
+	programs/cogito/cg-export programs/cogito/cg-help programs/cogito/cg-init 
programs/cogito/cg-log \
+	programs/cogito/cg-ls programs/cogito/cg-merge programs/cogito/cg-mkpatch 
programs/cogito/cg-patch \
+	programs/cogito/cg-pull programs/cogito/cg-branch-add 
programs/cogito/cg-branch-ls \
+	programs/cogito/cg-rm programs/cogito/cg-seek programs/cogito/cg-status 
programs/cogito/cg-tag \
+	programs/cogito/cg-update programs/cogito/cg-Xlib
 
 COMMON=	read-cache.o
 
@@ -45,17 +49,17 @@
 
 VERSION= VERSION
 
-LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o
-LIB_FILE=libgit.a
-LIB_H=cache.h object.h
+LIB_OBJS=src/read-cache.o src/sha1_file.o src/usage.o src/object.o 
src/commit.o src/tree.o src/blob.o src/rsh.o
+LIB_FILE=src/libgit.a
+LIB_H=src/cache.h src/object.h src/rsh.h
 
-LIB_H += strbuf.h
-LIB_OBJS += strbuf.o
+LIB_H += src/strbuf.h
+LIB_OBJS += src/strbuf.o
 
-LIB_H += diff.h
-LIB_OBJS += diff.o
+LIB_H += src/diff.h
+LIB_OBJS += src/diff.o
 
-LIBS = -lz
+LIBS = -lz -lcurl
 
 ifdef MOZILLA_SHA1
 	SHA1_HEADER="mozilla-sha1/sha1.h"
@@ -98,8 +102,14 @@
 	install -m755 -d $(DESTDIR)$(bindir)
 	install $(PROG) $(SCRIPTS) $(SCRIPT) $(GEN_SCRIPT) $(DESTDIR)$(bindir)
 
+uninstall:
+	$(foreach file,$(SCRIPT),$(shell rm $(DESTDIR)$(bindir)/$(shell basename 
$(file))))
+	$(foreach file,$(PROG),$(shell rm $(DESTDIR)$(bindir)/$(shell basename 
$(file))))
+	$(foreach file,$(SCRIPTS),$(shell rm $(DESTDIR)$(bindir)/$(shell basename 
$(file))))
+	$(foreach file,$(GEN_SCRIPT),$(shell rm $(DESTDIR)$(bindir)/$(shell basename 
$(file))))
+
 clean:
-	rm -f *.o mozilla-sha1/*.o ppc/*.o $(PROG) $(GEN_SCRIPT) $(LIB_FILE)
+	rm -f *.o src/*.o cogito/*.o mozilla-sha1/*.o ppc/*.o $(PROG) $(GEN_SCRIPT) 
$(LIB_FILE)
 
 backup: clean
 	cd .. ; tar czvf dircache.tar.gz dir-cache

^ permalink raw reply

* Re: Mercurial 0.3 vs git benchmarks
From: Chris Mason @ 2005-04-26 15:38 UTC (permalink / raw)
  To: Magnus Damm; +Cc: Linus Torvalds, Mike Taht, Matt Mackall, linux-kernel, git
In-Reply-To: <aec7e5c305042608095731d571@mail.gmail.com>

On Tuesday 26 April 2005 11:09, Magnus Damm wrote:
> On 4/26/05, Chris Mason <mason@suse.com> wrote:
> > This agrees with my tests here, the time to apply patches is somewhat
> > disk bound, even for the small 100 or 200 patch series.  The io should be
> > coming from data=ordered, since the commits are still every 5 seconds or
> > so.
>
> Yes, as long as you apply the patches to disk that is. I've hacked up
> a small backend tool that applies patches to files kept in memory and
> uses a modifed rabin-karp search to match hunks. So you basically read
> once and write once per file instead of moving data around for each
> applied patch. But it needs two passes.
>
> And no, the source code for the entire Linux kernel is not kept in
> memory - you need a smart frontend to manage the file cache. Drop me a
> line if you are interested.

Sorry, you've lost me.  Right now the cycle goes like this:

1) patch reads patch file, reads source file, writes source file
2) update-cache reads source file, writes git file

Which of those writes are you avoiding?  We have a smart way to manage the 
cache already for the source files...the vm does pretty well.  There's 
nothing to manage for the git files.  For the apply a bunch of patches 
workload, they are write once, read never (except for the index).

-chris


^ permalink raw reply

* Re: : Networking
From: Daniel Barkalow @ 2005-04-26 15:40 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, David S. Miller, git
In-Reply-To: <Pine.LNX.4.58.0504260746320.18901@ppc970.osdl.org>

On Tue, 26 Apr 2005, Linus Torvalds wrote:

> On Tue, 26 Apr 2005, Andrew Morton wrote:
> > 
> 
> The only thing you should be a bit careful about is to remember what the 
> "heads" at different points were. In particular, you want to remember 
> where you merged with me last was. I've started tagging my releases with 
> the git tag facility (_not_ the pasky one, but I think pasky will start 
> picking up on that soon enough), so finding a specific release will be 
> easy, but if you ever do a non-release merge you'll just have to tag it 
> yourself.

Your tag system is in the "cogito-0.8" release, plus a pasky-style way of
keeping track of what tags you have in your repository.

> > d) To generate davem's tree (patch against linus's current tree (ie: patch
> >    against 2.6.12-rc3+linus.patch)):
> > 
> > 	git pull git-net
> 
> Yes. This should have merged the two (assuming "git pull" does what I 
> think it does).

I think git pull only downloads the contents of the repo and saves the new
head in a separate file. You're left to do the merge yourself, in case
what you actually wanted to do was just read the patches in the remote
repo without merging them.

You probably need a "git merge git-net" here, and things will be in the
state that Linus expects.

	-Daniel
*This .sig left intentionally blank*


^ 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