Git development
 help / color / mirror / Atom feed
* Re: [ANNOUNCE] quilt2git v0.2
From: Sam Vilain @ 2006-02-28 20:55 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel, git
In-Reply-To: <20060228111115.GA32276@htj.dyndns.org>

Tejun Heo wrote:
> Hello, v0.2 of quilt2git available.  New in v0.2.
> 
> * handles new git HEAD file format properly (regular file storing ref: ...)
> 
> * makes use of mail format header from quilt patch description.  From:
>   becomes the author, Subject: the subject of the patch.  All commit
>   information should be maintained through git2quilt -> quilt2git now.
> 
> * --signoff option added.  This option is simply passed to git-commit.
> 
> * little fixes
> 
> http://home-tj.org/wiki/index.php/Misc
> http://home-tj.org/files/misc/quilt2git-0.2
> http://home-tj.org/files/misc/git2quilt-0.1
> 
> Thanks.
> 

FWIW, I have a similar script to import a quilt export as an stgit patch 
series, it's really simple but quite useful:

   http://vserver.ustl.gen.nz/scripts/import-quilt

Sam.

^ permalink raw reply

* Re: Quick question: end of lines
From: Martin Langhoff @ 2006-02-28 20:15 UTC (permalink / raw)
  To: Emmanuel Guerin; +Cc: git
In-Reply-To: <f898cca90602281032n6603bf14q@mail.gmail.com>

On 3/1/06, Emmanuel Guerin <emmanuel@guerin.fr.eu.org> wrote:
> To be more precise, I need to be able to checkout files on Unix and
> Windows, and it is important that the end of lines are set
> accordingly.

Why is this important?

(I am thinking: any reasonably good text editor will know how to deal
with unix newlines, but you may have different reasons).


martin

^ permalink raw reply

* Re: Quick question: end of lines
From: Johannes Schindelin @ 2006-02-28 20:07 UTC (permalink / raw)
  To: Emmanuel Guerin; +Cc: git
In-Reply-To: <f898cca90602281032n6603bf14q@mail.gmail.com>

Hi,

On Tue, 28 Feb 2006, Emmanuel Guerin wrote:

> Is it possible to checkout sources out of the GIT repository with
> Windows style end of lines?

No.

As far as git is concerned, every versioned file is equal. IMHO this 
decision is good, since

- different handling is more complicated (you have to keep track of the 
file type), and
- it is not really worth doing.

Windows can handle Unix line endings quite properly (with the notable 
exception of notepad.exe), and even Apple has learnt that it might be a 
stupid idea to insist on being different when it's just not worth it.

The only reason I would accept: you have to work with MS-DOS tools. But 
even in this case, I'd rather write a wrapper which converts to DOS line 
endings, executes the tool, and converts back.

Hth,
Dscho

^ permalink raw reply

* [PATCH 3/3] Tie it all together: "git log"
From: Linus Torvalds @ 2006-02-28 19:30 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602281115110.22647@g5.osdl.org>


This is what the previous diffs all built up to.

We can do "git log" as a trivial small helper function inside git.c, 
because the infrastructure is all there for us to use as a library.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
----

Again, this may not do exactly what the current "git log" does. That's not 
the point. The point is to introduce the fundamental functionality, so 
that people can play with this and improve on it, and fix any of my stupid 
bugs.

It should be pretty easy to change some of the other rev-list-walking 
functions to use the library interfaces too, instead of executing an 
external "git-rev-list" process. This was a perfect example of how to get 
something working, though.

		Linus

diff --git a/Makefile b/Makefile
index 0b1a998..ead13be 100644
--- a/Makefile
+++ b/Makefile
@@ -450,7 +450,7 @@ strip: $(PROGRAMS) git$X
 
 git$X: git.c $(LIB_FILE)
 	$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
-		$(CFLAGS) $(COMPAT_CFLAGS) -o $@ $(filter %.c,$^) $(LIB_FILE)
+		$(ALL_CFLAGS) -o $@ $(filter %.c,$^) $(LIB_FILE) $(LIBS)
 
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
 	rm -f $@
diff --git a/git.c b/git.c
index 993cd0d..b0da6b1 100644
--- a/git.c
+++ b/git.c
@@ -12,6 +12,10 @@
 #include "git-compat-util.h"
 #include "exec_cmd.h"
 
+#include "cache.h"
+#include "commit.h"
+#include "revision.h"
+
 #ifndef PATH_MAX
 # define PATH_MAX 4096
 #endif
@@ -245,6 +249,25 @@ static int cmd_help(int argc, char **arg
 	return 0;
 }
 
+#define LOGSIZE (65536)
+
+static int cmd_log(int argc, char **argv, char **envp)
+{
+	struct rev_info rev;
+	struct commit *commit;
+	char *buf = xmalloc(LOGSIZE);
+
+	argc = setup_revisions(argc, argv, &rev, "HEAD");
+	prepare_revision_walk(&rev);
+	setup_pager();
+	while ((commit = get_revision(&rev)) != NULL) {
+		pretty_print_commit(CMIT_FMT_DEFAULT, commit, ~0, buf, LOGSIZE, 18);
+		printf("%s\n", buf);
+	}
+	free(buf);
+	return 0;
+}
+
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
 
 static void handle_internal_command(int argc, char **argv, char **envp)
@@ -256,6 +279,7 @@ static void handle_internal_command(int 
 	} commands[] = {
 		{ "version", cmd_version },
 		{ "help", cmd_help },
+		{ "log", cmd_log },
 	};
 	int i;
 

^ permalink raw reply related

* [PATCH 2/3] Introduce trivial new pager.c helper infrastructure
From: Linus Torvalds @ 2006-02-28 19:26 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602281115110.22647@g5.osdl.org>


This introduces the new function

	void setup_pager(void);

to set up output to be written through a pager applocation.

All in preparation for doing the simple scripts in C.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

Ok, this should be pretty obvious, which is not to say that it shouldn't 
be improved (ie it only handles trivial definitions of PAGER). Any obvious 
improvements are left as an exercise for the reader, as not important for 
my current goal of actually having something working.


diff --git a/Makefile b/Makefile
index 3575489..0b1a998 100644
--- a/Makefile
+++ b/Makefile
@@ -205,7 +205,7 @@ LIB_OBJS = \
 	quote.o read-cache.o refs.o run-command.o \
 	server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
 	tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
-	fetch-clone.o revision.o \
+	fetch-clone.o revision.o pager.o \
 	$(DIFF_OBJS)
 
 LIBS = $(LIB_FILE)
diff --git a/cache.h b/cache.h
index 58eec00..3af6b86 100644
--- a/cache.h
+++ b/cache.h
@@ -352,4 +352,7 @@ extern int copy_fd(int ifd, int ofd);
 extern int receive_unpack_pack(int fd[2], const char *me, int quiet);
 extern int receive_keep_pack(int fd[2], const char *me, int quiet);
 
+/* pager.c */
+extern void setup_pager(void);
+
 #endif /* CACHE_H */
diff --git a/pager.c b/pager.c
new file mode 100644
index 0000000..1364e15
--- /dev/null
+++ b/pager.c
@@ -0,0 +1,48 @@
+#include "cache.h"
+
+/*
+ * This is split up from the rest of git so that we might do
+ * something different on Windows, for example.
+ */
+
+static void run_pager(void)
+{
+	const char *prog = getenv("PAGER");
+	if (!prog)
+		prog = "less";
+	setenv("LESS", "-S", 0);
+	execlp(prog, prog, NULL);
+}
+
+void setup_pager(void)
+{
+	pid_t pid;
+	int fd[2];
+
+	if (!isatty(1))
+		return;
+	if (pipe(fd) < 0)
+		return;
+	pid = fork();
+	if (pid < 0) {
+		close(fd[0]);
+		close(fd[1]);
+		return;
+	}
+
+	/* return in the child */
+	if (!pid) {
+		dup2(fd[1], 1);
+		close(fd[0]);
+		close(fd[1]);
+		return;
+	}
+
+	/* The original process turns into the PAGER */
+	dup2(fd[0], 0);
+	close(fd[0]);
+	close(fd[1]);
+
+	run_pager();
+	exit(255);
+}

^ permalink raw reply related

* [PATCH 1/3] git-rev-list libification: rev-list walking
From: Linus Torvalds @ 2006-02-28 19:24 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602281115110.22647@g5.osdl.org>


This actually moves the "meat" of the revision walking from rev-list.c
to the new library code in revision.h. It introduces the new functions

	void prepare_revision_walk(struct rev_info *revs);
	struct commit *get_revision(struct rev_info *revs);

to prepare and then walk the revisions that we have.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

All the same old warnigns apply!! This is a bit more intrusive than the 
previous patch series, since it actually changes how things work. It 
passes all the tests I threw at it (well, actually, I only tested the end 
result of the whole series, bad me), but I'd obviously like to remind 
everybody that this is some really core code, and mistakes are bad.

I didn't worry about cleaning code up. It probably could be cleaned up, 
but I worked at trying to just move as much of it as-is from rev-list.c as 
possible, while leaving any code that was really only relevant to rev-list 
itself alone.

diff --git a/rev-list.c b/rev-list.c
index 2e80930..94f22dd 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -8,11 +8,10 @@
 #include "diff.h"
 #include "revision.h"
 
-/* bits #0 and #1 in revision.h */
+/* bits #0-2 in revision.h */
 
-#define COUNTED		(1u << 2)
-#define SHOWN		(1u << 3)
-#define TREECHANGE	(1u << 4)
+#define COUNTED		(1u << 3)
+#define SHOWN		(1u << 4)
 #define TMP_MARK	(1u << 5) /* for isolated cases; clean after use */
 
 static const char rev_list_usage[] =
@@ -213,17 +212,17 @@ static struct object_list **process_tree
 	return p;
 }
 
-static void show_commit_list(struct commit_list *list)
+static void show_commit_list(struct rev_info *revs)
 {
+	struct commit *commit;
 	struct object_list *objects = NULL, **p = &objects, *pending;
-	while (list) {
-		struct commit *commit = pop_most_recent_commit(&list, SEEN);
 
+	while ((commit = get_revision(revs)) != NULL) {
 		p = process_tree(commit->tree, p, NULL, "");
 		if (process_commit(commit) == STOP)
 			break;
 	}
-	for (pending = revs.pending_objects; pending; pending = pending->next) {
+	for (pending = revs->pending_objects; pending; pending = pending->next) {
 		struct object *obj = pending->item;
 		const char *name = pending->name;
 		if (obj->flags & (UNINTERESTING | SEEN))
@@ -259,19 +258,6 @@ static void show_commit_list(struct comm
 	}
 }
 
-static int everybody_uninteresting(struct commit_list *orig)
-{
-	struct commit_list *list = orig;
-	while (list) {
-		struct commit *commit = list->item;
-		list = list->next;
-		if (commit->object.flags & UNINTERESTING)
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
 /*
  * This is a truly stupid algorithm, but it's only
  * used for bisection, and we just don't care enough.
@@ -379,224 +365,12 @@ static void mark_edges_uninteresting(str
 	}
 }
 
-#define TREE_SAME	0
-#define TREE_NEW	1
-#define TREE_DIFFERENT	2
-static int tree_difference = TREE_SAME;
-
-static void file_add_remove(struct diff_options *options,
-		    int addremove, unsigned mode,
-		    const unsigned char *sha1,
-		    const char *base, const char *path)
-{
-	int diff = TREE_DIFFERENT;
-
-	/*
-	 * Is it an add of a new file? It means that
-	 * the old tree didn't have it at all, so we
-	 * will turn "TREE_SAME" -> "TREE_NEW", but
-	 * leave any "TREE_DIFFERENT" alone (and if
-	 * it already was "TREE_NEW", we'll keep it
-	 * "TREE_NEW" of course).
-	 */
-	if (addremove == '+') {
-		diff = tree_difference;
-		if (diff != TREE_SAME)
-			return;
-		diff = TREE_NEW;
-	}
-	tree_difference = diff;
-}
-
-static void file_change(struct diff_options *options,
-		 unsigned old_mode, unsigned new_mode,
-		 const unsigned char *old_sha1,
-		 const unsigned char *new_sha1,
-		 const char *base, const char *path)
-{
-	tree_difference = TREE_DIFFERENT;
-}
-
-static struct diff_options diff_opt = {
-	.recursive = 1,
-	.add_remove = file_add_remove,
-	.change = file_change,
-};
-
-static int compare_tree(struct tree *t1, struct tree *t2)
-{
-	if (!t1)
-		return TREE_NEW;
-	if (!t2)
-		return TREE_DIFFERENT;
-	tree_difference = TREE_SAME;
-	if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
-		return TREE_DIFFERENT;
-	return tree_difference;
-}
-
-static int same_tree_as_empty(struct tree *t1)
-{
-	int retval;
-	void *tree;
-	struct tree_desc empty, real;
-
-	if (!t1)
-		return 0;
-
-	tree = read_object_with_reference(t1->object.sha1, "tree", &real.size, NULL);
-	if (!tree)
-		return 0;
-	real.buf = tree;
-
-	empty.buf = "";
-	empty.size = 0;
-
-	tree_difference = 0;
-	retval = diff_tree(&empty, &real, "", &diff_opt);
-	free(tree);
-
-	return retval >= 0 && !tree_difference;
-}
-
-static void try_to_simplify_commit(struct commit *commit)
-{
-	struct commit_list **pp, *parent;
-
-	if (!commit->tree)
-		return;
-
-	if (!commit->parents) {
-		if (!same_tree_as_empty(commit->tree))
-			commit->object.flags |= TREECHANGE;
-		return;
-	}
-
-	pp = &commit->parents;
-	while ((parent = *pp) != NULL) {
-		struct commit *p = parent->item;
-
-		if (p->object.flags & UNINTERESTING) {
-			pp = &parent->next;
-			continue;
-		}
-
-		parse_commit(p);
-		switch (compare_tree(p->tree, commit->tree)) {
-		case TREE_SAME:
-			parent->next = NULL;
-			commit->parents = parent;
-			return;
-
-		case TREE_NEW:
-			if (revs.remove_empty_trees && same_tree_as_empty(p->tree)) {
-				*pp = parent->next;
-				continue;
-			}
-		/* fallthrough */
-		case TREE_DIFFERENT:
-			pp = &parent->next;
-			continue;
-		}
-		die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
-	}
-	commit->object.flags |= TREECHANGE;
-}
-
-static void add_parents_to_list(struct commit *commit, struct commit_list **list)
-{
-	struct commit_list *parent = commit->parents;
-
-	/*
-	 * If the commit is uninteresting, don't try to
-	 * prune parents - we want the maximal uninteresting
-	 * set.
-	 *
-	 * Normally we haven't parsed the parent
-	 * yet, so we won't have a parent of a parent
-	 * here. However, it may turn out that we've
-	 * reached this commit some other way (where it
-	 * wasn't uninteresting), in which case we need
-	 * to mark its parents recursively too..
-	 */
-	if (commit->object.flags & UNINTERESTING) {
-		while (parent) {
-			struct commit *p = parent->item;
-			parent = parent->next;
-			parse_commit(p);
-			p->object.flags |= UNINTERESTING;
-			if (p->parents)
-				mark_parents_uninteresting(p);
-			if (p->object.flags & SEEN)
-				continue;
-			p->object.flags |= SEEN;
-			insert_by_date(p, list);
-		}
-		return;
-	}
-
-	/*
-	 * Ok, the commit wasn't uninteresting. Try to
-	 * simplify the commit history and find the parent
-	 * that has no differences in the path set if one exists.
-	 */
-	if (revs.paths)
-		try_to_simplify_commit(commit);
-
-	parent = commit->parents;
-	while (parent) {
-		struct commit *p = parent->item;
-
-		parent = parent->next;
-
-		parse_commit(p);
-		if (p->object.flags & SEEN)
-			continue;
-		p->object.flags |= SEEN;
-		insert_by_date(p, list);
-	}
-}
-
-static struct commit_list *limit_list(struct commit_list *list)
-{
-	struct commit_list *newlist = NULL;
-	struct commit_list **p = &newlist;
-	while (list) {
-		struct commit_list *entry = list;
-		struct commit *commit = list->item;
-		struct object *obj = &commit->object;
-
-		list = list->next;
-		free(entry);
-
-		if (revs.max_age != -1 && (commit->date < revs.max_age))
-			obj->flags |= UNINTERESTING;
-		if (revs.unpacked && has_sha1_pack(obj->sha1))
-			obj->flags |= UNINTERESTING;
-		add_parents_to_list(commit, &list);
-		if (obj->flags & UNINTERESTING) {
-			mark_parents_uninteresting(commit);
-			if (everybody_uninteresting(list))
-				break;
-			continue;
-		}
-		if (revs.min_age != -1 && (commit->date > revs.min_age))
-			continue;
-		p = &commit_list_insert(commit, p)->next;
-	}
-	if (revs.tree_objects)
-		mark_edges_uninteresting(newlist);
-	if (bisect_list)
-		newlist = find_bisection(newlist);
-	return newlist;
-}
-
 int main(int argc, const char **argv)
 {
 	struct commit_list *list;
 	int i;
 
-	argc = setup_revisions(argc, argv, &revs);
+	argc = setup_revisions(argc, argv, &revs, NULL);
 
 	for (i = 1 ; i < argc; i++) {
 		const char *arg = argv[i];
@@ -672,24 +446,18 @@ int main(int argc, const char **argv)
 	    (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
 		usage(rev_list_usage);
 
-	if (revs.paths)
-		diff_tree_setup_paths(revs.paths);
+	prepare_revision_walk(&revs);
+	if (revs.tree_objects)
+		mark_edges_uninteresting(revs.commits);
+
+	if (bisect_list)
+		revs.commits = find_bisection(revs.commits);
 
 	save_commit_buffer = verbose_header;
 	track_object_refs = 0;
 
-	if (!merge_order) {		
-		sort_by_date(&list);
-		if (list && !revs.limited && revs.max_count == 1 &&
-		    !revs.tag_objects && !revs.tree_objects && !revs.blob_objects) {
-			show_commit(list->item);
-			return 0;
-		}
-	        if (revs.limited)
-			list = limit_list(list);
-		if (revs.topo_order)
-			sort_in_topological_order(&list, revs.lifo);
-		show_commit_list(list);
+	if (!merge_order) {
+		show_commit_list(&revs);
 	} else {
 #ifndef NO_OPENSSL
 		if (sort_list_in_merge_order(list, &process_commit)) {
diff --git a/revision.c b/revision.c
index 0422593..fb728c1 100644
--- a/revision.c
+++ b/revision.c
@@ -3,6 +3,7 @@
 #include "blob.h"
 #include "tree.h"
 #include "commit.h"
+#include "diff.h"
 #include "refs.h"
 #include "revision.h"
 
@@ -183,6 +184,229 @@ static struct commit *get_commit_referen
 	die("%s is unknown object", name);
 }
 
+static int everybody_uninteresting(struct commit_list *orig)
+{
+	struct commit_list *list = orig;
+	while (list) {
+		struct commit *commit = list->item;
+		list = list->next;
+		if (commit->object.flags & UNINTERESTING)
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+#define TREE_SAME	0
+#define TREE_NEW	1
+#define TREE_DIFFERENT	2
+static int tree_difference = TREE_SAME;
+
+static void file_add_remove(struct diff_options *options,
+		    int addremove, unsigned mode,
+		    const unsigned char *sha1,
+		    const char *base, const char *path)
+{
+	int diff = TREE_DIFFERENT;
+
+	/*
+	 * Is it an add of a new file? It means that
+	 * the old tree didn't have it at all, so we
+	 * will turn "TREE_SAME" -> "TREE_NEW", but
+	 * leave any "TREE_DIFFERENT" alone (and if
+	 * it already was "TREE_NEW", we'll keep it
+	 * "TREE_NEW" of course).
+	 */
+	if (addremove == '+') {
+		diff = tree_difference;
+		if (diff != TREE_SAME)
+			return;
+		diff = TREE_NEW;
+	}
+	tree_difference = diff;
+}
+
+static void file_change(struct diff_options *options,
+		 unsigned old_mode, unsigned new_mode,
+		 const unsigned char *old_sha1,
+		 const unsigned char *new_sha1,
+		 const char *base, const char *path)
+{
+	tree_difference = TREE_DIFFERENT;
+}
+
+static struct diff_options diff_opt = {
+	.recursive = 1,
+	.add_remove = file_add_remove,
+	.change = file_change,
+};
+
+static int compare_tree(struct tree *t1, struct tree *t2)
+{
+	if (!t1)
+		return TREE_NEW;
+	if (!t2)
+		return TREE_DIFFERENT;
+	tree_difference = TREE_SAME;
+	if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
+		return TREE_DIFFERENT;
+	return tree_difference;
+}
+
+static int same_tree_as_empty(struct tree *t1)
+{
+	int retval;
+	void *tree;
+	struct tree_desc empty, real;
+
+	if (!t1)
+		return 0;
+
+	tree = read_object_with_reference(t1->object.sha1, "tree", &real.size, NULL);
+	if (!tree)
+		return 0;
+	real.buf = tree;
+
+	empty.buf = "";
+	empty.size = 0;
+
+	tree_difference = 0;
+	retval = diff_tree(&empty, &real, "", &diff_opt);
+	free(tree);
+
+	return retval >= 0 && !tree_difference;
+}
+
+static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
+{
+	struct commit_list **pp, *parent;
+
+	if (!commit->tree)
+		return;
+
+	if (!commit->parents) {
+		if (!same_tree_as_empty(commit->tree))
+			commit->object.flags |= TREECHANGE;
+		return;
+	}
+
+	pp = &commit->parents;
+	while ((parent = *pp) != NULL) {
+		struct commit *p = parent->item;
+
+		if (p->object.flags & UNINTERESTING) {
+			pp = &parent->next;
+			continue;
+		}
+
+		parse_commit(p);
+		switch (compare_tree(p->tree, commit->tree)) {
+		case TREE_SAME:
+			parent->next = NULL;
+			commit->parents = parent;
+			return;
+
+		case TREE_NEW:
+			if (revs->remove_empty_trees && same_tree_as_empty(p->tree)) {
+				*pp = parent->next;
+				continue;
+			}
+		/* fallthrough */
+		case TREE_DIFFERENT:
+			pp = &parent->next;
+			continue;
+		}
+		die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
+	}
+	commit->object.flags |= TREECHANGE;
+}
+
+static void add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
+{
+	struct commit_list *parent = commit->parents;
+
+	/*
+	 * If the commit is uninteresting, don't try to
+	 * prune parents - we want the maximal uninteresting
+	 * set.
+	 *
+	 * Normally we haven't parsed the parent
+	 * yet, so we won't have a parent of a parent
+	 * here. However, it may turn out that we've
+	 * reached this commit some other way (where it
+	 * wasn't uninteresting), in which case we need
+	 * to mark its parents recursively too..
+	 */
+	if (commit->object.flags & UNINTERESTING) {
+		while (parent) {
+			struct commit *p = parent->item;
+			parent = parent->next;
+			parse_commit(p);
+			p->object.flags |= UNINTERESTING;
+			if (p->parents)
+				mark_parents_uninteresting(p);
+			if (p->object.flags & SEEN)
+				continue;
+			p->object.flags |= SEEN;
+			insert_by_date(p, list);
+		}
+		return;
+	}
+
+	/*
+	 * Ok, the commit wasn't uninteresting. Try to
+	 * simplify the commit history and find the parent
+	 * that has no differences in the path set if one exists.
+	 */
+	if (revs->paths)
+		try_to_simplify_commit(revs, commit);
+
+	parent = commit->parents;
+	while (parent) {
+		struct commit *p = parent->item;
+
+		parent = parent->next;
+
+		parse_commit(p);
+		if (p->object.flags & SEEN)
+			continue;
+		p->object.flags |= SEEN;
+		insert_by_date(p, list);
+	}
+}
+
+static void limit_list(struct rev_info *revs)
+{
+	struct commit_list *list = revs->commits;
+	struct commit_list *newlist = NULL;
+	struct commit_list **p = &newlist;
+
+	while (list) {
+		struct commit_list *entry = list;
+		struct commit *commit = list->item;
+		struct object *obj = &commit->object;
+
+		list = list->next;
+		free(entry);
+
+		if (revs->max_age != -1 && (commit->date < revs->max_age))
+			obj->flags |= UNINTERESTING;
+		if (revs->unpacked && has_sha1_pack(obj->sha1))
+			obj->flags |= UNINTERESTING;
+		add_parents_to_list(revs, commit, &list);
+		if (obj->flags & UNINTERESTING) {
+			mark_parents_uninteresting(commit);
+			if (everybody_uninteresting(list))
+				break;
+			continue;
+		}
+		if (revs->min_age != -1 && (commit->date > revs->min_age))
+			continue;
+		p = &commit_list_insert(commit, p)->next;
+	}
+	revs->commits = newlist;
+}
+
 static void add_one_commit(struct commit *commit, struct rev_info *revs)
 {
 	if (!commit || (commit->object.flags & SEEN))
@@ -214,10 +438,9 @@ static void handle_all(struct rev_info *
  *
  * Returns the number of arguments left ("new argc").
  */
-int setup_revisions(int argc, const char **argv, struct rev_info *revs)
+int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
 {
 	int i, flags, seen_dashdash;
-	const char *def = NULL;
 	const char **unrecognized = argv+1;
 	int left = 1;
 
@@ -381,3 +604,23 @@ int setup_revisions(int argc, const char
 	*unrecognized = NULL;
 	return left;
 }
+
+void prepare_revision_walk(struct rev_info *revs)
+{
+	if (revs->paths)
+		diff_tree_setup_paths(revs->paths);
+	sort_by_date(&revs->commits);
+	if (revs->limited)
+		limit_list(revs);
+	if (revs->topo_order)
+		sort_in_topological_order(&revs->commits, revs->lifo);
+}
+
+struct commit *get_revision(struct rev_info *revs)
+{
+	if (!revs->commits)
+		return NULL;
+	return pop_most_recent_commit(&revs->commits, SEEN);
+}
+
+
diff --git a/revision.h b/revision.h
index a22f198..0bed3c0 100644
--- a/revision.h
+++ b/revision.h
@@ -3,6 +3,7 @@
 
 #define SEEN		(1u<<0)
 #define UNINTERESTING   (1u<<1)
+#define TREECHANGE	(1u<<2)
 
 struct rev_info {
 	/* Starting list */
@@ -32,7 +33,10 @@ struct rev_info {
 };
 
 /* revision.c */
-extern int setup_revisions(int argc, const char **argv, struct rev_info *revs);
+extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
+extern void prepare_revision_walk(struct rev_info *revs);
+extern struct commit *get_revision(struct rev_info *revs);
+
 extern void mark_parents_uninteresting(struct commit *commit);
 extern void mark_tree_uninteresting(struct tree *tree);
 

^ permalink raw reply related

* [PATCH 0/3] git-rev-list libification effort: the next stage
From: Linus Torvalds @ 2006-02-28 19:19 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


Ok, the following three patches that I'll send out are still pretty rough, 
but they actually get us to the first real point of this whole exercise: 
writing one of the trivial git helper scripts in C.

In particular, at the end, we have "git log" being implemented as this 
trivial C function:

	#define LOGSIZE (65536)

	static int cmd_log(int argc, char **argv, char **envp)
	{
		struct rev_info rev;
		struct commit *commit;
		char *buf = xmalloc(LOGSIZE);

		argc = setup_revisions(argc, argv, &rev, "HEAD");
		prepare_revision_walk(&rev);
		setup_pager();
		while ((commit = get_revision(&rev)) != NULL) {
			pretty_print_commit(CMIT_FMT_DEFAULT, commit, ~0, buf, LOGSIZE, 18);
			printf("%s\n", buf);
		}
		free(buf);
		return 0;
	}

which is actually a pretty good example of what I wanted to do.  It's
not perfect yet (it doesn't parse the "--pretty=xxx" option yet, nor the
"--since" and "--until" dates, for example), but I think this is all
going in the right direction. 

			Linus

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Catalin Marinas @ 2006-02-28 18:53 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git
In-Reply-To: <b0943d9e0602280700p132c6da2v@mail.gmail.com>

On 28/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:
> On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:
> > An idea (untested, I don't even know whether it's feasible) would be to
> > check which patches were merged by reverse-applying them starting with
> > the last. In this situation, all the merged patches should just revert
> > their changes. You only need to do a git-diff between the bottom and the
> > top of the patch and git-apply the output (maybe without even modifying
> > the tree). If this operation succeeds, the patch was integrated and you
> > don't even need to push it.
>
> I tried some simple tests with the idea above. I attached a patch if
> you'd like to try (I won't push it to the main StGIT repository yet.
> For safety reasons, it only skips the merged patches when pushing
> them. A future version could simply delete the merged patches.

Don't bother trying this patch. I just found a bug with git.reset()
and the caching of the git.__head variable. I'll post another patch in
a few hours.

--
Catalin

^ permalink raw reply

* Quick question: end of lines
From: Emmanuel Guerin @ 2006-02-28 18:32 UTC (permalink / raw)
  To: git

Hi all,

I  began recently to use git, and there is one thing I still do not
know how to do.

Is it possible to checkout sources out of the GIT repository with
Windows style end of lines?
In a manner much like the one Subversion is using?

To be more precise, I need to be able to checkout files on Unix and
Windows, and it is important that the end of lines are set
accordingly.

Thanks for any hints or pointers,

Regards,

Manu

^ permalink raw reply

* Re: [PATCH] diff-delta: bound hash list length to avoid O(m*n) behavior
From: Nicolas Pitre @ 2006-02-28 17:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqwrq4yi.fsf@assigned-by-dhcp.cox.net>

On Mon, 27 Feb 2006, Junio C Hamano wrote:

> Although I do not mean to rain on your effort and substantial
> improvement you made with this patch, we need to admit that
> improving pathological corner case has quite a diminishing
> effect in the overall picture.

It does, unfortunately.

The problem is that the code in diff_delta() is highly solicited during 
a pack generation.  Just the simple hashing change from this patch that 
involves two shifts instead of only one increased the CPU time to 
generate a pack quite appreciably.  This is just to say that this code 
is pretty sensitive to even small details.

> But this definitely is an improvement nevertheless.  I should
> try this on my wife's AMD64 (Cygwin).  The same datasets I used
> in my previous complaint still seem to take a couple of seconds
> (or more) each on my Duron 750 X-<.

There is no miracle.  To prevent the extreme cases additional tests have 
to be performed in all cases, and therefore performance for all cases is 
affected.

> A handful additional ideas.
> 
>  * Lower the hash limit a bit more (obvious).  That might have
>    detrimental effect in the general case.

It does.  The current parameters are what I think is the best compromize 
between cost and compression.  And still 99% of the cases don't need 
a lower hash limit since their hash lists are already way below the 
limit.  For the  cases where it makes a difference, well lowering the 
hash limit also increase the cost associated with the reworking of the 
hash list so there comes a point where you actually increase the 
resulting delta size while the CPU time stays constant.

>  * Study the hash bucket distribution for the pathological case
>    and see if we can cheaply detect a pattern.  I suspect these
>    cases have relatively few but heavily collided buckets with
>    mostly sparse other entries.  If there is such an easily
>    detectable pattern, maybe we can look for such a pattern at
>    runtime, and cull hash entries more aggressively in such a
>    case?

Same issue as above.  And "looking for such a pattern" really does 
increase the CPU time in _all_ cases.  So that looking for patological 
cases has to be as cheap as possible which I think is the case right 
now (and it is still too costly for my taste already).  And yet I don't 
think there is really a need for further reduction of the hash list at 
this point since the patological cases are really handled gracefully 
with this patch even with a nice and pretty packed delta.

>  * Try checking the target buffer to see if it would have many
>    hits on the heavily collided hash entries from the source
>    (maybe hash_count the target buffer as well).

Again that'd add another significant CPU cost to all cases, even those 
that don't need it at all.  The problem is not about those patological 
cases anymore since I think they are well under control now.  It is the 
overhead those few patological cases impose on the other 180000 good 
behaving objects that is a problem.

>  * Have pack-object detect a pathological blob (the test patch I
>    sent you previously uses the eye-candy timer for this
>    purpose, but we could getrusage() if we want to be more
>    precise) by observing how much time is spent for a single
>    round, and mark the blob as such, so we do not delta against
>    it with other blobs in find_deltas, when we are packing many
>    objects.  It does not really matter in the big picture if we
>    choose not to delta the pathological ones tightly, as long as
>    they are relatively few.

That is one solution, but that doesn't handle the root of the problem 
which is the cost of detecting those cases in the first place.

>  * Also in pack-object, have an optional backing-store to write
>    out deltified representations for results that took more than
>    certain amount of time to produce in find_deltas(), and reuse
>    them in write_object().

The pack reusing code is pretty effective in doing so already, isn't it?  
Since using git-repack -f should not be the common case then those 
patological cases (now taking one second instead of 60 or more) should 
be reused most of the time.

> I tried an experimental patch to cull collided hash buckets
> very aggressively.  I haven't applied your last "reuse index"
> patch, though -- I think that is orthogonal and I'd like to
> leave that to the next round.

It is indeed orthogonal and I think you could apply it to the next 
branch without the other patches (it should apply with little problems).  
This is an obvious and undisputable gain, even more if pack-objects is 
reworked to reduce memory usage by keeping only one live index for 
multiple consecutive deltaattempts.

> With the same dataset: resulting pack is 9651096 vs 9664546
> (your patch) final pack size, with wallclock 2m45s (user 2m31).
> Still not good enough, and at the same time I wonder why it gets
> _smaller_ results than yours.

It really becomes hard to find the best balance especially when the 
resulting delta is then fed through zlib.  Sometimes a larger delta will 
compress better, sometimes not.  My test bench was the whole git 
repository and the kernel repository, and with such large number of 
objects it seems that smaller deltas always translate into smaller 
packs.  But it might not necessarily always be the case.

> I'd appreciate it if you can test it on the 20MB blobs and see
> what happens if you have time.

Before your patch:
user 0m9.713s, delta size = 4910988 bytes, or 1744110 compressed.

With your patch:
user 0m3.948s, delta size = 6753517 bytes, or 1978803 once compressed.

BTW there is another potential for improvement in the delta code (but I 
have real work to do now so)...

Let's suppose the reference buffer has:

 
***********************************************************************/

This is common with some comment block styles.  Now that line will end 
up with multiple blocks that will hash to the same thing and linked 
successively in the same hash bucket except for the last ones where the 
'/' is involved in the hashing.

Now if the target buffer also contains a line similar to the above but 
one '*' character longer.  The first "***" will be hashed to x, then x 
will be looked up in the reference index, and the first entry 
corresponding to the first character of the line above will be returned.  
At that point a search forward is started to find out how much matches.  
In this case it will match up to the '/' in the reference buffer while 
the target will have another '*'.  The length will be recorded as the 
best match, so far so good.

Now the next entry from the same hash bucket will be tested in case it 
might provide a starting point for a longer match.  But we know in this 
case that the location of the second '*' in the reference buffer will be 
returned.  And we obviously know that this cannot match more data than 
the previous attempt, in fact it'll match one byte less.  And the hash 
entry to follow will return the location of the third '*' for another 
byte less to match.  Then the fourth '*' for yet another shorter match. 
And so on repeating those useless string comparisons multiple times.

One improvement might consist of counting the number of consecutive 
identical bytes when starting a compare, and manage to skip as many hash 
entries (minus the block size) before looping again with more entries in 
the same hash bucket.

The other case to distinguish is when the target buffer has instead a 
_shorter_ line, say 5 fewer '*''s before the final '/'.  Here we would 
loop 4 times matching only a bunch of '*' before we finally match the 
'/' as well on the fifth attempt becoming the best match.  In this case 
we could test if the repeated byte we noticed from the start is present 
further away in the reference buffer, and if so simply skip hash entries 
while searching forward in the reference buffer.  When the reference 
buffer doesn't match the repeated character then the comparison is 
resumed with the target buffer, and in this case the '/' would match 
right away, avoiding those four extra loops recomparing all those '*' 
needlessly.

Such improvements added to the search algorithm might make it 
significantly faster, even in the presence of multiple hash entries all 
located in the same bucket.  Or maybe not if the data set has few 
repeated characters.  And this is probably worthwhile only on top of my 
small block patch. Only experimentation could tell.  Someone willing to 
try?


Nicolas

^ permalink raw reply

* Re: [PATCH] git pull cannot find remote refs.
From: Stefan-W. Hahn @ 2006-02-28 16:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlkvwuvyl.fsf@assigned-by-dhcp.cox.net>

Also sprach Junio C Hamano am Mon, 27 Feb 2006 at 17:13:22 -0800:

> ls-remote shows "SHA1\tPATH".  The original says "hexadecimal
> followed by [either a single space or a single tab] followed by

> difference.  Puzzled...

Grmph... You are right.

> I've seen two servers DNS round-robin and one of them fail to
> respond.  The first "fetch" goes to the good one and the second
> ls-remote goes to the bad one, then you would see "Oops, we
> cannot peek tags".  But this patch does not have anything to do
> with that problem..

Trapped. I haven't seen this, but perhaps it was the problem. 
I'll watching for the next occurence.


Sorry for the noise.

Stefan

-- 
Stefan-W. Hahn                          It is easy to make things.
/ mailto:stefan.hahn@s-hahn.de /        It is hard to make things simple.			

^ permalink raw reply

* Re: fatal: unexpected EOF
From: Tony Luck @ 2006-02-28 15:59 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Linus Torvalds, Git Mailing List
In-Reply-To: <44046F94.3070806@didntduck.org>

> I doubt it is a problem with mirroring, since it affects all repos
> (kernel, git, cogito, etc.) at the same time.

Ditto.  Jes has been grumbling overnight that he can't get a reliable pull
from my kernel repo ... and that hasn't been updated in 10 days, so the
mirror code shouldn't be touching it.  His error was:

  fatal: read error (Connection reset by peer)
  Fetch failure: git://git.kernel.org/pub/...

He also reported that after a few retries it worked.

Does the git daemon log any errors to syslog on the server?  If so, can someone
with access go take a look.

-Tony

^ permalink raw reply

* Re: fatal: unexpected EOF
From: Brian Gerst @ 2006-02-28 15:43 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0602280731210.22647@g5.osdl.org>

Linus Torvalds wrote:
> 
> On Tue, 28 Feb 2006, Brian Gerst wrote:
> 
>>Lately I've been receiving this error frequently from git.kernel.org:
>>
>>Fetching pack (head and objects)...
>>fatal: unexpected EOF
>>cg-fetch: fetching pack failed
>>
>>What is causing this?
> 
> 
> Almost any error will cause the pack sending to abort, and the git:// 
> protocol only opens a single socket for data, so there is no way for the 
> other end to say _what_ failed.
> 
> With git.kernel.org, I suspect the reason for the failure is almost always 
> the same, though: the mirroring is not complete, so it doesn't have all 
> object files. The mirroring from master.kernel.org to the actual public 
> machines is just a rsync script, so there's no atomicity guarantees.
> 
> That said, it might be a load issue too - I don't know what limits 
> Peter & co put on the git daemons, and it might also be that it's set up 
> to accept at most <n> connections and will close anything else.
> 
> 		Linus
> 
> 

I doubt it is a problem with mirroring, since it affects all repos 
(kernel, git, cogito, etc.) at the same time.

--
				Brian Gerst

^ permalink raw reply

* Re: fatal: unexpected EOF
From: Linus Torvalds @ 2006-02-28 15:34 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Git Mailing List
In-Reply-To: <440449D7.3010508@didntduck.org>



On Tue, 28 Feb 2006, Brian Gerst wrote:
>
> Lately I've been receiving this error frequently from git.kernel.org:
> 
> Fetching pack (head and objects)...
> fatal: unexpected EOF
> cg-fetch: fetching pack failed
> 
> What is causing this?

Almost any error will cause the pack sending to abort, and the git:// 
protocol only opens a single socket for data, so there is no way for the 
other end to say _what_ failed.

With git.kernel.org, I suspect the reason for the failure is almost always 
the same, though: the mirroring is not complete, so it doesn't have all 
object files. The mirroring from master.kernel.org to the actual public 
machines is just a rsync script, so there's no atomicity guarantees.

That said, it might be a load issue too - I don't know what limits 
Peter & co put on the git daemons, and it might also be that it's set up 
to accept at most <n> connections and will close anything else.

		Linus

^ permalink raw reply

* Re: bug?: stgit creates (unneccessary?) conflicts when pulling
From: Catalin Marinas @ 2006-02-28 15:00 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git
In-Reply-To: <44037A5C.6080409@gmail.com>

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

On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:
> An idea (untested, I don't even know whether it's feasible) would be to
> check which patches were merged by reverse-applying them starting with
> the last. In this situation, all the merged patches should just revert
> their changes. You only need to do a git-diff between the bottom and the
> top of the patch and git-apply the output (maybe without even modifying
> the tree). If this operation succeeds, the patch was integrated and you
> don't even need to push it.

I tried some simple tests with the idea above. I attached a patch if
you'd like to try (I won't push it to the main StGIT repository yet.
For safety reasons, it only skips the merged patches when pushing
them. A future version could simply delete the merged patches.

--
Catalin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: merged-test.diff --]
[-- Type: text/x-patch; name="merged-test.diff", Size: 5189 bytes --]

Add a merged upstream test for pull and push

From: Catalin Marinas <catalin.marinas@gmail.com>

This patch adds the --merged option to both pull and push commands. With
this option, these commands will first try to check which patches were
merged upstream by reverse-applying them in reverse order. This should
solve the situation where several patches modify the same line in a file.

Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
---

 stgit/commands/pull.py |   20 +++++++++++++++++++-
 stgit/commands/push.py |   17 ++++++++++++++++-
 stgit/git.py           |   12 +++++++++---
 stgit/stack.py         |   20 ++++++++++++++++++++
 4 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index 843b579..5d75530 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -39,6 +39,9 @@ format."""
 
 options = [make_option('-n', '--nopush',
                        help = 'do not push the patches back after pulling',
+                       action = 'store_true'),
+           make_option('-m', '--merged',
+                       help = 'check for patches merged upstream (slower)',
                        action = 'store_true')]
 
 def func(parser, options, args):
@@ -77,12 +80,27 @@ def func(parser, options, args):
     # push the patches back
     if options.nopush:
         applied = []
+
+    # check for patches merged upstream
+    if options.merged:
+        merged = crt_series.merged_patches(patches)
+    else:
+        merged = []
+
     for p in applied:
+        if p in merged:
+            print 'Patch "%s" merged upstream' % p
+            continue
+
         print 'Pushing patch "%s"...' % p,
         sys.stdout.flush()
-        crt_series.push_patch(p)
+
+        modified = crt_series.push_patch(p)
+
         if crt_series.empty_patch(p):
             print 'done (empty patch)'
+        elif modified:
+            print 'done (modified)'
         else:
             print 'done'
 
diff --git a/stgit/commands/push.py b/stgit/commands/push.py
index 9924a78..72b2663 100644
--- a/stgit/commands/push.py
+++ b/stgit/commands/push.py
@@ -49,6 +49,9 @@ options = [make_option('-a', '--all',
            make_option('--reverse',
                        help = 'push the patches in reverse order',
                        action = 'store_true'),
+           make_option('-m', '--merged',
+                       help = 'check for patches merged upstream (slower)',
+                       action = 'store_true'),
            make_option('--undo',
                        help = 'undo the last push operation',
                        action = 'store_true')]
@@ -134,9 +137,21 @@ def func(parser, options, args):
     elif forwarded == 1:
         print 'Fast-forwarded patch "%s"' % patches[0]
 
-    for p in patches[forwarded:]:
+    patches = patches[forwarded:]
+
+    # check for patches merged upstream
+    if options.merged:
+        merged = crt_series.merged_patches(patches)
+    else:
+        merged = []
+
+    for p in patches:
         is_patch_appliable(p)
 
+        if p in merged:
+            print 'Patch "%s" merged upstream' % p
+            continue
+
         print 'Pushing patch "%s"...' % p,
         sys.stdout.flush()
 
diff --git a/stgit/git.py b/stgit/git.py
index 016bc3a..66b8612 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -462,14 +462,20 @@ def commit(message, files = None, parent
 
     return commit_id
 
-def apply_diff(rev1, rev2):
+def apply_diff(rev1, rev2, check_index = True):
     """Apply the diff between rev1 and rev2 onto the current
     index. This function doesn't need to raise an exception since it
     is only used for fast-pushing a patch. If this operation fails,
     the pushing would fall back to the three-way merge.
     """
-    return os.system('git-diff-tree -p %s %s | git-apply --index 2> /dev/null'
-                     % (rev1, rev2)) == 0
+    if check_index:
+        index_opt = '--index'
+    else:
+        index_opt = ''
+    cmd = 'git-diff-tree -p %s %s | git-apply %s 2> /dev/null' \
+          % (rev1, rev2, index_opt)
+
+    return os.system(cmd) == 0
 
 def merge(base, head1, head2):
     """Perform a 3-way merge between base, head1 and head2 into the
diff --git a/stgit/stack.py b/stgit/stack.py
index e1c55f0..9d5f043 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -780,6 +780,26 @@ class Series:
 
         return forwarded
 
+    def merged_patches(self, names):
+        """Test which patches were merged upstream by reverse-applying
+        them in reverse order. The function returns the list of
+        patches detected to have been applied. The state of the tree
+        is restored to the original one
+        """
+        patches = [Patch(name, self.__patch_dir, self.__refs_dir)
+                   for name in names]
+        patches.reverse()
+
+        merged = []
+        for p in patches:
+            if git.apply_diff(p.get_top(), p.get_bottom(), False):
+                merged.append(p.get_name())
+        merged.reverse()
+
+        git.reset()
+
+        return merged
+
     def push_patch(self, name):
         """Pushes a patch on the stack
         """

^ permalink raw reply related

* gitview: Set the default width  of graph cell
From: Aneesh Kumar K.V @ 2006-02-28 14:40 UTC (permalink / raw)
  To: git, Junio C Hamano

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



[-- Attachment #2: 0003-gitview-Set-the-default-width-of-graph-cell.txt --]
[-- Type: text/plain, Size: 755 bytes --]

Subject: gitview: Set the default width  of graph cell

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

---

 contrib/gitview/gitview |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

b298aa0ee1d98b263fe3d493f2911164a4488693
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 47ecaa3..ea05cd4 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -526,6 +526,9 @@ class GitView:
 		self.treeview.show()
 
 		cell = CellRendererGraph()
+		#  Set the default width to 265
+		#  This make sure that we have nice display with large tag names
+		cell.set_property("width", 265)
 		column = gtk.TreeViewColumn()
 		column.set_resizable(True)
 		column.pack_start(cell, expand=True)
-- 
1.2.3.gc55f-dirty


^ permalink raw reply related

* [PATCH] Darwin: Ignore missing /sw/lib
From: Shawn Pearce @ 2006-02-28 14:03 UTC (permalink / raw)
  To: git

When on Darwin platforms don't include Fink or DarwinPorts
into the link path unless the related library directory
is actually present.  The linker on MacOS 10.4 complains
if it is given a directory which does not exist.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

---
 I don't have Fink installed, consequently the linker is whining
 about /sw/lib not existing every time I link a GIT executable.
 I'd rather not see complaints from the linker unless they are
 important.

 Makefile |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

base f3a4ec48e402a7b49d410bdcb23470e9723788b0
last 84434f9549d56e522a2eb4de370100f0a6e5e041
diff --git a/Makefile b/Makefile
index 6c59cee41490d4bfba0fb43102555d8de3371d01..19578fc93a60cc41c31883ceac37a0f1ec4202d7 100644
--- a/Makefile
+++ b/Makefile
@@ -223,11 +223,15 @@ ifeq ($(uname_S),Darwin)
 	NEEDS_SSL_WITH_CRYPTO = YesPlease
 	NEEDS_LIBICONV = YesPlease
 	## fink
-	ALL_CFLAGS += -I/sw/include
-	ALL_LDFLAGS += -L/sw/lib
+	ifeq ($(shell test -d /sw/lib && echo y),y)
+		ALL_CFLAGS += -I/sw/include
+		ALL_LDFLAGS += -L/sw/lib
+	endif
 	## darwinports
-	ALL_CFLAGS += -I/opt/local/include
-	ALL_LDFLAGS += -L/opt/local/lib
+	ifeq ($(shell test -d /opt/local/lib && echo y),y)
+		ALL_CFLAGS += -I/opt/local/include
+		ALL_LDFLAGS += -L/opt/local/lib
+	endif
 endif
 ifeq ($(uname_S),SunOS)
 	NEEDS_SOCKET = YesPlease
-- 
1.2.3.gf3a4

^ permalink raw reply related

* gitview: Some  window layout changes.
From: Aneesh Kumar K.V @ 2006-02-28 13:42 UTC (permalink / raw)
  To: git, Junio C Hamano

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



[-- Attachment #2: 0002-gitview-Some-window-layout-changes.txt --]
[-- Type: text/plain, Size: 1973 bytes --]

Subject: gitview: Some  window layout changes.

This makes menubar look nice

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

---

 contrib/gitview/gitview |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

bc288bd1cd9c70e7eb1e8742527553d1c2dea61d
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index aded7ed..47ecaa3 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -368,7 +368,7 @@ class DiffWindow:
 		save_menu.connect("activate", self.save_menu_response, "save")
 		save_menu.show()
 		menu_bar.append(save_menu)
-		vbox.pack_start(menu_bar, False, False, 2)
+		vbox.pack_start(menu_bar, expand=False, fill=True)
 		menu_bar.show()
 
 		scrollwin = gtk.ScrolledWindow()
@@ -482,19 +482,10 @@ class GitView:
 
 	def construct(self):
 		"""Construct the window contents."""
+		vbox = gtk.VBox()
 		paned = gtk.VPaned()
 		paned.pack1(self.construct_top(), resize=False, shrink=True)
 		paned.pack2(self.construct_bottom(), resize=False, shrink=True)
-		self.window.add(paned)
-		paned.show()
-
-
-	def construct_top(self):
-		"""Construct the top-half of the window."""
-		vbox = gtk.VBox(spacing=6)
-		vbox.set_border_width(12)
-		vbox.show()
-
 		menu_bar = gtk.MenuBar()
 		menu_bar.set_pack_direction(gtk.PACK_DIRECTION_RTL)
 		help_menu = gtk.MenuItem("Help")
@@ -506,8 +497,20 @@ class GitView:
 		help_menu.set_submenu(menu)
 		help_menu.show()
 		menu_bar.append(help_menu)
-		vbox.pack_start(menu_bar, False, False, 2)
 		menu_bar.show()
+		vbox.pack_start(menu_bar, expand=False, fill=True)
+		vbox.pack_start(paned, expand=True, fill=True)
+		self.window.add(vbox)
+		paned.show()
+		vbox.show()
+
+
+	def construct_top(self):
+		"""Construct the top-half of the window."""
+		vbox = gtk.VBox(spacing=6)
+		vbox.set_border_width(12)
+		vbox.show()
+
 
 		scrollwin = gtk.ScrolledWindow()
 		scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-- 
1.2.3.gc55f-dirty


^ permalink raw reply related

* Select the text color based on whether the entry in highlighted.
From: Aneesh Kumar K.V @ 2006-02-28 13:41 UTC (permalink / raw)
  To: git, Junio C Hamano, Pavel Roskin

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



[-- Attachment #2: 0001-Select-the-text-color-based-on-whether-the-entry-in-highlighted.-Use.txt --]
[-- Type: text/plain, Size: 1299 bytes --]

From: Pavel Roskin <proski@gnu.org>
Subject: Select the text color based on whether the entry in highlighted.  Use
standard font.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

---

 contrib/gitview/gitview |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

21154c68bf8b95e0db49d507ea34e0b8a51308df
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 048caf6..aded7ed 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -239,20 +239,23 @@ class CellRendererGraph(gtk.GenericCellR
 				box_size / 4, 0, 2 * math.pi)
 
 
+		self.set_colour(ctx, colour, 0.0, 0.5)
+		ctx.stroke_preserve()
+
+		self.set_colour(ctx, colour, 0.5, 1.0)
+		ctx.fill_preserve()
+
 		if (len(names) != 0):
 			name = " "
 			for item in names:
 				name = name + item + " "
 
-			ctx.select_font_face("Monospace")
 			ctx.set_font_size(13)
-			ctx.text_path(name)
-
-		self.set_colour(ctx, colour, 0.0, 0.5)
-		ctx.stroke_preserve()
-
-		self.set_colour(ctx, colour, 0.5, 1.0)
-		ctx.fill()
+			if (flags & 1):
+				self.set_colour(ctx, colour, 0.5, 1.0)
+			else:
+				self.set_colour(ctx, colour, 0.0, 0.5)
+			ctx.show_text(name)
 
 class Commit:
 	""" This represent a commit object obtained after parsing the git-rev-list
-- 
1.2.3.gc55f-dirty


^ permalink raw reply related

* fatal: unexpected EOF
From: Brian Gerst @ 2006-02-28 13:02 UTC (permalink / raw)
  To: Git Mailing List

Lately I've been receiving this error frequently from git.kernel.org:

Fetching pack (head and objects)...
fatal: unexpected EOF
cg-fetch: fetching pack failed

What is causing this?

--
						Brian Gerst

^ permalink raw reply

* [PATCH 2/2] Speed up history generation
From: Luben Tuikov @ 2006-02-28 12:39 UTC (permalink / raw)
  To: git

Speed up history generation as suggested by Linus.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>

---

 gitweb.cgi |   11 +++--------
 1 files changed, 3 insertions(+), 8 deletions(-)

69d694fccacb09059731abe4918f8f9aa8969690
diff --git a/gitweb.cgi b/gitweb.cgi
index 452528f..bfea65d 100755
--- a/gitweb.cgi
+++ b/gitweb.cgi
@@ -2124,16 +2124,12 @@ sub git_history {
 	      "</div>\n";
 	print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b><br/></div>\n";
 
-	open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin
\'$file_name\'";
-	my $commit;
+	open my $fd, "-|", "$gitbin/git-rev-list $hash -- \'$file_name\'";
 	print "<table cellspacing=\"0\">\n";
 	my $alternate = 0;
 	while (my $line = <$fd>) {
-		if ($line =~ m/^([0-9a-fA-F]{40})/){
-			$commit = $1;
-			next;
-		}
-		if ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/ &&
(defined $commit)) {
+	        if ($line =~ m/^([0-9a-fA-F]{40})/){
+			my $commit = $1;
 			my %co = git_read_commit($commit);
 			if (!%co) {
 				next;
@@ -2165,7 +2161,6 @@ sub git_history {
 			}
 			print "</td>\n" .
 			      "</tr>\n";
-			undef $commit;
 		}
 	}
 	print "</table>\n";
-- 
1.2.3.g975a

^ permalink raw reply related

* [PATCH 1/2] Enable tree (directory) history display
From: Luben Tuikov @ 2006-02-28 12:38 UTC (permalink / raw)
  To: git

This patch allows history display of whole trees/directories,
a la "git-rev-list HEAD <dir or file>", but somewhat
slower, since exported git repository doesn't have
the files checked out so we have to use
"$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin \'$file_name\'"
method.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>

---

 gitweb.cgi |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

5c8ae3db3561238a57201fcb3297f16d7b37f377
diff --git a/gitweb.cgi b/gitweb.cgi
index c1bb624..452528f 100755
--- a/gitweb.cgi
+++ b/gitweb.cgi
@@ -1504,6 +1504,7 @@ sub git_tree {
 			      "</td>\n" .
 			      "<td class=\"link\">" .
 			      $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=tree;h=$t_hash$base_key;f=$base$t_name")}, "tree") .
+			      " | " . $cgi->a({-href => "$my_uri?" .
esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
 			      "</td>\n";
 		}
 		print "</tr>\n";
-- 
1.2.3.g975a

^ permalink raw reply related

* [ANNOUNCE] quilt2git v0.2
From: Tejun Heo @ 2006-02-28 11:11 UTC (permalink / raw)
  To: linux-kernel, git

Hello, v0.2 of quilt2git available.  New in v0.2.

* handles new git HEAD file format properly (regular file storing ref: ...)

* makes use of mail format header from quilt patch description.  From:
  becomes the author, Subject: the subject of the patch.  All commit
  information should be maintained through git2quilt -> quilt2git now.

* --signoff option added.  This option is simply passed to git-commit.

* little fixes

http://home-tj.org/wiki/index.php/Misc
http://home-tj.org/files/misc/quilt2git-0.2
http://home-tj.org/files/misc/git2quilt-0.1

Thanks.

-- 
tejun

^ permalink raw reply

* Re: [PATCH 2/3] apply --whitespace: configuration option.
From: Andreas Ericsson @ 2006-02-28  9:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzmkbn7qx.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> Andreas Ericsson <ae@op5.se> writes:
> 
> 
>>Junio C Hamano wrote:
>>
>>>The new configuration option apply.whitespace can take one of
>>>"warn", "error", "error-all", or "strip".  When git-apply is run
>>>to apply the patch to the index, they are used as the default
>>>value if there is no command line --whitespace option.
>>
>>I would think "warn-all" would be the logical thing, since "error"
>>either breaks out early or prints all warnings before denying the
>>patch anyway.
> 
> 
> Actually there is some thinking behind why I did not do warn-all.
> I did consider it at first but rejected.
> 
>  * If you are a busy top echelon person but cares about tree
>    cleanliness, --whitespace=error is good enough.  The patch is
>    rejected on WS basis whether it introduces one such trailing
>    WS or hundreds.  The patch is returned to the submitter and
>    the tree remains clean.
> 
>  * --whitespace=warn-all, if existed, would apply the patch
>    _anyway_, so if you notice you got warnings, and if that
>    bothers you enough that you would want to do something about
>    it, you will have to rewind the HEAD, fix up .dotest/patch
>    and reapply.  This means you are willing to clean up other
>    peoples' patches.
> 
>  * But if you are that kind of person, --whitespace=error-all is
>    a better choice for you.  Your tree stays clean and you do
>    not have to rewind.  Instead, you get all the errors you can
>    go through with your editor (e.g. Emacs users can use C-x `;
>    I hope vim users have similar macros) and fix things.
> 

Good Thinking. Thanks for explaining.

> 
> The last one is somewhat risky, and the output may need to be
> examined carefully depending on the contents (e.g. programming
> language) the project is dealing with.
> 
> 

echo Makefile >> .git/no-ws-strip
echo '*.[ch]' >> .git/ws-strip

Perhaps not viable, and probably stupid as well. Mixed content repos 
would likely just keep the 'warn' policy.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: [PATCH 2/3] apply --whitespace: configuration option.
From: Junio C Hamano @ 2006-02-28  9:38 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: git
In-Reply-To: <440414D6.8050407@op5.se>

Andreas Ericsson <ae@op5.se> writes:

> Junio C Hamano wrote:
>> The new configuration option apply.whitespace can take one of
>> "warn", "error", "error-all", or "strip".  When git-apply is run
>> to apply the patch to the index, they are used as the default
>> value if there is no command line --whitespace option.
>
> I would think "warn-all" would be the logical thing, since "error"
> either breaks out early or prints all warnings before denying the
> patch anyway.

Actually there is some thinking behind why I did not do warn-all.
I did consider it at first but rejected.

 * If you are a busy top echelon person but cares about tree
   cleanliness, --whitespace=error is good enough.  The patch is
   rejected on WS basis whether it introduces one such trailing
   WS or hundreds.  The patch is returned to the submitter and
   the tree remains clean.

 * --whitespace=warn-all, if existed, would apply the patch
   _anyway_, so if you notice you got warnings, and if that
   bothers you enough that you would want to do something about
   it, you will have to rewind the HEAD, fix up .dotest/patch
   and reapply.  This means you are willing to clean up other
   peoples' patches.

 * But if you are that kind of person, --whitespace=error-all is
   a better choice for you.  Your tree stays clean and you do
   not have to rewind.  Instead, you get all the errors you can
   go through with your editor (e.g. Emacs users can use C-x `;
   I hope vim users have similar macros) and fix things.

 * --whitespace=warn would show some, but not all, so that you
   can continue while making a mental note to scold the patch
   submitter to be careful the next time.  You chose "warn" to
   apply the patch anyway, so there is no point showing the full
   extent of damage -- the damage is already done to your tree.

 * --whitespace=strip is for people who care about cleanliness,
   who wants to be nice to the submitters, but not nice enough
   to educate them.  They do not want to fix things by hand.
   Instead they have the tool to do the fixing for them.

The last one is somewhat risky, and the output may need to be
examined carefully depending on the contents (e.g. programming
language) the project is dealing with.

^ 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