Git development
 help / color / mirror / Atom feed
* Re: [PATCH Cogito] Fix cg-log -f behavior
From: Junio C Hamano @ 2005-05-26 21:11 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Linus Torvalds, Petr Baudis, GIT Mailing List
In-Reply-To: <1117139740.12036.59.camel@pegasus>

>>>>> "MH" == Marcel Holtmann <marcel@holtmann.org> writes:

MH> Hi Junio,

>> Doesn't that still break one-tree case (i.e. [ -z $tree2 ])?

MH> I am not sure, because I never tried it. Does it use a different format?

I am not a Cogito user, but I am a bit wondering if you have
read what is around what you are modifying.

	# List all files for for the initial commit
	if [ -z $tree2 ]; then
		list_cmd="git-ls-tree $tree1"
	else
		list_cmd="git-diff-tree -r $tree1 $tree2"
	fi
	echo
	$list_cmd | while read modes type sha1s file; do

The code you changed is fed by either git-ls-tree or
git-diff-tree, depending on whether you are talking about
initial commit.  git-ls-tree gives "mode type sha1 file".

This is why I asked Linus about a slight format change for
git-ls-tree (and git-ls-files) this morning.

Currently, there are three incompatible format floating around.

  - diff-* brothers show the metadata (separated internally with
    SP), TAB, and path.  If it is a rename diff, another TAB and
    path follow them.

  - ls-tree gives everything with TAB separated.

  - ls-files gives everything with SP separated.

The suggestion I made this morning is to make ls-tree and
ls-files use SP inside metadata and TAB before path.  If we
can agree on that is the way to go, then the output from these
commands would become:

  - diff-* brothers:

    mode SP mode SP sha1 SP sha1 SP status TAB path [ TAB path ]

  - ls-tree:

    mode SP kind SP sha1 TAB path

  - ls-files --stage :

    mode SP sha1 SP stage TAB path

What this means is the above piece of code can now be rewritten
to parse with something like this, and it does not matter what
command you have upstream:

	echo
	# List all files for for the initial commit
	if [ -z $tree2 ]; then
        	git-ls-tree "$tree1"
	else
		git-diff-tree -r "$tree1" "$tree2"
	fi |
        cut -f2 |
	while read file; do
            ...

Note that the above code is totally untested.  I do not use
"cut" myself and I am writing this in my e-mail buffer.





^ permalink raw reply

* Re: git full diff output issues..
From: Linus Torvalds @ 2005-05-26 21:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Anton Altaparmakov, Git Mailing List
In-Reply-To: <7v64x5bt9n.fsf@assigned-by-dhcp.cox.net>



On Thu, 26 May 2005, Junio C Hamano wrote:
> 
> So what do you want from me at this point?  Nothing?

Yeah, I'm happy. Sorry for the false alarm.

Anyway, at this point

	git-apply --stat

is actually already useful: it's a diffstat clone. Which is perhaps not
very useful in itself, but it has the advantage of being an easy way to
check that I do the right thing there, and may well be useful also for the
git-specific extensions (ie right now it's really purely a diffstat clone,
but there's nothign that says that it couldn't show rename information etc 
too, which diffstat doesn't understand).

		Linus

^ permalink raw reply

* Re: git full diff output issues..
From: Junio C Hamano @ 2005-05-26 20:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Anton Altaparmakov, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505261316250.2307@ppc970.osdl.org>

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

LT> This means, btw, that the "git --diff" format must _not_ do

LT> 	diff --git a/file /dev/null
LT> 	deleted file mode 100644

I just checked, and both built-in and git-external-diff-script
should be safe about this issue.

So what do you want from me at this point?  Nothing?
 


^ permalink raw reply

* Re: Summary of core GIT while you are away.
From: Junio C Hamano @ 2005-05-26 20:51 UTC (permalink / raw)
  To: Kay Sievers; +Cc: Linus Torvalds, pasky, braddr, nico, david, Git Mailing List
In-Reply-To: <20050526202712.GA6024@vrfy.org>

>>>>> "KS" == Kay Sievers <kay.sievers@vrfy.org> writes:

KS> Before someone asks: kernel.org needs to wait until cogito has catched up and
KS> released a new version and it is installed on the machines.

Just from curiosity, does anybody runs (need to run) Cogito on
kernel.org machine(s)?  Or is it that gitweb depends on Cogito,
not running directly on top of Plumbing?


^ permalink raw reply

* Re: [PATCH Cogito] Fix cg-log -f behavior
From: Marcel Holtmann @ 2005-05-26 20:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Petr Baudis, GIT Mailing List
In-Reply-To: <7vk6llbv1j.fsf@assigned-by-dhcp.cox.net>

Hi Junio,

> Doesn't that still break one-tree case (i.e. [ -z $tree2 ])?

I am not sure, because I never tried it. Does it use a different format?

Regards

Marcel



^ permalink raw reply

* Re: git full diff output issues..
From: Linus Torvalds @ 2005-05-26 20:33 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.60.0505262036500.16829@hermes-1.csi.cam.ac.uk>



On Thu, 26 May 2005, Anton Altaparmakov wrote:
> 
> Given that git already has the metadata lines in the diff ("old mode", 
> "deleted file mode", etc) why not simply add another metadata line "name" 
> and what follows that is the name until an end of line character (or a NUL 
> if you want file names with embedded new lines).  You can then only emit 
> the "name" metadata line when no actual diff is present and hence the name 
> is uncertain.

Yes, that would work. 

However, I ended up just validating the name parsing by making sure that 
when I parse the "git --diff" line, I only take the name if I can see it 
being the same for both the old and the new. IOW, if I see

	diff --git a/hi b/hello

then I won't take it, but if I see

	diff --git hi there/I am/being difficult   oopsie dir/I am/being difficult

then I get "I am/being difficult" by virtue of checking the two names 
against each other.

This means, btw, that the "git --diff" format must _not_ do

	diff --git a/file /dev/null
	deleted file mode 100644

because in that case I don't trust the filename enough. Of course, this
all only happens when deleting empty files, if the file had any contents,
then I will see the unambiguos filename on the '---' line, and again be
happy.

IOW, git-apply is being pretty anal about things, but it looks like that
works out well.

			Linus

^ permalink raw reply

* Re: Summary of core GIT while you are away.
From: Kay Sievers @ 2005-05-26 20:27 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Junio C Hamano, pasky, braddr, nico, david, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505251826460.2307@ppc970.osdl.org>

On Wed, May 25, 2005 at 06:45:14PM -0700, Linus Torvalds wrote:
> 
> 
> On Thu, 26 May 2005, Kay Sievers wrote:
> >
> > On Mon, May 16, 2005 at 09:10:10AM -0700, Linus Torvalds wrote:
> > > 
> > > Then you could just do
> > > 
> > > 	git-rev-list -v --header HEAD | grep -z 'author[^\n]*Linus'
> > > 
> > > to tell it to do the "verbose" thing (only showing the header of the 
> > > commit, not the whole message), and grep for "Linus" in the author line.
> > 
> > What happened to that idea? That's not already working in some other way I
> > missed, right? The pickaxe stuff is nice and was easy to call from the cgi,
> > but searching in commit messages would be nice too.
> > If it's not going to happen in the git-binaries, I may do it just in the
> > cgi itself.
> 
> Ok, you twisted my arm. Checked in.
> 
> 	git-rev-list --header HEAD | grep -z 'author[\n]*Linus'

Nice, thanks. Here is a very first try. It searches the commit messages
and uses pickaxe to search in the file content:
  http://ehlo.org/~kay/gitweb.cgi?p=git/git.git;a=search;s=symlink

Before someone asks: kernel.org needs to wait until cogito has catched up and
released a new version and it is installed on the machines.

Kay

^ permalink raw reply

* Re: [PATCH Cogito] Fix cg-log -f behavior
From: Junio C Hamano @ 2005-05-26 20:18 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Petr Baudis, GIT Mailing List
In-Reply-To: <1117137826.12036.57.camel@pegasus>

Doesn't that still break one-tree case (i.e. [ -z $tree2 ])?



^ permalink raw reply

* [PATCH Cogito] Fix cg-log -f behavior
From: Marcel Holtmann @ 2005-05-26 20:03 UTC (permalink / raw)
  To: Petr Baudis; +Cc: GIT Mailing List

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

Hi Petr,

the attached patch fixes the wrong behavior when calling cg-log -f. The
output format of git-diff-tree has changed and so we need to adapt to
that to be able to show the file list again.

Regards

Marcel


Signed-off-by: Marcel Holtmann <marcel@holtmann.org>


[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 464 bytes --]

Index: cg-log
===================================================================
--- afc7419cdf2909781fa5dd9d57ea90738e515126/cg-log  (mode:100755)
+++ uncommitted/cg-log  (mode:100755)
@@ -78,7 +78,7 @@
 		list_cmd="git-diff-tree -r $tree1 $tree2"
 	fi
 	echo
-	$list_cmd | while read modes type sha1s file; do
+	$list_cmd | while read mode1 mode2 sha1a sha1b status file; do
 		echo -n "$sep"
 		sep=", "
 		if [ $(echo "$line$sep$file" | wc -c) -le 75 ]; then

^ permalink raw reply

* Re: git full diff output issues..
From: Anton Altaparmakov @ 2005-05-26 19:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505261223240.2307@ppc970.osdl.org>

On Thu, 26 May 2005, Linus Torvalds wrote:
> On Thu, 26 May 2005, Linus Torvalds wrote:
> > 
> > So we'd change it from
> > 
> > 	deleted file mode 100644
> > 
> > to
> > 
> > 	deleted file mode 100644 arch/um/kernel/checksum.c
> > 
> > in this case..
> 
> I just realized that this same thing is equally true of just plain mode 
> changes, where wif we don't have any content we just get
> 
> 	diff --git a/name b/name
> 	old mode xxxx
> 	new mode yyyy
> 
> so I might as well parse the diff header here (I don't want to repeat the 
> name twice for mode changes). Oh well.

Given that git already has the metadata lines in the diff ("old mode", 
"deleted file mode", etc) why not simply add another metadata line "name" 
and what follows that is the name until an end of line character (or a NUL 
if you want file names with embedded new lines).  You can then only emit 
the "name" metadata line when no actual diff is present and hence the name 
is uncertain.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net
WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/

^ permalink raw reply

* Re: git full diff output issues..
From: Junio C Hamano @ 2005-05-26 19:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505261223240.2307@ppc970.osdl.org>

I'd appreciate it if you take these two patches I sent last
night.

    * Add git-external-diff-script

    This is a demonstration of GIT_EXTERNAL_DIFF mechanism, and a
    testbed for tweaking and enhancing what the built-in diff should
    be.  This script is designed to output exactly the same output
    as the built-in diff driver produces when set as GIT_EXTERNAL_DIFF.

    * Diff updates.

    With the introduction of 'T', and the "apply-patch" Linus has
    been quietly working on without much advertisement, it started
    to make sense to emit usable information in the "diff --git"
    patch output format.  Earlier built-in diff driver punted and
    did not say anything about a symbolic link changing into a file
    or vice versa, but this version represents that as a pair of
    deletion and creation.

After that, you can experiment to flush out issues with the
current built-in using git-external-diff-script for quick
turnaround.  When you have a concrete "ok this is good" format
we can port that to C in diff.c:builtin_diff().


^ permalink raw reply

* Re: git full diff output issues..
From: Junio C Hamano @ 2005-05-26 19:36 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505261223240.2307@ppc970.osdl.org>

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

LT> On Thu, 26 May 2005, Linus Torvalds wrote:
>> 
>> So we'd change it from
>> 
>> deleted file mode 100644
>> 
>> to
>> 
>> deleted file mode 100644 arch/um/kernel/checksum.c
>> 
>> in this case..

LT> I just realized that this same thing is equally true of just plain mode 
LT> changes, where wif we don't have any content we just get

LT> 	diff --git a/name b/name
LT> 	old mode xxxx
LT> 	new mode yyyy

LT> so I might as well parse the diff header here (I don't want to repeat the 
LT> name twice for mode changes). Oh well.

So what do you want?  created and deleted would acquire path and
mode thing doesn't?  I think adding path only to "new mode" line
would be a sensible compromise, since we are interested in what
the resulting tree would look like most of the time.



^ permalink raw reply

* Re: git full diff output issues..
From: Linus Torvalds @ 2005-05-26 19:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505261214140.2307@ppc970.osdl.org>



On Thu, 26 May 2005, Linus Torvalds wrote:
> 
> So we'd change it from
> 
> 	deleted file mode 100644
> 
> to
> 
> 	deleted file mode 100644 arch/um/kernel/checksum.c
> 
> in this case..

I just realized that this same thing is equally true of just plain mode 
changes, where wif we don't have any content we just get

	diff --git a/name b/name
	old mode xxxx
	new mode yyyy

so I might as well parse the diff header here (I don't want to repeat the 
name twice for mode changes). Oh well.

		Linus

^ permalink raw reply

* git full diff output issues..
From: Linus Torvalds @ 2005-05-26 19:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List


While testing my "git-apply" thing (coming along quite nicely, thanks for
asking), I've hit a case that is nasty to parse.

This is from the 2.6.12-rc4 -> 2.6.12-rc5 patch:

	diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
	deleted file mode 100644
	diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
	new file mode 100644
	--- /dev/null
	+++ b/arch/um/kernel/initrd.c
	@@ -0,0 +1,78 @@

and the magic here is that deleted file that was empty to begin with, so 
it didn't have a patch, just a note on deletion.

Why is that nasty? Because we don't have the file _name_ in any good 
format. The filename only exists int he "diff --git" header, and that one 
has the space-parsing issue, which makes it less than optimal.

I'd suggest we enhance the "full diff" output for new and deleted files to 
match the rename output, ie we'd give the actual filename on that line 
too, to avoid any ambiguities.

So we'd change it from

	deleted file mode 100644

to

	deleted file mode 100644 arch/um/kernel/checksum.c

in this case..

Comments?

		Linus

^ permalink raw reply

* Re: [PATCH] ls-tree matching multiple paths
From: Junio C Hamano @ 2005-05-26 18:06 UTC (permalink / raw)
  To: Jason McMullan; +Cc: Linus Torvalds, git
In-Reply-To: <7vacmhdgct.fsf@assigned-by-dhcp.cox.net>

>>>>> "JCH" == Junio C Hamano <junkio@cox.net> writes:

JCH> +040000	tree	X	path2/baz
JCH> +100644	blob	X	path2/baz/b

Side note.  Linus, don't you think it would make more sense to
change the column separator befor type and SHA1 from TAB to SP?
We should keep the one before the path to TAB for easier
splitting with cut (which defaults to a TAB).  This comes from
the same reasoning as the latest diff-raw format design we did.

While we are at it, we may want to do the same to ls-files,
which does not use TAB for inter_name_termination (it uses SP
for everything).


^ permalink raw reply

* [PATCH] ls-tree matching multiple paths
From: Junio C Hamano @ 2005-05-26 17:52 UTC (permalink / raw)
  To: Jason McMullan; +Cc: Linus Torvalds, git
In-Reply-To: <1117120411.11542.16.camel@jmcmullan.timesys>

Jason, could you double check your MUA setup?  The copy I got, and
the mailing list archive MARC has, both seems to have got line
wrapped.  Here is the beginning of your message cut & pasted from
http://marc.theaimsgroup.com/?l=git&m=111712054707691&w=2

    ...
    Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>

    diff --git a/Documentation/git-ls-tree.txt
    b/Documentation/git-ls-tree.txt
    --- a/Documentation/git-ls-tree.txt
    ...

I fixed it up by hand and added a test case, which your test passes
fine.  Again, thanks for doing this.

------------
From: Jason McMullan <jason.mcmullan@timesys.com>

Enhance git-ls-tree to allow optional 'match paths' that
restricts the output of git-ls-tree.  This is useful to retrieve
a single file's SHA1 out of a tree without creating an index.

[JC: I added the test case]

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

Documentation/git-ls-tree.txt |    7 +-
ls-tree.c                     |  135 ++++++++++++++++++++++++++++++++++++------
t/t3100-ls-tree-restrict.sh   |  103 ++++++++++++++++++++++++++++++++
3 files changed, 227 insertions(+), 18 deletions(-)
new file (100755): t/t3100-ls-tree-restrict.sh

diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -9,7 +9,7 @@ git-ls-tree - Displays a tree object in 
 
 SYNOPSIS
 --------
-'git-ls-tree' [-r] [-z] <tree-ish>
+'git-ls-tree' [-r] [-z] <tree-ish> [paths...]
 
 DESCRIPTION
 -----------
@@ -27,6 +27,11 @@ OPTIONS
 -z::
 	\0 line termination on output
 
+paths::
+	Optionally, restrict the output of git-ls-tree to specific
+	paths. Directories will only list their tree blob ids.
+	Implies -r.
+
 Output Format
 -------------
         <mode>\t	<type>\t	<object>\t	<file>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -13,20 +13,79 @@ struct path_prefix {
 	const char *name;
 };
 
+#define DEBUG(fmt, ...)	
+
+static int string_path_prefix(char *buff, size_t blen, struct path_prefix *prefix)
+{
+	int len = 0;
+	if (prefix) {
+		if (prefix->prev) {
+			len = string_path_prefix(buff,blen,prefix->prev);
+			buff += len;
+			blen -= len;
+			if (blen > 0) {
+				*buff = '/';
+				len++;
+				buff++;
+				blen--;
+			}
+		}
+		strncpy(buff,prefix->name,blen);
+		return len + strlen(prefix->name);
+	}
+
+	return 0;
+}
+
 static void print_path_prefix(struct path_prefix *prefix)
 {
 	if (prefix) {
-		if (prefix->prev)
+		if (prefix->prev) {
 			print_path_prefix(prefix->prev);
+			putchar('/');
+		}
 		fputs(prefix->name, stdout);
-		putchar('/');
 	}
 }
 
+/*
+ * return:
+ * 	-1 if prefix is *not* a subset of path
+ * 	 0 if prefix == path
+ * 	 1 if prefix is a subset of path
+ */
+static int pathcmp(const char *path, struct path_prefix *prefix)
+{
+	char buff[PATH_MAX];
+	int len,slen;
+
+	if (prefix == NULL)
+		return 1;
+
+	len = string_path_prefix(buff, sizeof buff, prefix);
+	slen = strlen(path);
+
+	if (slen < len)
+		return -1;
+
+	if (strncmp(path,buff,len) == 0) {
+		if (slen == len)
+			return 0;
+		else
+			return 1;
+	}
+
+	return -1;
+}	
+
+/*
+ * match may be NULL, or a *sorted* list of paths
+ */
 static void list_recursive(void *buffer,
 			   const char *type,
 			   unsigned long size,
-			   struct path_prefix *prefix)
+			   struct path_prefix *prefix,
+			   char **match, int matches)
 {
 	struct path_prefix this_prefix;
 	this_prefix.prev = prefix;
@@ -34,54 +93,96 @@ static void list_recursive(void *buffer,
 	if (strcmp(type, "tree"))
 		die("expected a 'tree' node");
 
+	if (matches)
+		recursive = 1;
+
 	while (size) {
 		int namelen = strlen(buffer)+1;
-		void *eltbuf;
+		void *eltbuf = NULL;
 		char elttype[20];
 		unsigned long eltsize;
 		unsigned char *sha1 = buffer + namelen;
 		char *path = strchr(buffer, ' ') + 1;
 		unsigned int mode;
+		const char *matched = NULL;
+		int mtype = -1;
+		int mindex;
 
 		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
 			die("corrupt 'tree' file");
 		buffer = sha1 + 20;
 		size -= namelen + 20;
 
-		printf("%06o\t%s\t%s\t", mode,
-		       S_ISDIR(mode) ? "tree" : "blob",
-		       sha1_to_hex(sha1));
-		print_path_prefix(prefix);
-		fputs(path, stdout);
-		putchar(line_termination);
+		this_prefix.name = path;
+		for ( mindex = 0; mindex < matches; mindex++) {
+			mtype = pathcmp(match[mindex],&this_prefix);
+			if (mtype >= 0) {
+				matched = match[mindex];
+				break;
+			}
+		}
+
+		/*
+		 * If we're not matching, or if this is an exact match,
+		 * print out the info
+		 */
+		if (!matches || (matched != NULL && mtype == 0)) {
+			printf("%06o\t%s\t%s\t", mode,
+			       S_ISDIR(mode) ? "tree" : "blob",
+			       sha1_to_hex(sha1));
+			print_path_prefix(&this_prefix);
+			putchar(line_termination);
+		}
 
 		if (! recursive || ! S_ISDIR(mode))
 			continue;
 
+		if (matches && ! matched)
+			continue;
+
 		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
 			error("cannot read %s", sha1_to_hex(sha1));
 			continue;
 		}
-		this_prefix.name = path;
-		list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+
+		/* If this is an exact directory match, we may have
+		 * directory files following this path. Match on them.
+		 * Otherwise, we're at a pach subcomponent, and we need
+		 * to try to match again.
+		 */
+		if (mtype == 0)
+			mindex++;
+
+		list_recursive(eltbuf, elttype, eltsize, &this_prefix, &match[mindex], matches-mindex);
 		free(eltbuf);
 	}
 }
 
-static int list(unsigned char *sha1)
+static int qcmp(const void *a, const void *b)
+{
+	return strcmp(*(char **)a, *(char **)b);
+}
+
+static int list(unsigned char *sha1,char **path)
 {
 	void *buffer;
 	unsigned long size;
+	int npaths;
+
+	for (npaths = 0; path[npaths] != NULL; npaths++)
+		;
+
+	qsort(path,npaths,sizeof(char *),qcmp);
 
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buffer)
 		die("unable to read sha1 file");
-	list_recursive(buffer, "tree", size, NULL);
+	list_recursive(buffer, "tree", size, NULL, path, npaths);
 	free(buffer);
 	return 0;
 }
 
-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>";
+static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key> [paths...]";
 
 int main(int argc, char **argv)
 {
@@ -101,11 +202,11 @@ int main(int argc, char **argv)
 		argc--; argv++;
 	}
 
-	if (argc != 2)
+	if (argc < 2)
 		usage(ls_tree_usage);
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
-	if (list(sha1) < 0)
+	if (list(sha1, &argv[2]) < 0)
 		die("list failed");
 	return 0;
 }
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
new file mode 100755
--- /dev/null
+++ b/t/t3100-ls-tree-restrict.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-ls-tree test.
+
+This test runs git-ls-tree with the following in a tree.
+
+    path0       - a file
+    path1	- a symlink
+    path2/foo   - a file in a directory
+    path2/bazbo - a symlink in a directory
+    path2/baz/b - a file in a directory in a directory
+
+The new path restriction code should do the right thing for path2 and
+path2/baz
+'
+. ./test-lib.sh
+
+test_expect_success \
+    'setup' \
+    'mkdir path2 path2/baz &&
+     echo Hi >path0 &&
+     ln -s path0 path1 &&
+     echo Lo >path2/foo &&
+     ln -s ../path1 path2/bazbo &&
+     echo Mi >path2/baz/b &&
+     find path? \( -type f -o -type l \) -print |
+     xargs git-update-cache --add &&
+     tree=`git-write-tree` &&
+     echo $tree'
+
+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+test_output () {
+    sed -e "s/	$_x40	/	X	/" <current >check
+    diff -u expected check
+}
+
+test_expect_success \
+    'ls-tree plain' \
+    'git-ls-tree $tree >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+040000	tree	X	path2
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree recursive' \
+    'git-ls-tree -r $tree >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+040000	tree	X	path2
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+120000	blob	X	path2/bazbo
+100644	blob	X	path2/foo
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path >current &&
+     cat >expected <<\EOF &&
+EOF
+     test_output'
+
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path1 path0 >current &&
+     cat >expected <<\EOF &&
+100644	blob	X	path0
+120000	blob	X	path1
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2 >current &&
+     cat >expected <<\EOF &&
+040000	tree	X	path2
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+120000	blob	X	path2/bazbo
+100644	blob	X	path2/foo
+EOF
+     test_output'
+
+test_expect_success \
+    'ls-tree filtered' \
+    'git-ls-tree $tree path2/baz >current &&
+     cat >expected <<\EOF &&
+040000	tree	X	path2/baz
+100644	blob	X	path2/baz/b
+EOF
+     test_output'
+
+test_done


^ permalink raw reply

* Re: [PATCH] ls-tree matching multiple paths
From: Jason McMullan @ 2005-05-26 15:13 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <1117111843.11542.11.camel@jmcmullan.timesys>

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


Same as before, but can now match multiple paths.

Relies upon the name sorted order of the default git-ls-tree -r 
internals.

Signed-Off-By: Jason McMullan <jason.mcmullan@timesys.com>

diff --git a/Documentation/git-ls-tree.txt
b/Documentation/git-ls-tree.txt
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -9,7 +9,7 @@ git-ls-tree - Displays a tree object in 
 
 SYNOPSIS
 --------
-'git-ls-tree' [-r] [-z] <tree-ish>
+'git-ls-tree' [-r] [-z] <tree-ish> [paths...]
 
 DESCRIPTION
 -----------
@@ -27,6 +27,11 @@ OPTIONS
 -z::
 	\0 line termination on output
 
+paths::
+	Optionally, restrict the output of git-ls-tree to specific
+	paths. Directories will only list their tree blob ids.
+	Implies -r.
+
 Output Format
 -------------
         <mode>\t	<type>\t	<object>\t	<file>
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -13,20 +13,79 @@ struct path_prefix {
 	const char *name;
 };
 
+#define DEBUG(fmt, ...)	
+
+static int string_path_prefix(char *buff, size_t blen, struct
path_prefix *prefix)
+{
+	int len = 0;
+	if (prefix) {
+		if (prefix->prev) {
+			len = string_path_prefix(buff,blen,prefix->prev);
+			buff += len;
+			blen -= len;
+			if (blen > 0) {
+				*buff = '/';
+				len++;
+				buff++;
+				blen--;
+			}
+		}
+		strncpy(buff,prefix->name,blen);
+		return len + strlen(prefix->name);
+	}
+
+	return 0;
+}
+
 static void print_path_prefix(struct path_prefix *prefix)
 {
 	if (prefix) {
-		if (prefix->prev)
+		if (prefix->prev) {
 			print_path_prefix(prefix->prev);
+			putchar('/');
+		}
 		fputs(prefix->name, stdout);
-		putchar('/');
 	}
 }
 
+/*
+ * return:
+ * 	-1 if prefix is *not* a subset of path
+ * 	 0 if prefix == path
+ * 	 1 if prefix is a subset of path
+ */
+static int pathcmp(const char *path, struct path_prefix *prefix)
+{
+	char buff[PATH_MAX];
+	int len,slen;
+
+	if (prefix == NULL)
+		return 1;
+
+	len = string_path_prefix(buff, sizeof buff, prefix);
+	slen = strlen(path);
+
+	if (slen < len)
+		return -1;
+
+	if (strncmp(path,buff,len) == 0) {
+		if (slen == len)
+			return 0;
+		else
+			return 1;
+	}
+
+	return -1;
+}	
+
+/*
+ * match may be NULL, or a *sorted* list of paths
+ */
 static void list_recursive(void *buffer,
 			   const char *type,
 			   unsigned long size,
-			   struct path_prefix *prefix)
+			   struct path_prefix *prefix,
+			   char **match, int matches)
 {
 	struct path_prefix this_prefix;
 	this_prefix.prev = prefix;
@@ -34,54 +93,96 @@ static void list_recursive(void *buffer,
 	if (strcmp(type, "tree"))
 		die("expected a 'tree' node");
 
+	if (matches)
+		recursive = 1;
+
 	while (size) {
 		int namelen = strlen(buffer)+1;
-		void *eltbuf;
+		void *eltbuf = NULL;
 		char elttype[20];
 		unsigned long eltsize;
 		unsigned char *sha1 = buffer + namelen;
 		char *path = strchr(buffer, ' ') + 1;
 		unsigned int mode;
+		const char *matched = NULL;
+		int mtype = -1;
+		int mindex;
 
 		if (size < namelen + 20 || sscanf(buffer, "%o", &mode) != 1)
 			die("corrupt 'tree' file");
 		buffer = sha1 + 20;
 		size -= namelen + 20;
 
-		printf("%06o\t%s\t%s\t", mode,
-		       S_ISDIR(mode) ? "tree" : "blob",
-		       sha1_to_hex(sha1));
-		print_path_prefix(prefix);
-		fputs(path, stdout);
-		putchar(line_termination);
+		this_prefix.name = path;
+		for ( mindex = 0; mindex < matches; mindex++) {
+			mtype = pathcmp(match[mindex],&this_prefix);
+			if (mtype >= 0) {
+				matched = match[mindex];
+				break;
+			}
+		}
+
+		/*
+		 * If we're not matching, or if this is an exact match,
+		 * print out the info
+		 */
+		if (!matches || (matched != NULL && mtype == 0)) {
+			printf("%06o\t%s\t%s\t", mode,
+			       S_ISDIR(mode) ? "tree" : "blob",
+			       sha1_to_hex(sha1));
+			print_path_prefix(&this_prefix);
+			putchar(line_termination);
+		}
 
 		if (! recursive || ! S_ISDIR(mode))
 			continue;
 
+		if (matches && ! matched)
+			continue;
+
 		if (! (eltbuf = read_sha1_file(sha1, elttype, &eltsize)) ) {
 			error("cannot read %s", sha1_to_hex(sha1));
 			continue;
 		}
-		this_prefix.name = path;
-		list_recursive(eltbuf, elttype, eltsize, &this_prefix);
+
+		/* If this is an exact directory match, we may have
+		 * directory files following this path. Match on them.
+		 * Otherwise, we're at a pach subcomponent, and we need
+		 * to try to match again.
+		 */
+		if (mtype == 0)
+			mindex++;
+
+		list_recursive(eltbuf, elttype, eltsize, &this_prefix,
&match[mindex], matches-mindex);
 		free(eltbuf);
 	}
 }
 
-static int list(unsigned char *sha1)
+static int qcmp(const void *a, const void *b)
+{
+	return strcmp(*(char **)a, *(char **)b);
+}
+
+static int list(unsigned char *sha1,char **path)
 {
 	void *buffer;
 	unsigned long size;
+	int npaths;
+
+	for (npaths = 0; path[npaths] != NULL; npaths++)
+		;
+
+	qsort(path,npaths,sizeof(char *),qcmp);
 
 	buffer = read_object_with_reference(sha1, "tree", &size, NULL);
 	if (!buffer)
 		die("unable to read sha1 file");
-	list_recursive(buffer, "tree", size, NULL);
+	list_recursive(buffer, "tree", size, NULL, path, npaths);
 	free(buffer);
 	return 0;
 }
 
-static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>";
+static const char *ls_tree_usage = "git-ls-tree [-r] [-z] <key>
[paths...]";
 
 int main(int argc, char **argv)
 {
@@ -101,11 +202,11 @@ int main(int argc, char **argv)
 		argc--; argv++;
 	}
 
-	if (argc != 2)
+	if (argc < 2)
 		usage(ls_tree_usage);
 	if (get_sha1(argv[1], sha1) < 0)
 		usage(ls_tree_usage);
-	if (list(sha1) < 0)
+	if (list(sha1, &argv[2]) < 0)
 		die("list failed");
 	return 0;
 }



-- 
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] ls-tree matching a prefix
From: McMullan, Jason @ 2005-05-26 12:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vsm0aeguo.fsf@assigned-by-dhcp.cox.net>

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

On Wed, 2005-05-25 at 21:44 -0700, Junio C Hamano wrote:
> I'd rather see the behaviour match existing commands with path
> restriction, like diff-tree, diff-cache, and diff-files.  That
> is, to take a list of paths and limit your output to those that
> match one of them.  I do not think this enhancement would
> negatively affect your stated use of getting one entry with the
> exact match.

Ok, will do.

-- 
Jason McMullan <jason.mcmullan@timesys.com>
TimeSys Corporation


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] mkdelta enhancements
From: Nicolas Pitre @ 2005-05-26 12:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vll62egoe.fsf@assigned-by-dhcp.cox.net>

On Wed, 25 May 2005, Junio C Hamano wrote:

> I have not measured and I have not studied how the current
> mkdelta does things, but if you are not doing so already it may
> make sense to keep the later one expanded in full and represent
> older ones as delta, since that would give faster access to more
> often used items (I am assuming more recent version are likely
> to be accessed more frequently, which I believe is what SCMs
> typically do.

This is precisely what is done with git-deltafy-script.

The mkdelta program doesn't know about object history.  It only enforce 
delta precedence according to the order objects are listed on the 
command line.  It's up to mkdelta users to enforce any ordering policy.


Nicolas

^ permalink raw reply

* Re: [doc]playing with git, and netdev/libata-dev trees
From: James Purser @ 2005-05-26 11:54 UTC (permalink / raw)
  To: Frank Sorenson; +Cc: git
In-Reply-To: <4295868A.5070509@tuxrocks.com>

On Thu, 2005-05-26 at 18:19, Frank Sorenson wrote:

> A tarball of git will work, but it's a big bootstrap, and will need
> periodic updating.
> 

I don't really see the problem with an initial install from a tarball.
If the tarball is a direct pull of the git.git tree .git/ and all then
all anyone has to do to keep it up to date is either grab a copy of
cogito, or set up their own git based scripts.


-- 
James Purser
http://k-sit.com


^ permalink raw reply

* [PATCH] Add git-external-diff-script
From: Junio C Hamano @ 2005-05-26  9:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

This is a demonstration of GIT_EXTERNAL_DIFF mechanism, and a
testbed for tweaking and enhancing what the built-in diff should
do.  This script is designed to output exactly the same output
as what the built-in diff driver produces when used as the
GIT_EXTERNAL_DIFF command.

I've run this and updated built-in diff on the entire history of
linux-2.6 git repository, and JG's udev.git repository which has
interesting symlink cases to make sure it is equivalent to the
built-in diff driver.

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

git-external-diff-script |   67 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+)
new file (100755): git-external-diff-script

diff --git a/git-external-diff-script b/git-external-diff-script
new file mode 100755
--- /dev/null
+++ b/git-external-diff-script
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Copyright (C) 2005 Junio C Hamano
+#
+# This script is designed to emulate what the built-in diff driver
+# does when set as GIT_EXTERNAL_SCRIPT.
+
+case "$#" in
+1)
+    echo "* Unmerged path $1"
+    exit 0 ;;
+*)
+    name1="$1" tmp1="$2" hex1="$3" mode1="$4" tmp2="$5" hex2="$6" mode2="$7"
+    case "$#" in
+    7)
+	name2="$name1" ;;
+    9)
+	name2="$8" xfrm_msg="$9" ;;
+    esac ;;	
+esac
+
+show_create () {
+    name_="$1" tmp_="$2" hex_="$3" mode_="$4"
+    echo "diff --git a/$name_ b/$name_"
+    echo "new file mode $mode_"
+    diff ${GIT_DIFF_OPTS-'-pu'} -L /dev/null -L "b/$name_" /dev/null "$tmp_"
+}
+
+show_delete () {
+    name_="$1" tmp_="$2" hex_="$3" mode_="$4"
+    echo "diff --git a/$name_ b/$name_"
+    echo "deleted file mode $mode_"
+    diff ${GIT_DIFF_OPTS-'-pu'} -L "a/$name_" -L /dev/null "$tmp_" /dev/null
+}
+
+case "$mode1" in
+120*) type1=l ;;
+100*) type1=f ;;
+.)    show_create "$name2" "$tmp2" "$hex2" "$mode2"
+      exit 0 ;;
+esac
+case "$mode2" in
+120*) type2=l ;;
+100*) type2=f ;;
+.)    show_delete "$name1" "$tmp1" "$hex1" "$mode1"
+      exit 0 ;;
+esac
+
+if test "$type1" != "$type2"
+then
+	show_delete "$name1" "$tmp1" "$hex1" "$mode1"
+	show_create "$name2" "$tmp2" "$hex2" "$mode2"
+	exit 0
+fi
+
+echo diff --git "a/$name1" "b/$name2"
+if test "$mode1" != "$mode2"
+then
+    echo "old mode $mode1"
+    echo "new mode $mode2"
+    if test "$xfrm_msg" != ""
+    then
+	echo -n $xfrm_msg
+    fi
+fi
+diff ${GIT_DIFF_OPTS-'-pu'} -L "a/$name1" -L "b/$name2" "$tmp1" "$tmp2"
+exit 0
+
------------------------------------------------


^ permalink raw reply

* [PATCH] Diff updates to express type changes
From: Junio C Hamano @ 2005-05-26  9:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List

With the introduction of type 'T' in the diff-raw output, and
the "apply-patch" program Linus has been quietly working on
without much advertisement, it started to make sense to emit
usable information in the "diff --git" patch output format as
well.  Earlier built-in diff driver punted and did not say
anything about a symbolic link changing into a file or vice
versa, but this version represents it as a pair of deletion
and creation.

It also fixes a minor problem dealing with old archive created
with ancient git.  The earlier code was reporting file mode
change between 100664 and 100644 (we shouldn't).  The linux-2.6
git tree has a good example that exposes this problem.  A good
test case is commit ce1dc02f76432a46db149241e015a4f782974623.

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

diff.c     |   45 ++++++++++++++++++++++++++++++++++++---------
diffcore.h |    6 ++++++
2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -171,8 +171,8 @@ struct diff_filespec *alloc_filespec(con
 void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
 		   unsigned short mode)
 {
-	if (mode) { /* just playing defensive */
-		spec->mode = mode;
+	if (mode) {
+		spec->mode = DIFF_FILE_CANON_MODE(mode);
 		memcpy(spec->sha1, sha1, 20);
 		spec->sha1_valid = !!memcmp(sha1, null_sha1, 20);
 	}
@@ -390,7 +390,8 @@ static void remove_tempfile_on_signal(in
  *               infile2 infile2-sha1 infile2-mode [ rename-to ]
  *
  */
-static void run_external_diff(const char *name,
+static void run_external_diff(const char *pgm,
+			      const char *name,
 			      const char *other,
 			      struct diff_filespec *one,
 			      struct diff_filespec *two,
@@ -418,7 +419,6 @@ static void run_external_diff(const char
 	if (pid < 0)
 		die("unable to fork");
 	if (!pid) {
-		const char *pgm = external_diff();
 		if (pgm) {
 			if (one && two) {
 				const char *exec_arg[10];
@@ -468,6 +468,30 @@ static void run_external_diff(const char
 	remove_tempfile();
 }
 
+static void run_diff(const char *name,
+		     const char *other,
+		     struct diff_filespec *one,
+		     struct diff_filespec *two,
+		     const char *xfrm_msg)
+{
+	const char *pgm = external_diff();
+	if (!pgm &&
+	    DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
+	    (S_IFMT & one->mode) != (S_IFMT & two->mode)) {
+		/* a filepair that changes between file and symlink
+		 * needs to be split into deletion and creation.
+		 */
+		struct diff_filespec *null = alloc_filespec(two->path);
+		run_external_diff(NULL, name, other, one, null, xfrm_msg);
+		free(null);
+		null = alloc_filespec(one->path);
+		run_external_diff(NULL, name, other, null, two, xfrm_msg);
+		free(null);
+	}
+	else
+		run_external_diff(pgm, name, other, one, two, xfrm_msg);
+}
+
 void diff_setup(int reverse_diff_)
 {
 	reverse_diff = reverse_diff_;
@@ -553,9 +577,11 @@ int diff_unmodified_pair(struct diff_fil
 	one = p->one;
 	two = p->two;
 
-	/* deletion, addition, mode change and renames are all interesting. */
+	/* deletion, addition, mode or type change
+	 * and rename are all interesting.
+	 */
 	if (DIFF_FILE_VALID(one) != DIFF_FILE_VALID(two) ||
-	    (one->mode != two->mode) ||
+	    DIFF_PAIR_MODE_CHANGED(p) ||
 	    strcmp(one->path, two->path))
 		return 0;
 
@@ -608,9 +634,9 @@ static void diff_flush_patch(struct diff
 	}
 
 	if (DIFF_PAIR_UNMERGED(p))
-		run_external_diff(name, NULL, NULL, NULL, NULL);
+		run_diff(name, NULL, NULL, NULL, NULL);
 	else
-		run_external_diff(name, other, p->one, p->two, msg);
+		run_diff(name, other, p->one, p->two, msg);
 }
 
 int diff_needs_to_stay(struct diff_queue_struct *q, int i,
@@ -775,7 +801,8 @@ void diff_flush(int diff_output_style, i
 
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filepair *p = q->queue[i];
-		if (p->status == 'X')
+		if ((diff_output_style == DIFF_FORMAT_NO_OUTPUT) ||
+		    (p->status == 'X'))
 			continue;
 		if (p->status == 0)
 			die("internal error in diff-resolve-rename-copy");
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -48,6 +48,12 @@ struct diff_filepair {
 #define DIFF_PAIR_TYPE_CHANGED(p) \
 	((S_IFMT & (p)->one->mode) != (S_IFMT & (p)->two->mode))
 
+#define DIFF_PAIR_MODE_CHANGED(p) ((p)->one->mode != (p)->two->mode)
+
+#define DIFF_FILE_CANON_MODE(mode) \
+	(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
+	S_ISLNK(mode) ? S_IFLNK : S_IFDIR)
+
 extern int diff_unmodified_pair(struct diff_filepair *);
 
 struct diff_queue_struct {
------------------------------------------------


^ permalink raw reply

* Re: git-update-cache: allow dot-files
From: Junio C Hamano @ 2005-05-26  9:02 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Linus Torvalds, git
In-Reply-To: <20050526083745.GD22262@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

PB> That doesn't make any sense. When I'm working on kernel.org, why
PB> would you prohibit me to set GIT_DIR to /pub/scm/cogito/cogito.git ?

What you say makes perfect sense, but avoiding hardcoded ".git/"
does not make any sense either in that situation.  

Alternative suggestions welcome.


^ permalink raw reply

* Re: git-update-cache: allow dot-files
From: Petr Baudis @ 2005-05-26  8:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7v3bscrtwx.fsf@assigned-by-dhcp.cox.net>

Dear diary, on Wed, May 25, 2005 at 03:11:42AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> >>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:
> 
> LT> Heh. There's a difference between being anal, and allowing people to shoot 
> LT> themselves in the foot.
> 
> How about we do something like this:
> 
>  (1) we keep hardcoded .git refusing as you did;
>  (2) we forbid GIT_DIR to be set to anything other than what
>      ends with "/.git", unless it is literally ".git";

That doesn't make any sense. When I'm working on kernel.org, why
would you prohibit me to set GIT_DIR to /pub/scm/cogito/cogito.git ?

-- 
				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: seek request
From: Petr Baudis @ 2005-05-26  8:29 UTC (permalink / raw)
  To: Zack Brown; +Cc: Git Mailing List
In-Reply-To: <20050522071106.GA8060@tumblerings.org>

Dear diary, on Sun, May 22, 2005 at 09:11:06AM CEST, I got a letter
where Zack Brown <zbrown@tumblerings.org> told me that...
> Hi folks,
> 
> In Cogito, it would be nice to have a
> 
> cg-seek +
> 
> that would seek to the next archive state. This way, I could start off seeking
> back to the beginning of an archive, and quickly step forward, looking at files
> as I went, to the present.
> 
> A corresponding
> cg-seek -
> would go the reverse direction, back toward the beginning of a project.
> 
> I'm not sure how useful this would be for actual source code - I suspect any
> benefit would be minimal - but the benefit for documentation and text files,
> where the only way to test improvements is to read them by eye, would be
> significant.

Well, and what if the commit has multiple parents? Or - even much more
interestingly - multiple children?

If we keep applying the first parent rule, we could just traverse the
graph from heads/master to HEAD following this rule, and then just take
a step back to where we came from for cg-seek +. It wouldn't be exactly
cheap, but it'd probably work.

Patch welcomed. ;-)

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

^ 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