Git development
 help / color / mirror / Atom feed
* Re: ALSA official git repository
From: Andrew Morton @ 2005-05-27 22:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: perex, linux-kernel, git
In-Reply-To: <Pine.LNX.4.58.0505271502240.17402@ppc970.osdl.org>

Linus Torvalds <torvalds@osdl.org> wrote:
>
> > which means that the algorithm for identifying the author is "the final
> > From:".
> 
> No, the algorithm is:
>  - the email author, _or_ if there is one, the top "From:" in the body.

That all assumes that the tools are smart enough to separate the email
headers from the body :(


^ permalink raw reply

* [PATCH 01/12] Fix math thinko in similarity estimator.
From: Junio C Hamano @ 2005-05-27 22:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

The math to reject delta that is too big was confused.

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

diffcore-rename.c |    2 +-
1 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -163,7 +163,7 @@ static int estimate_similarity(struct di
 	/* A delta that has a lot of literal additions would have
 	 * big delta_size no matter what else it does.
 	 */
-	if (minimum_score < MAX_SCORE * delta_size / base_size)
+	if (base_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
 		return 0;
 
 	/* Estimate the edit size by interpreting delta. */
------------------------------------------------


^ permalink raw reply

* [PATCH 02/12] Introduce diff_free_filepair() funcion.
From: Junio C Hamano @ 2005-05-27 22:50 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This introduces a new function to free a common data structure,
and plugs some leaks.

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

diff.c              |   15 +++++++++------
diffcore-pathspec.c |    2 +-
diffcore-pickaxe.c  |    2 +-
diffcore-rename.c   |    7 ++-----
diffcore.h          |    2 ++
5 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -521,6 +521,13 @@ struct diff_filepair *diff_queue(struct 
 	return dp;
 }
 
+void diff_free_filepair(struct diff_filepair *p)
+{
+	diff_free_filespec_data(p->one);
+	diff_free_filespec_data(p->two);
+	free(p);
+}
+
 static void diff_flush_raw(struct diff_filepair *p,
 			   int line_termination,
 			   int inter_name_termination)
@@ -817,12 +824,8 @@ void diff_flush(int diff_output_style, i
 			break;
 		}
 	}
-	for (i = 0; i < q->nr; i++) {
-		struct diff_filepair *p = q->queue[i];
-		diff_free_filespec_data(p->one);
-		diff_free_filespec_data(p->two);
-		free(p);
-	}
+	for (i = 0; i < q->nr; i++)
+		diff_free_filepair(q->queue[i]);
 	free(q->queue);
 	q->queue = NULL;
 	q->nr = q->alloc = 0;
diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c
--- a/diffcore-pathspec.c
+++ b/diffcore-pathspec.c
@@ -59,7 +59,7 @@ void diffcore_pathspec(const char **path
 		    matches_pathspec(p->two->path, spec, speccnt))
 			diff_q(&outq, p);
 		else
-			free(p);
+			diff_free_filepair(p);
 	}
 	free(q->queue);
 	*q = outq;
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -49,7 +49,7 @@ void diffcore_pickaxe(const char *needle
 			 contains(p->two, needle, len))
 			diff_q(&outq, p);
 		if (onum == outq.nr)
-			free(p);
+			diff_free_filepair(p);
 	}
 	free(q->queue);
 	*q = outq;
diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -361,11 +361,8 @@ void diffcore_rename(int detect_rename, 
 			else
 				pair_to_free = p;
 		}
-		if (pair_to_free) {
-			diff_free_filespec_data(pair_to_free->one);
-			diff_free_filespec_data(pair_to_free->two);
-			free(pair_to_free);
-		}
+		if (pair_to_free)
+			diff_free_filepair(pair_to_free);
 	}
 	diff_debug_queue("done copying original", &outq);
 
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -54,6 +54,8 @@ struct diff_filepair {
 	(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
 	S_ISLNK(mode) ? S_IFLNK : S_IFDIR)
 
+extern void diff_free_filepair(struct diff_filepair *);
+
 extern int diff_unmodified_pair(struct diff_filepair *);
 
 struct diff_queue_struct {
------------------------------------------------


^ permalink raw reply

* [PATCH 03/12] Make pathspec only care about the detination tree.
From: Junio C Hamano @ 2005-05-27 22:51 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

Earlier it had a misguided attempt to include paths that matches
either source tree or destination tree after the rename/copy
detection.  The new semantics will be that pathspec defines a
narrowed down world the diffcore operates in, so it should not
even look at where in the source tree the path came from.

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

diffcore-pathspec.c |    3 +--
1 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c
--- a/diffcore-pathspec.c
+++ b/diffcore-pathspec.c
@@ -55,8 +55,7 @@ void diffcore_pathspec(const char **path
 
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filepair *p = q->queue[i];
-		if (matches_pathspec(p->one->path, spec, speccnt) ||
-		    matches_pathspec(p->two->path, spec, speccnt))
+		if (matches_pathspec(p->two->path, spec, speccnt))
 			diff_q(&outq, p);
 		else
 			diff_free_filepair(p);
------------------------------------------------


^ permalink raw reply

* [PATCH 04/12] Remove unused rank field from diff_core structure.
From: Junio C Hamano @ 2005-05-27 22:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This removes a field that is no longer used from diff_score
structure.

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

diffcore-rename.c |    1 -
1 files changed, 1 deletion(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -113,7 +113,6 @@ struct diff_score {
 	int src; /* index in rename_src */
 	int dst; /* index in rename_dst */
 	int score;
-	int rank;
 };
 
 static int estimate_similarity(struct diff_filespec *src,
------------------------------------------------


^ permalink raw reply

* [PATCH 05/12] Do not expose internal scaling to diff-helper.
From: Junio C Hamano @ 2005-05-27 22:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

Instead we can normalize what diff-raw records at the diffcore
side.

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

diff-helper.c |    2 --
diff.c        |    2 +-
2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/diff-helper.c b/diff-helper.c
--- a/diff-helper.c
+++ b/diff-helper.c
@@ -4,7 +4,6 @@
 #include "cache.h"
 #include "strbuf.h"
 #include "diff.h"
-#include "diffcore.h" /* just for MAX_SCORE */
 
 static const char *pickaxe = NULL;
 static int line_termination = '\n';
@@ -78,7 +77,6 @@ int main(int ac, const char **av) {
 			if (status == 'R' || status == 'C') {
 				two_paths = 1;
 				sscanf(cp, "%d", &score);
-				score = score * MAX_SCORE / 100;
 				if (line_termination) {
 					cp = strchr(cp,
 						    inter_name_termination);
diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -886,7 +886,7 @@ void diff_helper_input(unsigned old_mode
 	if (new_mode)
 		fill_filespec(two, new_sha1, new_mode);
 	dp = diff_queue(&diff_queued_diff, one, two);
-	dp->score = score;
+	dp->score = score * MAX_SCORE / 100;
 	dp->status = status;
 }
 
------------------------------------------------


^ permalink raw reply

* [PATCH 06/12] Remove final newline from the value of xfrm_msg variable.
From: Junio C Hamano @ 2005-05-27 22:54 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This change makes the implementation of git-external-diff-script
cleaner.

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

diff.c                   |    6 +++---
git-external-diff-script |    2 +-
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -141,7 +141,7 @@ static void builtin_diff(const char *nam
 			printf("new mode %s\n", temp[1].mode);
 		}
 		if (xfrm_msg && xfrm_msg[0])
-			fputs(xfrm_msg, stdout);
+			puts(xfrm_msg);
 
 		if (strncmp(temp[0].mode, temp[1].mode, 3))
 			/* we do not run diff between different kind
@@ -622,7 +622,7 @@ static void diff_flush_patch(struct diff
 		sprintf(msg_,
 			"similarity index %d%%\n"
 			"copy from %s\n"
-			"copy to %s\n",
+			"copy to %s",
 			(int)(0.5 + p->score * 100.0/MAX_SCORE),
 			p->one->path, p->two->path);
 		msg = msg_;
@@ -631,7 +631,7 @@ static void diff_flush_patch(struct diff
 		sprintf(msg_,
 			"similarity index %d%%\n"
 			"rename old %s\n"
-			"rename new %s\n",
+			"rename new %s",
 			(int)(0.5 + p->score * 100.0/MAX_SCORE),
 			p->one->path, p->two->path);
 		msg = msg_;
diff --git a/git-external-diff-script b/git-external-diff-script
--- a/git-external-diff-script
+++ b/git-external-diff-script
@@ -59,7 +59,7 @@ then
     echo "new mode $mode2"
     if test "$xfrm_msg" != ""
     then
-	echo -n $xfrm_msg
+	echo "$xfrm_msg"
     fi
 fi
 diff ${GIT_DIFF_OPTS-'-pu'} -L "a/$name1" -L "b/$name2" "$tmp1" "$tmp2"
------------------------------------------------


^ permalink raw reply

* [PATCH 07/12] Clean up diff_setup() to make it more extensible.
From: Junio C Hamano @ 2005-05-27 22:54 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This changes the argument of diff_setup() from an integer that
says if we are feeding reversed diff to a bitmask, so that later
global options can be added more easily.

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

diff-cache.c |    6 +++---
diff-files.c |    6 +++---
diff-tree.c  |    6 +++---
diff.c       |    5 +++--
diff.h       |   12 +++++++-----
5 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/diff-cache.c b/diff-cache.c
--- a/diff-cache.c
+++ b/diff-cache.c
@@ -5,7 +5,7 @@ static int cached_only = 0;
 static int diff_output_format = DIFF_FORMAT_HUMAN;
 static int match_nonexisting = 0;
 static int detect_rename = 0;
-static int reverse_diff = 0;
+static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
 
@@ -202,7 +202,7 @@ int main(int argc, const char **argv)
 			continue;
 		}
 		if (!strcmp(arg, "-R")) {
-			reverse_diff = 1;
+			diff_setup_opt |= DIFF_SETUP_REVERSE;
 			continue;
 		}
 		if (!strcmp(arg, "-S")) {
@@ -224,7 +224,7 @@ int main(int argc, const char **argv)
 		usage(diff_cache_usage);
 
 	/* The rest is for paths restriction. */
-	diff_setup(reverse_diff);
+	diff_setup(diff_setup_opt);
 
 	mark_merge_entries();
 
diff --git a/diff-files.c b/diff-files.c
--- a/diff-files.c
+++ b/diff-files.c
@@ -11,7 +11,7 @@ static const char *diff_files_usage =
 
 static int diff_output_format = DIFF_FORMAT_HUMAN;
 static int detect_rename = 0;
-static int reverse_diff = 0;
+static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
 static int silent = 0;
@@ -51,7 +51,7 @@ int main(int argc, const char **argv)
 		else if (!strcmp(argv[1], "-z"))
 			diff_output_format = DIFF_FORMAT_MACHINE;
 		else if (!strcmp(argv[1], "-R"))
-			reverse_diff = 1;
+			diff_setup_opt |= DIFF_SETUP_REVERSE;
 		else if (!strcmp(argv[1], "-S"))
 			pickaxe = argv[1] + 2;
 		else if (!strncmp(argv[1], "-M", 2)) {
@@ -75,7 +75,7 @@ int main(int argc, const char **argv)
 		exit(1);
 	}
 
-	diff_setup(reverse_diff);
+	diff_setup(diff_setup_opt);
 
 	for (i = 0; i < entries; i++) {
 		struct stat st;
diff --git a/diff-tree.c b/diff-tree.c
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -10,7 +10,7 @@ static int show_tree_entry_in_recursive 
 static int read_stdin = 0;
 static int diff_output_format = DIFF_FORMAT_HUMAN;
 static int detect_rename = 0;
-static int reverse_diff = 0;
+static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
 static const char *header = NULL;
@@ -255,7 +255,7 @@ static int diff_tree_sha1(const unsigned
 
 static void call_diff_setup(void)
 {
-	diff_setup(reverse_diff);
+	diff_setup(diff_setup_opt);
 }
 
 static int call_diff_flush(void)
@@ -497,7 +497,7 @@ int main(int argc, const char **argv)
 			continue;
 		}
 		if (!strcmp(arg, "-R")) {
-			reverse_diff = 1;
+			diff_setup_opt |= DIFF_SETUP_REVERSE;
 			continue;
 		}
 		if (!strcmp(arg, "-p")) {
diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -492,9 +492,10 @@ static void run_diff(const char *name,
 		run_external_diff(pgm, name, other, one, two, xfrm_msg);
 }
 
-void diff_setup(int reverse_diff_)
+void diff_setup(int flags)
 {
-	reverse_diff = reverse_diff_;
+	if (flags & DIFF_SETUP_REVERSE)
+		reverse_diff = 1;
 }
 
 struct diff_queue_struct diff_queued_diff;
diff --git a/diff.h b/diff.h
--- a/diff.h
+++ b/diff.h
@@ -28,11 +28,8 @@ extern void diff_unmerge(const char *pat
 
 extern int diff_scoreopt_parse(const char *opt);
 
-#define DIFF_FORMAT_HUMAN	0
-#define DIFF_FORMAT_MACHINE	1
-#define DIFF_FORMAT_PATCH	2
-#define DIFF_FORMAT_NO_OUTPUT	3
-extern void diff_setup(int reverse);
+#define DIFF_SETUP_REVERSE      	1
+extern void diff_setup(int flags);
 
 #define DIFF_DETECT_RENAME	1
 #define DIFF_DETECT_COPY	2
@@ -44,6 +41,11 @@ extern void diffcore_pathspec(const char
 
 extern int diff_queue_is_empty(void);
 
+#define DIFF_FORMAT_HUMAN	0
+#define DIFF_FORMAT_MACHINE	1
+#define DIFF_FORMAT_PATCH	2
+#define DIFF_FORMAT_NO_OUTPUT	3
+
 extern void diff_flush(int output_style, int resolve_rename_copy);
 
 #endif /* DIFF_H */
------------------------------------------------


^ permalink raw reply

* [PATCH 08/12] Remove a function not used anymore.
From: Junio C Hamano @ 2005-05-27 22:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

Earlier rename/copy detection left unmodified filepair in the
output and forced downstream to keep them even when they are
filtering, and the diff_needs_to_stay() function was used for
the logic.  It is not used anymore, so remove it.

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

diff.c     |   22 ----------------------
diffcore.h |    3 ---
2 files changed, 25 deletions(-)

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -647,28 +647,6 @@ static void diff_flush_patch(struct diff
 		run_diff(name, other, p->one, p->two, msg);
 }
 
-int diff_needs_to_stay(struct diff_queue_struct *q, int i,
-		       struct diff_filespec *it)
-{
-	/* If it will be used in later entry (either stay or used
-	 * as the source of rename/copy), we need to copy, not rename.
-	 */
-	while (i < q->nr) {
-		struct diff_filepair *p = q->queue[i++];
-		if (!DIFF_FILE_VALID(p->two))
-			continue; /* removed is fine */
-		if (strcmp(p->one->path, it->path))
-			continue; /* not relevant */
-
-		/* p has its src set to *it and it is not a delete;
-		 * it will be used for in-place change, rename/copy,
-		 * or just stays there.  We cannot rename it out.
-		 */
-		return 1;
-	}
-	return 0;
-}
-
 int diff_queue_is_empty(void)
 {
 	struct diff_queue_struct *q = &diff_queued_diff;
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -70,9 +70,6 @@ extern struct diff_filepair *diff_queue(
 					struct diff_filespec *);
 extern void diff_q(struct diff_queue_struct *, struct diff_filepair *);
 
-extern int diff_needs_to_stay(struct diff_queue_struct *, int,
-			      struct diff_filespec *);
-
 #define DIFF_DEBUG 0
 #if DIFF_DEBUG
 void diff_debug_filespec(struct diff_filespec *, int, const char *);
------------------------------------------------


^ permalink raw reply

* [PATCH 09/12] Add --pickaxe-all to diff-* brothers.
From: Junio C Hamano @ 2005-05-27 22:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

When --pickaxe-all is given in addition to -S, pickaxe shows the
entire diffs contained in the changeset, not just the diffs for
the filepair that touched the sought-after string.  This is
useful to see the changes in context.

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

diff-cache.c       |    7 ++++
diff-files.c       |    5 ++-
diff-helper.c      |    7 +++-
diff-tree.c        |    7 ++++
diff.h             |    4 ++
diffcore-pickaxe.c |   77 +++++++++++++++++++++++++++++++++++++++--------------
6 files changed, 81 insertions(+), 26 deletions(-)

diff --git a/diff-cache.c b/diff-cache.c
--- a/diff-cache.c
+++ b/diff-cache.c
@@ -8,6 +8,7 @@ static int detect_rename = 0;
 static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
+static int pickaxe_opts = 0;
 
 /* A file entry went away or appeared */
 static void show_file(const char *prefix, struct cache_entry *ce, unsigned char *sha1, unsigned int mode)
@@ -209,6 +210,10 @@ int main(int argc, const char **argv)
 			pickaxe = arg + 2;
 			continue;
 		}
+		if (!strcmp(arg, "--pickaxe-all")) {
+			pickaxe_opts = DIFF_PICKAXE_ALL;
+			continue;
+		}
 		if (!strcmp(arg, "-m")) {
 			match_nonexisting = 1;
 			continue;
@@ -238,7 +243,7 @@ int main(int argc, const char **argv)
 	if (detect_rename)
 		diffcore_rename(detect_rename, diff_score_opt);
 	if (pickaxe)
-		diffcore_pickaxe(pickaxe);
+		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	if (pathspec)
 		diffcore_pathspec(pathspec);
 	diff_flush(diff_output_format, 1);
diff --git a/diff-files.c b/diff-files.c
--- a/diff-files.c
+++ b/diff-files.c
@@ -14,6 +14,7 @@ static int detect_rename = 0;
 static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
+static int pickaxe_opts = 0;
 static int silent = 0;
 
 static void show_unmerge(const char *path)
@@ -54,6 +55,8 @@ int main(int argc, const char **argv)
 			diff_setup_opt |= DIFF_SETUP_REVERSE;
 		else if (!strcmp(argv[1], "-S"))
 			pickaxe = argv[1] + 2;
+		else if (!strcmp(argv[1], "--pickaxe-all"))
+			pickaxe_opts = DIFF_PICKAXE_ALL;
 		else if (!strncmp(argv[1], "-M", 2)) {
 			diff_score_opt = diff_scoreopt_parse(argv[1]);
 			detect_rename = DIFF_DETECT_RENAME;
@@ -116,7 +119,7 @@ int main(int argc, const char **argv)
 	if (detect_rename)
 		diffcore_rename(detect_rename, diff_score_opt);
 	if (pickaxe)
-		diffcore_pickaxe(pickaxe);
+		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	if (1 < argc)
 		diffcore_pathspec(argv + 1);
 	diff_flush(diff_output_format, 1);
diff --git a/diff-helper.c b/diff-helper.c
--- a/diff-helper.c
+++ b/diff-helper.c
@@ -6,6 +6,7 @@
 #include "diff.h"
 
 static const char *pickaxe = NULL;
+static int pickaxe_opts = 0;
 static int line_termination = '\n';
 static int inter_name_termination = '\t';
 
@@ -23,6 +24,8 @@ int main(int ac, const char **av) {
 		else if (av[1][1] == 'S') {
 			pickaxe = av[1] + 2;
 		}
+		else if (!strcmp(av[1], "--pickaxe-all"))
+			pickaxe_opts = DIFF_PICKAXE_ALL;
 		else
 			usage(diff_helper_usage);
 		ac--; av++;
@@ -127,14 +130,14 @@ int main(int ac, const char **av) {
 			continue;
 		}
 		if (pickaxe)
-			diffcore_pickaxe(pickaxe);
+			diffcore_pickaxe(pickaxe, pickaxe_opts);
 		if (1 < ac)
 			diffcore_pathspec(av + 1);
 		diff_flush(DIFF_FORMAT_PATCH, 0);
 		printf("%s\n", sb.buf);
 	}
 	if (pickaxe)
-		diffcore_pickaxe(pickaxe);
+		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	if (1 < ac)
 		diffcore_pathspec(av + 1);
 	diff_flush(DIFF_FORMAT_PATCH, 0);
diff --git a/diff-tree.c b/diff-tree.c
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -13,6 +13,7 @@ static int detect_rename = 0;
 static int diff_setup_opt = 0;
 static int diff_score_opt = 0;
 static const char *pickaxe = NULL;
+static int pickaxe_opts = 0;
 static const char *header = NULL;
 static const char *header_prefix = "";
 
@@ -263,7 +264,7 @@ static int call_diff_flush(void)
 	if (detect_rename)
 		diffcore_rename(detect_rename, diff_score_opt);
 	if (pickaxe)
-		diffcore_pickaxe(pickaxe);
+		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	if (diff_queue_is_empty()) {
 		diff_flush(DIFF_FORMAT_NO_OUTPUT, 0);
 		return 0;
@@ -509,6 +510,10 @@ int main(int argc, const char **argv)
 			pickaxe = arg + 2;
 			continue;
 		}
+		if (!strcmp(arg, "--pickaxe-all")) {
+			pickaxe_opts = DIFF_PICKAXE_ALL;
+			continue;
+		}
 		if (!strncmp(arg, "-M", 2)) {
 			detect_rename = DIFF_DETECT_RENAME;
 			diff_score_opt = diff_scoreopt_parse(arg);
diff --git a/diff.h b/diff.h
--- a/diff.h
+++ b/diff.h
@@ -36,7 +36,9 @@ extern void diff_setup(int flags);
 
 extern void diffcore_rename(int rename_copy, int minimum_score);
 
-extern void diffcore_pickaxe(const char *needle);
+#define DIFF_PICKAXE_ALL	1
+extern void diffcore_pickaxe(const char *needle, int opts);
+
 extern void diffcore_pathspec(const char **pathspec);
 
 extern int diff_queue_is_empty(void);
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -21,36 +21,73 @@ static int contains(struct diff_filespec
 	return 0;
 }
 
-void diffcore_pickaxe(const char *needle)
+void diffcore_pickaxe(const char *needle, int opts)
 {
 	struct diff_queue_struct *q = &diff_queued_diff;
 	unsigned long len = strlen(needle);
-	int i;
+	int i, has_changes;
 	struct diff_queue_struct outq;
 	outq.queue = NULL;
 	outq.nr = outq.alloc = 0;
 
-	for (i = 0; i < q->nr; i++) {
-		struct diff_filepair *p = q->queue[i];
-		int onum = outq.nr;
-		if (!DIFF_FILE_VALID(p->one)) {
-			if (!DIFF_FILE_VALID(p->two))
-				continue; /* ignore nonsense */
-			/* created */
-			if (contains(p->two, needle, len))
-				diff_q(&outq, p);
+	if (opts & DIFF_PICKAXE_ALL) {
+		/* Showing the whole changeset if needle exists */
+		for (i = has_changes = 0; !has_changes && i < q->nr; i++) {
+			struct diff_filepair *p = q->queue[i];
+			if (!DIFF_FILE_VALID(p->one)) {
+				if (!DIFF_FILE_VALID(p->two))
+					continue; /* ignore unmerged */
+				/* created */
+				if (contains(p->two, needle, len))
+					has_changes++;
+			}
+			else if (!DIFF_FILE_VALID(p->two)) {
+				if (contains(p->one, needle, len))
+					has_changes++;
+			}
+			else if (!diff_unmodified_pair(p) &&
+				 contains(p->one, needle, len) !=
+				 contains(p->two, needle, len))
+				has_changes++;
 		}
-		else if (!DIFF_FILE_VALID(p->two)) {
-			if (contains(p->one, needle, len))
+		if (has_changes)
+			return; /* not munge the queue */
+
+		/* otherwise we will clear the whole queue
+		 * by copying the empty outq at the end of this
+		 * function, but first clear the current entries
+		 * in the queue.
+		 */
+		for (i = 0; i < q->nr; i++)
+			diff_free_filepair(q->queue[i]);
+	}
+	else 
+		/* Showing only the filepairs that has the needle */
+		for (i = 0; i < q->nr; i++) {
+			struct diff_filepair *p = q->queue[i];
+			has_changes = 0;
+			if (!DIFF_FILE_VALID(p->one)) {
+				if (!DIFF_FILE_VALID(p->two))
+					; /* ignore unmerged */
+				/* created */
+				else if (contains(p->two, needle, len))
+					has_changes = 1;
+			}
+			else if (!DIFF_FILE_VALID(p->two)) {
+				if (contains(p->one, needle, len))
+					has_changes = 1;
+			}
+			else if (!diff_unmodified_pair(p) &&
+				 contains(p->one, needle, len) !=
+				 contains(p->two, needle, len))
+				has_changes = 1;
+
+			if (has_changes)
 				diff_q(&outq, p);
+			else
+				diff_free_filepair(p);
 		}
-		else if (!diff_unmodified_pair(p) &&
-			 contains(p->one, needle, len) !=
-			 contains(p->two, needle, len))
-			diff_q(&outq, p);
-		if (onum == outq.nr)
-			diff_free_filepair(p);
-	}
+
 	free(q->queue);
 	*q = outq;
 	return;
------------------------------------------------


^ permalink raw reply

* [PATCH 10/12] Fix the way diffcore-rename records unremoved source.
From: Junio C Hamano @ 2005-05-27 22:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

Earier version of diffcore-rename used to keep unmodified
filepair in its output so that the last stage of the processing
that tells renames from copies can make all of rename/copy to
copies.  However this had a bad interaction with other diffcore
filters that wanted to run after diffcore-rename, in that such
unmodified filepair must be retained for proper distinction
between renames and copies to happen.

This patch fixes the problem by changing the way diffcore-rename
records the information needed to distinguish "all are copies"
case and "the last one is a rename" case.

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

diff.c              |   76 ++++++++++++++++++--------------------
diffcore-rename.c   |   63 ++++++++++++-------------------
diffcore.h          |    7 ++-
t/t4007-rename-3.sh |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 169 insertions(+), 80 deletions(-)
new file (100644): t/t4007-rename-3.sh

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -518,6 +518,7 @@ struct diff_filepair *diff_queue(struct 
 	dp->one = one;
 	dp->two = two;
 	dp->score = 0;
+	dp->source_stays = 0;
 	diff_q(queue, dp);
 	return dp;
 }
@@ -675,8 +676,8 @@ void diff_debug_filepair(const struct di
 {
 	diff_debug_filespec(p->one, i, "one");
 	diff_debug_filespec(p->two, i, "two");
-	fprintf(stderr, "score %d, status %c\n",
-		p->score, p->status ? : '?');
+	fprintf(stderr, "score %d, status %c source_stays %d\n",
+		p->score, p->status ? : '?', p->source_stays);
 }
 
 void diff_debug_queue(const char *msg, struct diff_queue_struct *q)
@@ -698,8 +699,6 @@ static void diff_resolve_rename_copy(voi
 	struct diff_filepair *p, *pp;
 	struct diff_queue_struct *q = &diff_queued_diff;
 
-	/* This should not depend on the ordering of things. */
-
 	diff_debug_queue("resolve-rename-copy", q);
 
 	for (i = 0; i < q->nr; i++) {
@@ -707,23 +706,28 @@ static void diff_resolve_rename_copy(voi
 		p->status = 0; /* undecided */
 		if (DIFF_PAIR_UNMERGED(p))
 			p->status = 'U';
-		else if (!DIFF_FILE_VALID((p)->one))
+		else if (!DIFF_FILE_VALID(p->one))
 			p->status = 'N';
-		else if (!DIFF_FILE_VALID((p)->two)) {
-			/* Deletion record should be omitted if there
-			 * are rename/copy entries using this one as
-			 * the source.  Then we can say one of them
-			 * is a rename and the rest are copies.
+		else if (!DIFF_FILE_VALID(p->two)) {
+			/* Deleted entry may have been picked up by
+			 * another rename-copy entry.  So we scan the
+			 * queue and if we find one that uses us as the
+			 * source we do not say delete for this entry.
 			 */
-			p->status = 'D';
 			for (j = 0; j < q->nr; j++) {
 				pp = q->queue[j];
-				if (!strcmp(pp->one->path, p->one->path) &&
-				    strcmp(pp->one->path, pp->two->path)) {
+				if (!strcmp(p->one->path, pp->one->path) &&
+				    pp->score) {
+					/* rename/copy are always valid
+					 * so we do not say DIFF_FILE_VALID()
+					 * on pp->one and pp->two.
+					 */
 					p->status = 'X';
 					break;
 				}
 			}
+			if (!p->status)
+				p->status = 'D';
 		}
 		else if (DIFF_PAIR_TYPE_CHANGED(p))
 			p->status = 'T';
@@ -732,33 +736,24 @@ static void diff_resolve_rename_copy(voi
 		 * whose both sides are valid and of the same type, i.e.
 		 * either in-place edit or rename/copy edit.
 		 */
-		else if (strcmp(p->one->path, p->two->path)) {
-			/* See if there is somebody else anywhere that
-			 * will keep the path (either modified or
-			 * unmodified).  If so, we have to be a copy,
-			 * not a rename.  In addition, if there is
-			 * some other rename or copy that comes later
-			 * than us that uses the same source, we
-			 * have to be a copy, not a rename.
+		else if (p->score) {
+			if (p->source_stays) {
+				p->status = 'C';
+				continue;
+			}
+			/* See if there is some other filepair that
+			 * copies from the same source as us.  If so
+			 * we are a copy.  Otherwise we are a rename.
 			 */
-			for (j = 0; j < q->nr; j++) {
+			for (j = i + 1; j < q->nr; j++) {
 				pp = q->queue[j];
 				if (strcmp(pp->one->path, p->one->path))
-					continue;
-				if (!strcmp(pp->one->path, pp->two->path)) {
-					if (DIFF_FILE_VALID(pp->two)) {
-						/* non-delete */
-						p->status = 'C';
-						break;
-					}
-					continue;
-				}
-				/* pp is a rename/copy ... */
-				if (i < j) {
-					/* ... and comes later than us */
-					p->status = 'C';
-					break;
-				}
+					continue; /* not us */
+				if (!pp->score)
+					continue; /* not a rename/copy */
+				/* pp is a rename/copy from the same source */
+				p->status = 'C';
+				break;
 			}
 			if (!p->status)
 				p->status = 'R';
@@ -767,8 +762,11 @@ static void diff_resolve_rename_copy(voi
 			 p->one->mode != p->two->mode)
 			p->status = 'M';
 		else
-			/* this is a "no-change" entry */
-			p->status = 'X';
+			/* this is a "no-change" entry.
+			 * should not happen anymore.
+			 * p->status = 'X';
+			 */
+			die("internal error in diffcore: unmodified entry remains");
 	}
 	diff_debug_queue("resolve-rename-copy done", q);
 }
diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -52,14 +52,15 @@ static struct diff_rename_dst *locate_re
 	return &(rename_dst[first]);
 }
 
+/* Table of rename/copy src files */
 static struct diff_rename_src {
 	struct diff_filespec *one;
-	unsigned src_used : 1;
+	unsigned src_stays : 1;
 } *rename_src;
 static int rename_src_nr, rename_src_alloc;
 
-static struct diff_rename_src *locate_rename_src(struct diff_filespec *one,
-						 int insert_ok)
+static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
+						   int src_stays)
 {
 	int first, last;
 
@@ -77,9 +78,7 @@ static struct diff_rename_src *locate_re
 		}
 		first = next+1;
 	}
-	/* not found */
-	if (!insert_ok)
-		return NULL;
+
 	/* insert to make it at "first" */
 	if (rename_src_alloc <= rename_src_nr) {
 		rename_src_alloc = alloc_nr(rename_src_alloc);
@@ -91,7 +90,7 @@ static struct diff_rename_src *locate_re
 		memmove(rename_src + first + 1, rename_src + first,
 			(rename_src_nr - first - 1) * sizeof(*rename_src));
 	rename_src[first].one = one;
-	rename_src[first].src_used = 0;
+	rename_src[first].src_stays = src_stays;
 	return &(rename_src[first]);
 }
 
@@ -199,15 +198,14 @@ static void record_rename_pair(struct di
 	fill_filespec(two, dst->sha1, dst->mode);
 
 	dp = diff_queue(renq, one, two);
-	dp->score = score;
-
-	rename_src[src_index].src_used = 1;
+	dp->score = score ? : 1; /* make sure it is at least 1 */
+	dp->source_stays = rename_src[src_index].src_stays;
 	rename_dst[dst_index].pair = dp;
 }
 
 /*
  * We sort the rename similarity matrix with the score, in descending
- * order (more similar first).
+ * order (the most similar first).
  */
 static int score_compare(const void *a_, const void *b_)
 {
@@ -254,9 +252,9 @@ void diffcore_rename(int detect_rename, 
 			else
 				locate_rename_dst(p->two, 1);
 		else if (!DIFF_FILE_VALID(p->two))
-			locate_rename_src(p->one, 1);
-		else if (1 < detect_rename) /* find copy, too */
-			locate_rename_src(p->one, 1);
+			register_rename_src(p->one, 0);
+		else if (detect_rename == DIFF_DETECT_COPY)
+			register_rename_src(p->one, 1);
 	}
 	if (rename_dst_nr == 0)
 		goto cleanup; /* nothing to do */
@@ -280,7 +278,7 @@ void diffcore_rename(int detect_rename, 
 	 * doing the delta matrix altogether.
 	 */
 	if (renq.nr == rename_dst_nr)
-		goto flush_rest;
+		goto cleanup;
 
 	num_create = (rename_dst_nr - renq.nr);
 	num_src = rename_src_nr;
@@ -307,37 +305,30 @@ void diffcore_rename(int detect_rename, 
 		if (dst->pair)
 			continue; /* already done, either exact or fuzzy. */
 		if (mx[i].score < minimum_score)
-			break; /* there is not any more diffs applicable. */
+			break; /* there is no more usable pair. */
 		record_rename_pair(&renq, mx[i].dst, mx[i].src, mx[i].score);
 	}
 	free(mx);
 	diff_debug_queue("done detecting fuzzy", &renq);
 
- flush_rest:
+ cleanup:
 	/* At this point, we have found some renames and copies and they
 	 * are kept in renq.  The original list is still in *q.
-	 *
-	 * Scan the original list and move them into the outq; we will sort
-	 * outq and swap it into the queue supplied to pass that to
-	 * downstream, so we assign the sort keys in this loop.
-	 *
-	 * See comments at the top of record_rename_pair for numbers used
-	 * to assign rename_rank.
 	 */
 	outq.queue = NULL;
 	outq.nr = outq.alloc = 0;
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filepair *p = q->queue[i];
-		struct diff_rename_src *src = locate_rename_src(p->one, 0);
 		struct diff_rename_dst *dst = locate_rename_dst(p->two, 0);
 		struct diff_filepair *pair_to_free = NULL;
 
 		if (dst) {
 			/* creation */
 			if (dst->pair) {
-				/* renq has rename/copy already to produce
-				 * this file, so we do not emit the creation
-				 * record in the output.
+				/* renq has rename/copy to produce
+				 * this file already, so we do not
+				 * emit the creation record in the
+				 * output.
 				 */
 				diff_q(&outq, dst->pair);
 				pair_to_free = p;
@@ -349,17 +340,12 @@ void diffcore_rename(int detect_rename, 
 				diff_q(&outq, p);
 		}
 		else if (!diff_unmodified_pair(p))
-			/* all the other cases need to be recorded as is */
+			/* all the usual ones need to be kept */
 			diff_q(&outq, p);
-		else {
-			/* unmodified pair needs to be recorded only if
-			 * it is used as the source of rename/copy
-			 */
-			if (src && src->src_used)
-				diff_q(&outq, p);
-			else
-				pair_to_free = p;
-		}
+		else
+			/* no need to keep unmodified pairs */
+			pair_to_free = p;
+
 		if (pair_to_free)
 			diff_free_filepair(pair_to_free);
 	}
@@ -370,7 +356,6 @@ void diffcore_rename(int detect_rename, 
 	*q = outq;
 	diff_debug_queue("done collapsing", q);
 
- cleanup:
 	free(rename_dst);
 	rename_dst = NULL;
 	rename_dst_nr = rename_dst_alloc = 0;
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -39,8 +39,11 @@ extern void diff_free_filespec_data(stru
 struct diff_filepair {
 	struct diff_filespec *one;
 	struct diff_filespec *two;
-	int score; /* only valid when one and two are different paths */
-	int status; /* M C R N D U (see Documentation/diff-format.txt) */
+	unsigned short int score; /* only valid when one and two are
+				   * different paths
+				   */
+	char source_stays; /* all of R/C are copies */
+	char status; /* M C R N D U (see Documentation/diff-format.txt) */
 };
 #define DIFF_PAIR_UNMERGED(p) \
 	(!DIFF_FILE_VALID((p)->one) && !DIFF_FILE_VALID((p)->two))
diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh
new file mode 100644
--- /dev/null
+++ b/t/t4007-rename-3.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='Rename interaction with pathspec.
+
+'
+. ./test-lib.sh
+
+_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"
+sanitize_diff_raw='s/ \('"$_x40"'\) \1 \([CR]\)[0-9]*	/ \1 \1 \2#	/'
+compare_diff_raw () {
+    # When heuristics are improved, the score numbers would change.
+    # Ignore them while comparing.
+    # Also we do not check SHA1 hash generation in this test, which
+    # is a job for t0000-basic.sh
+
+    sed -e "$sanitize_diff_raw" <"$1" >.tmp-1
+    sed -e "$sanitize_diff_raw" <"$2" >.tmp-2
+    diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
+}
+
+test_expect_success \
+    'prepare reference tree' \
+    'mkdir path0 path1 &&
+     cp ../../COPYING path0/COPYING &&
+     git-update-cache --add path0/COPYING &&
+    tree=$(git-write-tree) &&
+    echo $tree'
+
+test_expect_success \
+    'prepare work tree' \
+    'cp path0/COPYING path1/COPYING &&
+     git-update-cache --add --remove path0/COPYING path1/COPYING'
+
+# In the tree, there is only path0/COPYING.  In the cache, path0 and
+# path1 both have COPYING and the latter is a copy of path0/COPYING.
+# Comparing the full tree with cache should tell us so.
+
+git-diff-cache -C $tree >current
+
+cat >expected <<\EOF
+:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100	path0/COPYING	path1/COPYING
+EOF
+
+test_expect_success \
+    'validate the result' \
+    'compare_diff_raw current expected'
+
+# In the tree, there is only path0/COPYING.  In the cache, path0 and
+# path1 both have COPYING and the latter is a copy of path0/COPYING.
+# When we omit output from path0 it should still be able to tell us
+# that path1/COPYING is result from a copy from path0/COPYING, not
+# rename, which would imply path0/COPYING is now gone.
+
+git-diff-cache -C $tree path1 >current
+
+cat >expected <<\EOF
+:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100	path0/COPYING	path1/COPYING
+EOF
+
+test_expect_success \
+    'validate the result' \
+    'compare_diff_raw current expected'
+
+test_expect_success \
+    'tweak work tree' \
+    'rm -f path0/COPYING &&
+     git-update-cache --remove path0/COPYING'
+
+# In the tree, there is only path0/COPYING.  In the cache, path0 does
+# not have COPYING anymore and path1 has COPYING which is a copy of
+# path0/COPYING.  Showing the full tree with cache should tell us about
+# the rename.
+
+git-diff-cache -C $tree >current
+
+cat >expected <<\EOF
+:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100	path0/COPYING	path1/COPYING
+EOF
+
+test_expect_success \
+    'validate the result' \
+    'compare_diff_raw current expected'
+
+# In the tree, there is only path0/COPYING.  In the cache, path0 does
+# not have COPYING anymore and path1 has COPYING which is a copy of
+# path0/COPYING.  Even if we restrict the output to path1, it still
+# should show us the rename.
+
+git-diff-cache -C $tree path1 >current
+
+cat >expected <<\EOF
+:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100	path0/COPYING	path1/COPYING
+EOF
+
+test_expect_success \
+    'validate the result' \
+    'compare_diff_raw current expected'
+
+test_done
------------------------------------------------


^ permalink raw reply

* [PATCH 11/12] Move pathspec to the beginning of the diffcore chain.
From: Junio C Hamano @ 2005-05-27 22:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This changes the way how pathspec is used in the three diff-*
brothers.  Earlier, they tried to grab as much information from
the original input and used pathspec to limit the output.  This
version uses pathspec upfront to narrow the world diffcore
operates in, so "git-diff-* <arguments> some-directory" does not
look at things outside the specified subtree when finding
rename/copy or running pickaxe.

Since diff-tree already takes this view and does not feed
anything outside the specified directotires to begin with, this
patch does not have to touch that command.

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

diff-cache.c        |    4 ++--
diff-files.c        |    4 ++--
diff-helper.c       |    8 ++++----
t/t4007-rename-3.sh |   22 +++++++++++-----------
4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/diff-cache.c b/diff-cache.c
--- a/diff-cache.c
+++ b/diff-cache.c
@@ -240,12 +240,12 @@ int main(int argc, const char **argv)
 		die("unable to read tree object %s", tree_name);
 
 	ret = diff_cache(active_cache, active_nr);
+	if (pathspec)
+		diffcore_pathspec(pathspec);
 	if (detect_rename)
 		diffcore_rename(detect_rename, diff_score_opt);
 	if (pickaxe)
 		diffcore_pickaxe(pickaxe, pickaxe_opts);
-	if (pathspec)
-		diffcore_pathspec(pathspec);
 	diff_flush(diff_output_format, 1);
 	return ret;
 }
diff --git a/diff-files.c b/diff-files.c
--- a/diff-files.c
+++ b/diff-files.c
@@ -116,12 +116,12 @@ int main(int argc, const char **argv)
 		show_modified(oldmode, mode, ce->sha1, null_sha1,
 			      ce->name);
 	}
+	if (1 < argc)
+		diffcore_pathspec(argv + 1);
 	if (detect_rename)
 		diffcore_rename(detect_rename, diff_score_opt);
 	if (pickaxe)
 		diffcore_pickaxe(pickaxe, pickaxe_opts);
-	if (1 < argc)
-		diffcore_pathspec(argv + 1);
 	diff_flush(diff_output_format, 1);
 	return 0;
 }
diff --git a/diff-helper.c b/diff-helper.c
--- a/diff-helper.c
+++ b/diff-helper.c
@@ -129,17 +129,17 @@ int main(int ac, const char **av) {
 					  new_path);
 			continue;
 		}
-		if (pickaxe)
-			diffcore_pickaxe(pickaxe, pickaxe_opts);
 		if (1 < ac)
 			diffcore_pathspec(av + 1);
+		if (pickaxe)
+			diffcore_pickaxe(pickaxe, pickaxe_opts);
 		diff_flush(DIFF_FORMAT_PATCH, 0);
 		printf("%s\n", sb.buf);
 	}
-	if (pickaxe)
-		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	if (1 < ac)
 		diffcore_pathspec(av + 1);
+	if (pickaxe)
+		diffcore_pickaxe(pickaxe, pickaxe_opts);
 	diff_flush(DIFF_FORMAT_PATCH, 0);
 	return 0;
 }
diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh
--- a/t/t4007-rename-3.sh
+++ b/t/t4007-rename-3.sh
@@ -46,23 +46,23 @@ cat >expected <<\EOF
 EOF
 
 test_expect_success \
-    'validate the result' \
+    'validate the result (#1)' \
     'compare_diff_raw current expected'
 
 # In the tree, there is only path0/COPYING.  In the cache, path0 and
 # path1 both have COPYING and the latter is a copy of path0/COPYING.
-# When we omit output from path0 it should still be able to tell us
-# that path1/COPYING is result from a copy from path0/COPYING, not
-# rename, which would imply path0/COPYING is now gone.
+# However when we say we care only about path1, we should just see
+# path1/COPYING suddenly appearing from nowhere, not detected as
+# a copy from path0/COPYING.
 
 git-diff-cache -C $tree path1 >current
 
 cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100	path0/COPYING	path1/COPYING
+:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 N	path1/COPYING
 EOF
 
 test_expect_success \
-    'validate the result' \
+    'validate the result (#2)' \
     'compare_diff_raw current expected'
 
 test_expect_success \
@@ -82,22 +82,22 @@ cat >expected <<\EOF
 EOF
 
 test_expect_success \
-    'validate the result' \
+    'validate the result (#3)' \
     'compare_diff_raw current expected'
 
 # In the tree, there is only path0/COPYING.  In the cache, path0 does
 # not have COPYING anymore and path1 has COPYING which is a copy of
-# path0/COPYING.  Even if we restrict the output to path1, it still
-# should show us the rename.
+# path0/COPYING.  When we say we care only about path1, we should just
+# see path1/COPYING appearing from nowhere.
 
 git-diff-cache -C $tree path1 >current
 
 cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100	path0/COPYING	path1/COPYING
+:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 N	path1/COPYING
 EOF
 
 test_expect_success \
-    'validate the result' \
+    'validate the result (#4)' \
     'compare_diff_raw current expected'
 
 test_done
------------------------------------------------


^ permalink raw reply

* [PATCH 12/12] Optimize diff-tree -[CM] --stdin
From: Junio C Hamano @ 2005-05-27 22:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

This attempts to optimize "diff-tree -[CM] --stdin", which
compares successible tree pairs.  This optimization does not
make much sense for other commands in the diff-* brothers.

When reading from --stdin and using rename/copy detection, the
patch makes diff-tree to read the current index file first.
This is done to reuse the optimization used by diff-cache in the
non-cached case.  Similarity estimator can avoid expanding a
blob if the index says what is in the work tree has an exact
copy of that blob already expanded.

Another optimization the patch makes is to check only file sizes
first to terminate similarity estimation early.  In order for
this to work, it needs a way to tell the size of the blob
without expanding it.  Since an obvious way of doing it, which
is to keep all the blobs previously used in the memory, is too
costly, it does so by keeping the filesize for each object it
has already seen in memory.

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

diff-tree.c        |    3 +
diff.c             |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++--
diff.h             |    2 +
diffcore-pickaxe.c |    2 -
diffcore-rename.c  |   19 ++++++++----
diffcore.h         |    2 -
6 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/diff-tree.c b/diff-tree.c
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -578,6 +578,9 @@ int main(int argc, const char **argv)
 	if (!read_stdin)
 		return 0;
 
+	if (detect_rename)
+		diff_setup_opt |= (DIFF_SETUP_USE_SIZE_CACHE |
+				   DIFF_SETUP_USE_CACHE);
 	while (fgets(line, sizeof(line), stdin))
 		diff_tree_stdin(line);
 
diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -12,6 +12,7 @@ static const char *diff_opts = "-pu";
 static unsigned char null_sha1[20] = { 0, };
 
 static int reverse_diff;
+static int use_size_cache;
 
 static const char *external_diff(void)
 {
@@ -222,12 +223,60 @@ static int work_tree_matches(const char 
 	return 1;
 }
 
+static struct sha1_size_cache {
+	unsigned char sha1[20];
+	unsigned long size;
+} **sha1_size_cache;
+static int sha1_size_cache_nr, sha1_size_cache_alloc;
+
+static struct sha1_size_cache *locate_size_cache(unsigned char *sha1,
+						 unsigned long size)
+{
+	int first, last;
+	struct sha1_size_cache *e;
+
+	first = 0;
+	last = sha1_size_cache_nr;
+	while (last > first) {
+		int next = (last + first) >> 1;
+		e = sha1_size_cache[next];
+		int cmp = memcmp(e->sha1, sha1, 20);
+		if (!cmp)
+			return e;
+		if (cmp < 0) {
+			last = next;
+			continue;
+		}
+		first = next+1;
+	}
+	/* not found */
+	if (size == UINT_MAX)
+		return NULL;
+	/* insert to make it at "first" */
+	if (sha1_size_cache_alloc <= sha1_size_cache_nr) {
+		sha1_size_cache_alloc = alloc_nr(sha1_size_cache_alloc);
+		sha1_size_cache = xrealloc(sha1_size_cache,
+					   sha1_size_cache_alloc *
+					   sizeof(*sha1_size_cache));
+	}
+	sha1_size_cache_nr++;
+	if (first < sha1_size_cache_nr)
+		memmove(sha1_size_cache + first + 1, sha1_size_cache + first,
+			(sha1_size_cache_nr - first - 1) *
+			sizeof(*sha1_size_cache));
+	e = xmalloc(sizeof(struct sha1_size_cache));
+	sha1_size_cache[first] = e;
+	memcpy(e->sha1, sha1, 20);
+	e->size = size;
+	return e;
+}
+
 /*
  * While doing rename detection and pickaxe operation, we may need to
  * grab the data for the blob (or file) for our own in-core comparison.
  * diff_filespec has data and size fields for this purpose.
  */
-int diff_populate_filespec(struct diff_filespec *s)
+int diff_populate_filespec(struct diff_filespec *s, int size_only)
 {
 	int err = 0;
 	if (!DIFF_FILE_VALID(s))
@@ -235,6 +284,9 @@ int diff_populate_filespec(struct diff_f
 	if (S_ISDIR(s->mode))
 		return -1;
 
+	if (!use_size_cache)
+		size_only = 0;
+
 	if (s->data)
 		return err;
 	if (!s->sha1_valid ||
@@ -254,6 +306,8 @@ int diff_populate_filespec(struct diff_f
 		s->size = st.st_size;
 		if (!s->size)
 			goto empty;
+		if (size_only)
+			return 0;
 		if (S_ISLNK(st.st_mode)) {
 			int ret;
 			s->data = xmalloc(s->size);
@@ -273,9 +327,21 @@ int diff_populate_filespec(struct diff_f
 		close(fd);
 	}
 	else {
+		/* We cannot do size only for SHA1 blobs */
 		char type[20];
+		struct sha1_size_cache *e;
+
+		if (size_only) {
+			e = locate_size_cache(s->sha1, UINT_MAX);
+			if (e) {
+				s->size = e->size;
+				return 0;
+			}
+		}
 		s->data = read_sha1_file(s->sha1, type, &s->size);
 		s->should_free = 1;
+		if (s->data && size_only)
+			locate_size_cache(s->sha1, s->size);
 	}
 	return 0;
 }
@@ -361,7 +427,7 @@ static void prepare_temp_file(const char
 		return;
 	}
 	else {
-		if (diff_populate_filespec(one))
+		if (diff_populate_filespec(one, 0))
 			die("cannot read data blob for %s", one->path);
 		prep_temp_blob(temp, one->data, one->size,
 			       one->sha1, one->mode);
@@ -496,6 +562,19 @@ void diff_setup(int flags)
 {
 	if (flags & DIFF_SETUP_REVERSE)
 		reverse_diff = 1;
+	if (flags & DIFF_SETUP_USE_CACHE) {
+		if (!active_cache)
+			/* read-cache does not die even when it fails
+			 * so it is safe for us to do this here.  Also
+			 * it does not smudge active_cache or active_nr
+			 * when it fails, so we do not have to worry about
+			 * cleaning it up oufselves either.
+			 */
+			read_cache();
+	}
+	if (flags & DIFF_SETUP_USE_SIZE_CACHE)
+		use_size_cache = 1;
+	
 }
 
 struct diff_queue_struct diff_queued_diff;
diff --git a/diff.h b/diff.h
--- a/diff.h
+++ b/diff.h
@@ -29,6 +29,8 @@ extern void diff_unmerge(const char *pat
 extern int diff_scoreopt_parse(const char *opt);
 
 #define DIFF_SETUP_REVERSE      	1
+#define DIFF_SETUP_USE_CACHE		2
+#define DIFF_SETUP_USE_SIZE_CACHE	4
 extern void diff_setup(int flags);
 
 #define DIFF_DETECT_RENAME	1
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -11,7 +11,7 @@ static int contains(struct diff_filespec
 {
 	unsigned long offset, sz;
 	const char *data;
-	if (diff_populate_filespec(one))
+	if (diff_populate_filespec(one, 0))
 		return 0;
 	sz = one->size;
 	data = one->data;
diff --git a/diffcore-rename.c b/diffcore-rename.c
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -99,8 +99,11 @@ static int is_exact_match(struct diff_fi
 	if (src->sha1_valid && dst->sha1_valid &&
 	    !memcmp(src->sha1, dst->sha1, 20))
 		return 1;
-	if (diff_populate_filespec(src) || diff_populate_filespec(dst))
-		/* this is an error but will be caught downstream */
+	if (diff_populate_filespec(src, 1) || diff_populate_filespec(dst, 1))
+		return 0;
+	if (src->size != dst->size)
+		return 0;
+	if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
 		return 0;
 	if (src->size == dst->size &&
 	    !memcmp(src->data, dst->data, src->size))
@@ -125,9 +128,11 @@ static int estimate_similarity(struct di
 	 * dst, and then some edit has been applied to dst.
 	 *
 	 * Compare them and return how similar they are, representing
-	 * the score as an integer between 0 and 10000, except
-	 * where they match exactly it is considered better than anything
-	 * else.
+	 * the score as an integer between 0 and MAX_SCORE.
+	 *
+	 * When there is an exact match, it is considered a better
+	 * match than anything else; the destination does not even
+	 * call into this function in that case.
 	 */
 	void *delta;
 	unsigned long delta_size, base_size;
@@ -147,6 +152,7 @@ static int estimate_similarity(struct di
 	/* We would not consider edits that change the file size so
 	 * drastically.  delta_size must be smaller than
 	 * (MAX_SCORE-minimum_score)/MAX_SCORE * min(src->size, dst->size).
+	 *
 	 * Note that base_size == 0 case is handled here already
 	 * and the final score computation below would not have a
 	 * divide-by-zero issue.
@@ -154,6 +160,9 @@ static int estimate_similarity(struct di
 	if (base_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
 		return 0;
 
+	if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
+		return 0; /* error but caught downstream */
+
 	delta = diff_delta(src->data, src->size,
 			   dst->data, dst->size,
 			   &delta_size);
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -33,7 +33,7 @@ extern struct diff_filespec *alloc_files
 extern void fill_filespec(struct diff_filespec *, const unsigned char *,
 			  unsigned short);
 
-extern int diff_populate_filespec(struct diff_filespec *);
+extern int diff_populate_filespec(struct diff_filespec *, int);
 extern void diff_free_filespec_data(struct diff_filespec *);
 
 struct diff_filepair {
------------------------------------------------


^ permalink raw reply

* [RFC] Removing git-*.html references from manpages
From: Jonas Fonseca @ 2005-05-27 22:58 UTC (permalink / raw)
  To: David Greaves; +Cc: git

Hello,

Just a minor issue but still. Currently the manpages contains the
following:

	git-export: git-export.html

I'd like to have the interlinking references removed from the manpages
so it becomes just:

	git-export

or what ever was put between the square brackets of the link: macro.

The fix requires the introduction of an asciidoc.conf file and a new
link macro which I've called gitlink: but it could be shorter (and also
smarter so link:git-CMD.html[git-CMD] could become man:git-CMD[]).

Below is a small patch probe to show the basic idea.

What do you think?

--- a/Documentation/Makefile  (mode:100644)
+++ b/Documentation/Makefile  (mode:100644)
@@ -32,10 +32,10 @@
 	rm -f *.xml *.html *.1 *.7
 
 %.html : %.txt
-	asciidoc -b css-embedded -d manpage $<
+	asciidoc -b css-embedded -d manpage -f asciidoc.conf $<
 
 %.1 %.7 : %.xml
 	xmlto man $<
 
 %.xml : %.txt
-	asciidoc -b docbook -d manpage $<
+	asciidoc -b docbook -d manpage -f asciidoc.conf $<
--- /dev/null  (tree:f6db9be9d431080d9e7f61edb616b8bac8c9618f)
+++ b/Documentation/asciidoc.conf  (mode:100644)
@@ -0,0 +1,14 @@
+ifdef::backend-docbook[]
+
+# Don't show the link target to git-*.html pages in the man page
+[gitlink-inlinemacro]
+<emphasis>{attrlist}</emphasis>
+
+endif::backend-docbook[]
+
+ifdef::backend-css-embedded[]
+
+[gitlink-inlinemacro]
+<a href="{target}">{0={target}}</a>
+
+endif::backend-css-embedded[]
--- a/Documentation/git.txt  (mode:100644)
+++ b/Documentation/git.txt  (mode:100644)
@@ -39,34 +39,34 @@
 
 Manipulation commands
 ~~~~~~~~~~~~~~~~~~~~~
-link:git-checkout-cache.html[git-checkout-cache]::
+gitlink:git-checkout-cache.html[git-checkout-cache]::
 	Copy files from the cache to the working directory
 
-link:git-commit-tree.html[git-commit-tree]::
+gitlink:git-commit-tree.html[git-commit-tree]::
 	Creates a new commit object
 
-link:git-init-db.html[git-init-db]::
+gitlink:git-init-db.html[git-init-db]::
 	Creates an empty git object database
 
-link:git-merge-base.html[git-merge-base]::
+gitlink:git-merge-base.html[git-merge-base]::
 	Finds as good a common ancestor as possible for a merge
 
-link:git-mkdelta.html[git-mkdelta]::
+gitlink:git-mkdelta.html[git-mkdelta]::
 	Creates a delta object
 
-link:git-mktag.html[git-mktag]::
+gitlink:git-mktag.html[git-mktag]::
 	Creates a tag object
 
-link:git-read-tree.html[git-read-tree]::
+gitlink:git-read-tree.html[git-read-tree]::
 	Reads tree information into the directory cache
 
-link:git-update-cache.html[git-update-cache]::
+gitlink:git-update-cache.html[git-update-cache]::
 	Modifies the index or directory cache
 
-link:git-write-blob.html[git-write-blob]::
+gitlink:git-write-blob.html[git-write-blob]::
 	Creates a blob from a file
 
-link:git-write-tree.html[git-write-tree]::
+gitlink:git-write-tree.html[git-write-tree]::
 	Creates a tree from the current cache
 
 Interrogation commands

-- 
Jonas Fonseca

^ permalink raw reply

* Re: [PATCH 00/12] Diff updates
From: Junio C Hamano @ 2005-05-27 23:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <7vk6lk5lxt.fsf_-_@assigned-by-dhcp.cox.net>

I've said "I am done with diff" twice on this list already.
Aside from unevitable bug reports ;-) I think this time I am
done.  At least the major ones I wanted to do.

Except one thing.  What do you think about the current behaviour
of "diff-cache -p (uncached") in a work tree which was freshly
checked-out, unmodified but you "touch"ed some files to make
them stat-dirty?

I think ancient diff-cache did not report those files, but with
the new "diff --git" headers it will show the "diff --git"
header mentioning those files followed by no content nor mode
changes.  Admittedly this matches the diff-raw output behaviour
more closely, but I find it a bit distracting.  Do you care
about cleaning this up?



^ permalink raw reply

* Re: More gitweb queries..
From: Benjamin Herrenschmidt @ 2005-05-27 23:12 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kay Sievers, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505271145570.17402@ppc970.osdl.org>


>   On that small note, I also find "gitk" very cool indeed, too bad about 
>   the fact that tk/tcl seems to always end up looking so _ugly_. Is there 
>   any way to get anti-aliased fonts and a less 'Motify' blocky look from 
>   tcl/tk? Every time I see that, I feel like I'm back in the last century  
>   or something.

Heh, tell paulus, he loves Tk :-)

He told me the next version of Tk will have anti aliased fonts. I don't
know about blockyness of the widgets tho.

>   Combining some of the features of the two (that über-cool revision 
>   history graph from gitk rules, for example) might be cool. I get the 
>   urge to do octopus-merges in the kernel just because of how good they
>   look in gitk ;) ]




^ permalink raw reply

* [gitweb bug] Pressing commitdiff on first commit returns 403
From: Jonas Fonseca @ 2005-05-27 23:37 UTC (permalink / raw)
  To: Kay Sievers; +Cc: git

Just a minor issue. For example the URL below for the commitdiff of the
first git commit gives me ``403 Forbidden - Reading diff-tree failed.''

http://kernel.org/git/?p=git/git.git;a=commitdiff;h=e83c5163316f89bfbde7d9ab23ca2e25604af290

-- 
Jonas Fonseca

^ permalink raw reply

* Re: More gitweb queries..
From: Kay Sievers @ 2005-05-27 23:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505271145570.17402@ppc970.osdl.org>

On Fri, May 27, 2005 at 12:24:20PM -0700, Linus Torvalds wrote:
>  - looking around, the ALSA guys aren't the only ones that start off with 
>    an empty line, so it's probably worth fixing the summary etc to ignore 
>    whitespace at the beginning rather than give empty summary reasons.

That is already fixed a few days ago, but unfortunately only in my devel
version. After the catch-up on the recent format changes of the git-output,
I need to wait now until the new git-binaries are hitting kernel.org.

>  - any reason to limit the "summary" page to just the last 14 changes? The 
>    "log" thing you can ask to go back further, it would be nice to have
>    something like a "last 100" thing for summaries too, especially since 
>    the summary is so nice and dense, so you can actually get a nice view 
>    of what has happened without scrolling _too_ much.

Yes, I recognized that too. Jeff asked for branches and I did the summary
page just for the branches. :) With that I realized that the dense log of the
summary is sometimes nicer than the full log. How about this:
  http://ehlo.org/~kay/gitweb.cgi?p=git/git.git;a=shortlog

It is reachable on the summary page by clicking in the title of the
shortlog.

>  - I was in the "commitdiff" thing, and initially thought that there was 
>    no way to get back to the "summary" view.
> 
>    It turns out I was wrong (the summary is reachable by just clicking at
>    the project name itself in the top header), but it's a bit strange that
>    the "commitdiff" thing has an explicit link back to itself (hey, 
>    consistency is good, so I'm not complaining)

Well, yes I was trying to get a navigation which is not changing with
every new page... It's not an active link now. Maybe that's better.

>    but the link back to the
>    summary page is implicit.
> 
>    So how about adding an explicit "summary" link to the list of other 
>    explicit links (log, commit, commitdiff and tree) at the top of the 
>    page?

Done! That was easy. It will show up on kernel.org when the actual
git-binaries are installed.

> I actually like browsing other peoples projects with the gitweb
> interfaces, it's both responsive and verbose enough to really say
> something good. In contrast, cvsweb is always just a mess of "these are
> the files, go at it", which is totally pointless and doesn't tell anything
> about what is actually happening in the project.
> 
> So dammit, I'm very biased indeed, but I'm just looking at gitweb, and
> comparing it to both the CVS and SVN web things, and they just reinforce
> my conviction that CVS is absolute crap, and I find myself surprised by
> how crap SVN also appears.

Good to hear that. It's a long road to make software from "working" to
"nice to use". That was probably never the goal of some SCM-web-interfaces. :)

>   Combining some of the features of the two (that über-cool revision 
>   history graph from gitk rules, for example) might be cool. I get the 
>   urge to do octopus-merges in the kernel just because of how good they
>   look in gitk ;) ]

I would like to show something like the graph too, but I don't really know
how to do this in html. Seems slippery if not impossible.
If anybody has a nice idea how to represent that, I will give it a try.

Kay

^ permalink raw reply

* Re: [gitweb bug] Pressing commitdiff on first commit returns 403
From: Kay Sievers @ 2005-05-28  0:02 UTC (permalink / raw)
  To: Jonas Fonseca; +Cc: git
In-Reply-To: <20050527233750.GB25491@diku.dk>

On Sat, May 28, 2005 at 01:37:50AM +0200, Jonas Fonseca wrote:
> Just a minor issue. For example the URL below for the commitdiff of the
> first git commit gives me ``403 Forbidden - Reading diff-tree failed.''
> 
> http://kernel.org/git/?p=git/git.git;a=commitdiff;h=e83c5163316f89bfbde7d9ab23ca2e25604af290

That's already fixed in the next version.

thanks,
Kay

^ permalink raw reply

* Re: More gitweb queries..
From: Daniel Serpell @ 2005-05-28  1:03 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <20050527235924.GB19491@vrfy.org>

Hi!

On 5/27/05, Kay Sievers <kay.sievers@vrfy.org> wrote:
> On Fri, May 27, 2005 at 12:24:20PM -0700, Linus Torvalds wrote:
> >   Combining some of the features of the two (that über-cool revision
> >   history graph from gitk rules, for example) might be cool. I get the
> >   urge to do octopus-merges in the kernel just because of how good they
> >   look in gitk ;) ]
> 
> I would like to show something like the graph too, but I don't really know
> how to do this in html. Seems slippery if not impossible.
> If anybody has a nice idea how to represent that, I will give it a try.

Well, you could draw them in javascript, using
http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm :-)

Alternatively, you could use a fixed set of little images, a bar "|", a
dot "o" and branches like "Y", "7" and "\". Obviously, octopus-merges
are very difficult to draw using only those.

BTW, I tried searching on gitweb, and I think that found a problem, see:
http://ehlo.org/~kay/gitweb.cgi?p=git/git.git;a=search;s=check
At the bottom of the page, highlighting of the search term stops and the
commits are all the same color.

        Daniel.

^ permalink raw reply

* Re: ALSA official git repository
From: Linus Torvalds @ 2005-05-28  2:21 UTC (permalink / raw)
  To: Andrew Morton; +Cc: perex, linux-kernel, git
In-Reply-To: <20050527154625.5490f405.akpm@osdl.org>



On Fri, 27 May 2005, Andrew Morton wrote:
> 
> That all assumes that the tools are smart enough to separate the email
> headers from the body :(

Well, _that_ is trivial: the first empty line is the marker between header 
and body. 

This is a stupid awk program to do this:

	/^From: / { name=$0 }
	state==1 { print name; exit }
	/^$/ { state=1 }

Or something. 


		Linus

^ permalink raw reply

* Re: More gitweb queries..
From: Junio C Hamano @ 2005-05-28  2:26 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Thomas Glanzmann, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0505271457480.17402@ppc970.osdl.org>

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

LT> There's no limit in the data structures, although there clearly is a 
LT> "sanity" limit (and I personally suspect it comes before you hit 16 ;)

I know that my head would start hurting way before I hit 16.

I probably shouldn't have coined the word Octopus in the first
place, giving people a false impression that somehow 8 is a
magic number.  To begin with, what I inflicted on you was not
even an Octopus but a Pentapus, merge of 5 IIRC.

Also we are counting heads, not legs.  Should have said Hydra,
but I do not offhand know how many heads it has --- I've never
met one.  I know King Ghidorah has 3 heads ;-).


^ permalink raw reply

* Re: More gitweb queries..
From: David Lang @ 2005-05-28  2:51 UTC (permalink / raw)
  To: Daniel Serpell; +Cc: Git Mailing List
In-Reply-To: <f0796bb705052718035cd5dbe2@mail.gmail.com>

> Hi!
>
> On 5/27/05, Kay Sievers <kay.sievers@vrfy.org> wrote:
>> On Fri, May 27, 2005 at 12:24:20PM -0700, Linus Torvalds wrote:
>>>   Combining some of the features of the two (that über-cool revision
>>>   history graph from gitk rules, for example) might be cool. I get the
>>>   urge to do octopus-merges in the kernel just because of how good they
>>>   look in gitk ;) ]
>>
>> I would like to show something like the graph too, but I don't really know
>> how to do this in html. Seems slippery if not impossible.
>> If anybody has a nice idea how to represent that, I will give it a try.
>
> Well, you could draw them in javascript, using
> http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm :-)
>
> Alternatively, you could use a fixed set of little images, a bar "|", a
> dot "o" and branches like "Y", "7" and "\". Obviously, octopus-merges
> are very difficult to draw using only those.

you could look into SVG (scaleable vector graphics or some such thing) 
that are supposed to be in the newest browsers (or soon to be added, I'm 
not sure). this should let you do all the drawing nessasary reasonably 
easily (if you are willing to limit users to that, which is probably not 
that big of a problem for git)

David Lang

-- 
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
  -- C.A.R. Hoare

^ permalink raw reply

* Re: [PATCH] ls-tree path restriction semantics fixes
From: Junio C Hamano @ 2005-05-28  3:31 UTC (permalink / raw)
  To: Jason McMullan; +Cc: git
In-Reply-To: <1117221986.11542.29.camel@jmcmullan.timesys>

>>>>> "JM" == Jason McMullan <jason.mcmullan@timesys.com> writes:

JM>   git-ls-tree reporting just the tree's hash is valid, because if
JM> you want everything in that tree, you can just do:

JM> git-ls-tree `git-ls-tree HEAD path/dir | (read m t h n; echo $h)`

JM>   I don't see the problem there.

I do not see the problem either in Turing sense, but that is
like saying you could code anything given an assembler.  There
is a difference between being possible and being practical.

I do think the current behaviour is broken, so I think we are in
half agreement.  What I think is the cleanest would be to make
"git-ls-tree $tree" behave similarly to what "/bin/ls -a" does.
Then we have various combination of options, and also path
arguments, to think about.  How about doing something like this?

 - Running without any paths.

   "git-ls-tree $tree" shows everything first level, just like
   "/bin/ls -a" shows everything in cwd.  There is nothing to
   fix here.

 - Running with paths.

   "git-ls-tree $tree path1 path2..." should show path$n if
   path$n is not a tree and everything under path$n including
   path$n itself if path$n is a tree, just like the way "/bin/ls
   -a path1 path2..." works.  There is major breakage here as
   you pointed out with your "git-ls-tree $tree t" vs
   "git-ls-tree $tree t t" example.

 - Recursive behaviour without paths.

   "git-ls-tree -r $tree" should show everything recursively,
   just like what "/bin/ls -a -R" does.  There is nothing to
   fix.

 - Recursive behaviour with paths.

   "git-ls-tree -r $tree path1 path2..." should show everything
   recursively under path$n, just like what "/bin/ls -a -R path1
   path2..." does.  Again this is not how it currently works as
   you pointed out.

 - With paths but not descending into them.

   "git-ls-tree -d $tree path1 path2..." should show only the
   named path$n even when path$n is a tree, just like what
   "/bin/ls -a -R -d path1 path2..." does.  This is what is
   missing from today's git-ls-tree.


^ permalink raw reply

* Re: ALSA official git repository
From: Chris Wedgwood @ 2005-05-28  3:33 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linus Torvalds, perex, linux-kernel, git
In-Reply-To: <20050527154625.5490f405.akpm@osdl.org>

On Fri, May 27, 2005 at 03:46:25PM -0700, Andrew Morton wrote:

> That all assumes that the tools are smart enough to separate the email
> headers from the body :(

the first blank line separates these, sed can do that --- so is it
really a problem?


^ 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