Git development
 help / color / mirror / Atom feed
* [PATCH 11/13] Introduce reduce_heads()
From: Miklos Vajna @ 2008-06-21 17:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Junio C Hamano, git
In-Reply-To: <cover.1214066798.git.vmiklos@frugalware.org>

From: Junio C Hamano <gitster@pobox.com>

The new function reduce_heads() is given a list of commits, and removes
ones that can be reached from other commits in the list.  It is useful for
reducing the commits randomly thrown at the git-merge command and remove
redundant commits that the user shouldn't have given to it.

The implementation uses the get_merge_bases_many() introduced in the
previous commit.  If the merge base between one commit taken from the list
and the remaining commits is the commit itself, that means the commit is
reachable from some of the other commits.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Makefile               |    1 +
 builtin-reduce-heads.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 builtin.h              |    1 +
 commit.c               |   45 +++++++++++++++++++++++++++++++++++++++++++++
 commit.h               |    2 ++
 git.c                  |    1 +
 6 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 builtin-reduce-heads.c

diff --git a/Makefile b/Makefile
index b003e3e..d660756 100644
--- a/Makefile
+++ b/Makefile
@@ -522,6 +522,7 @@ BUILTIN_OBJS += builtin-pack-refs.o
 BUILTIN_OBJS += builtin-prune-packed.o
 BUILTIN_OBJS += builtin-prune.o
 BUILTIN_OBJS += builtin-push.o
+BUILTIN_OBJS += builtin-reduce-heads.o
 BUILTIN_OBJS += builtin-read-tree.o
 BUILTIN_OBJS += builtin-reflog.o
 BUILTIN_OBJS += builtin-remote.o
diff --git a/builtin-reduce-heads.c b/builtin-reduce-heads.c
new file mode 100644
index 0000000..ff6178d
--- /dev/null
+++ b/builtin-reduce-heads.c
@@ -0,0 +1,44 @@
+#include "cache.h"
+#include "commit.h"
+#include "strbuf.h"
+
+static void show_commit_list(struct commit_list *list)
+{
+	while (list) {
+		struct strbuf it;
+		struct commit *commit = list->item;
+
+		list = list->next;
+		strbuf_init(&it, 128);
+		parse_commit(commit);
+		pretty_print_commit(CMIT_FMT_ONELINE, commit, &it,
+				    0, NULL, NULL, 0, 0);
+		puts(it.buf);
+		strbuf_release(&it);
+	}
+}
+
+int cmd_reduce_heads(int ac, const char **av, const char *prefix)
+{
+	struct commit_list *list = NULL, **tail = &list;
+	int i;
+
+	for (i = 1; i < ac; i++) {
+		struct commit *commit;
+		unsigned char sha1[20];
+
+		if (get_sha1(av[i], sha1))
+			die("'%s' is not a valid ref.", av[i]);
+		commit = lookup_commit_reference(sha1);
+		if (!commit)
+			die("cannot find commit %s", av[i]);
+		tail = &commit_list_insert(commit, tail)->next;
+	}
+
+	show_commit_list(list);
+	putchar('\n');
+
+	list = reduce_heads(list);
+	show_commit_list(list);
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index 2b01fea..f069ee7 100644
--- a/builtin.h
+++ b/builtin.h
@@ -75,6 +75,7 @@ extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_config(int argc, const char **argv, const char *prefix);
+extern int cmd_reduce_heads(int argc, const char **argv, const char *prefix);
 extern int cmd_rerere(int argc, const char **argv, const char *prefix);
 extern int cmd_reset(int argc, const char **argv, const char *prefix);
 extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
diff --git a/commit.c b/commit.c
index cafed26..d20b14e 100644
--- a/commit.c
+++ b/commit.c
@@ -725,3 +725,48 @@ int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 	free_commit_list(bases);
 	return ret;
 }
+
+struct commit_list *reduce_heads(struct commit_list *heads)
+{
+	struct commit_list *p;
+	struct commit_list *result = NULL, **tail = &result;
+	struct commit **other;
+	size_t num_head, num_other;
+
+	if (!heads)
+		return NULL;
+
+	/* Avoid unnecessary reallocations */
+	for (p = heads, num_head = 0; p; p = p->next)
+		num_head++;
+	other = xcalloc(sizeof(*other), num_head);
+
+	/* For each commit, see if it can be reached by others */
+	for (p = heads; p; p = p->next) {
+		struct commit_list *q, *base;
+
+		num_other = 0;
+		for (q = heads; q; q = q->next) {
+			if (p == q)
+				continue;
+			other[num_other++] = q->item;
+		}
+		if (num_other) {
+			base = get_merge_bases_many(p->item, num_other, other, 1);
+		} else
+			base = NULL;
+		/*
+		 * If p->item does not have anything common with other
+		 * commits, there won't be any merge base.  If it is
+		 * reachable from some of the others, p->item will be
+		 * the merge base.  If its history is connected with
+		 * others, but p->item is not reachable by others, we
+		 * will get something other than p->item back.
+		 */
+		if (!base || (base->item != p->item))
+			tail = &(commit_list_insert(p->item, tail)->next);
+		free_commit_list(base);
+	}
+	free(other);
+	return result;
+}
diff --git a/commit.h b/commit.h
index dcec7fb..2acfc79 100644
--- a/commit.h
+++ b/commit.h
@@ -140,4 +140,6 @@ static inline int single_parent(struct commit *commit)
 	return commit->parents && !commit->parents->next;
 }
 
+struct commit_list *reduce_heads(struct commit_list *heads);
+
 #endif /* COMMIT_H */
diff --git a/git.c b/git.c
index 2fbe96b..80b16ce 100644
--- a/git.c
+++ b/git.c
@@ -285,6 +285,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "prune-packed", cmd_prune_packed, RUN_SETUP },
 		{ "push", cmd_push, RUN_SETUP },
 		{ "read-tree", cmd_read_tree, RUN_SETUP },
+		{ "reduce-heads", cmd_reduce_heads, RUN_SETUP },
 		{ "reflog", cmd_reflog, RUN_SETUP },
 		{ "remote", cmd_remote, RUN_SETUP },
 		{ "repo-config", cmd_config },
-- 
1.5.6

^ permalink raw reply related

* [PATCH 09/13] Add new test to ensure git-merge handles more than 25 refs.
From: Miklos Vajna @ 2008-06-21 17:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Junio C Hamano
In-Reply-To: <cover.1214066798.git.vmiklos@frugalware.org>

The old shell version handled only 25 refs but we no longer have this
limitation. Add a test to make sure this limitation will not be
introduced again in the future.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t7602-merge-octopus-many.sh |   52 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100755 t/t7602-merge-octopus-many.sh

diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
new file mode 100755
index 0000000..fcb8285
--- /dev/null
+++ b/t/t7602-merge-octopus-many.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='git-merge
+
+Testing octopus merge with more than 25 refs.'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	echo c0 > c0.c &&
+	git add c0.c &&
+	git commit -m c0 &&
+	git tag c0 &&
+	i=1 &&
+	while test $i -le 30
+	do
+		git reset --hard c0 &&
+		echo c$i > c$i.c &&
+		git add c$i.c &&
+		git commit -m c$i &&
+		git tag c$i &&
+		i=`expr $i + 1` || return 1
+	done
+'
+
+test_expect_success 'merge c1 with c2, c3, c4, ... c29' '
+	git reset --hard c1 &&
+	i=2 &&
+	refs="" &&
+	while test $i -le 30
+	do
+		refs="$refs c$i"
+		i=`expr $i + 1`
+	done
+	git merge $refs &&
+	test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" &&
+	i=1 &&
+	while test $i -le 30
+	do
+		test "$(git rev-parse c$i)" = "$(git rev-parse HEAD^$i)" &&
+		i=`expr $i + 1` || return 1
+	done &&
+	git diff --exit-code &&
+	i=1 &&
+	while test $i -le 30
+	do
+		test -f c$i.c &&
+		i=`expr $i + 1` || return 1
+	done
+'
+
+test_done
-- 
1.5.6

^ permalink raw reply related

* [PATCH 13/13] Add new test case to ensure git-merge filters for independent parents
From: Miklos Vajna @ 2008-06-21 17:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <cover.1214066798.git.vmiklos@frugalware.org>

The old shell version used show-branch --independent to filter for the
ones that cannot be reached from any other reference.

The new C version uses filter_independent() from commit.c for this, so
add test to ensure it works as expected.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 t/t7603-merge-filter-independent.sh |   63 +++++++++++++++++++++++++++++++++++
 1 files changed, 63 insertions(+), 0 deletions(-)
 create mode 100755 t/t7603-merge-filter-independent.sh

diff --git a/t/t7603-merge-filter-independent.sh b/t/t7603-merge-filter-independent.sh
new file mode 100755
index 0000000..e9249cd
--- /dev/null
+++ b/t/t7603-merge-filter-independent.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+test_description='git-merge
+
+Testing octopus merge when filtering independent branches.'
+
+. ./test-lib.sh
+
+# 0 - 1
+#   \ 2
+#   \ 3
+#   \ 4 - 5
+#
+# So 1, 2, 3 and 5 should be kept, 4 should be filtered.
+
+test_expect_success 'setup' '
+	echo c0 > c0.c &&
+	git add c0.c &&
+	git commit -m c0 &&
+	git tag c0 &&
+	echo c1 > c1.c &&
+	git add c1.c &&
+	git commit -m c1 &&
+	git tag c1 &&
+	git reset --hard c0 &&
+	echo c2 > c2.c &&
+	git add c2.c &&
+	git commit -m c2 &&
+	git tag c2 &&
+	git reset --hard c0 &&
+	echo c3 > c3.c &&
+	git add c3.c &&
+	git commit -m c3 &&
+	git tag c3 &&
+	git reset --hard c0 &&
+	echo c4 > c4.c &&
+	git add c4.c &&
+	git commit -m c4 &&
+	git tag c4 &&
+	echo c5 > c5.c &&
+	git add c5.c &&
+	git commit -m c5 &&
+	git tag c5
+'
+
+test_expect_success 'merge c1 with c2, c3, c4, c5' '
+	git reset --hard c1 &&
+	git merge c2 c3 c4 c5 &&
+	test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" &&
+	test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" &&
+	test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" &&
+	test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" &&
+	test "$(git rev-parse c5)" = "$(git rev-parse HEAD^4)" &&
+	git diff --exit-code &&
+	test -f c0.c &&
+	test -f c1.c &&
+	test -f c2.c &&
+	test -f c3.c &&
+	test -f c4.c &&
+	test -f c5.c
+'
+
+test_done
-- 
1.5.6

^ permalink raw reply related

* Re: [PATCH 2/2] git-merge-recursive-{ours,theirs}
From: Jakub Narebski @ 2008-06-21 16:56 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin, geoffrey.russell, sverre, Johannes Sixt,
	Miklos Vajna, git
In-Reply-To: <7vy74z9l3l.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Actually, I think "git-merge-recursive-theirs" is a mistake.  We should
> bite the bullet and give "git-merge" an ability to pass backend specific
> parameters to "git-merge-recursive".  The new convention could be that
> anything that begins with -X is passed to the backend.
> 
> E.g.
> 
> 	git merge -Xfavor=theirs foo
>       git merge -Xsubtree=/=gitk-git paulus

Gaaah... only after reading it for third time I see that it isn't
some funky "=/=" symbol, but subtree with grafing '/' in one side
to 'gitk-git' subdirectory in other side.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH 2/2] git-merge-recursive-{ours,theirs}
From: Johannes Schindelin @ 2008-06-21 16:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: geoffrey.russell, sverre, Johannes Sixt, Miklos Vajna, git
In-Reply-To: <7vy74z9l3l.fsf@gitster.siamese.dyndns.org>

Hi,

On Sat, 21 Jun 2008, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> >> @@ -1379,11 +1401,18 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
> >>  	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
> >>  	int index_fd;
> >>  
> >> +	merge_recursive_variants = 0;
> >>  	if (argv[0]) {
> >>  		int namelen = strlen(argv[0]);
> >>  		if (8 < namelen &&
> >>  		    !strcmp(argv[0] + namelen - 8, "-subtree"))
> >> -			subtree_merge = 1;
> >> +			merge_recursive_variants = MERGE_RECURSIVE_SUBTREE;
> >> +		else if (5 < namelen &&
> >> +			 !strcmp(argv[0] + namelen - 5, "-ours"))
> >> +			merge_recursive_variants = MERGE_RECURSIVE_OURS;
> >> +		else if (7 < namelen &&
> >> +			 !strcmp(argv[0] + namelen - 7, "-theirs"))
> >> +			merge_recursive_variants = MERGE_RECURSIVE_THEIRS;
> >
> > This just cries out loud for a new function suffixcmp().
> 
> Actually, I think "git-merge-recursive-theirs" is a mistake.  We should
> bite the bullet and give "git-merge" an ability to pass backend specific
> parameters to "git-merge-recursive".

Fair enough.

> The new convention could be that anything that begins with -X is passed 
> to the backend.
> 
> E.g.
> 
> 	git merge -Xfavor=theirs foo
>         git merge -Xsubtree=/=gitk-git paulus
> 
> As you noticed already, subtree is just a funny optional behaviour
> attached to recursive, so are theirs and ours.  The above two would invoke
> git-merge-recursive like so:
> 
> 	git merge-recursive -Xfavor=theirs <base> -- HEAD MERGE_HEAD
> 	git merge-recursive -Xsubtree=/=gitk-git <base> -- HEAD MERGE_HEAD
> 
> We could even mix these two if we are ambitious.

Looks fine to me.  And much cleaner than the hardlinking.

Ciao,
Dscho

^ permalink raw reply

* Re: [RFC/PATCH] gitweb: Extend project_index file format by project description
From: Jakub Narebski @ 2008-06-21 16:09 UTC (permalink / raw)
  To: Lea Wiemann; +Cc: git
In-Reply-To: <485D1E76.6090709@gmail.com>

Lea Wiemann wrote:
> Jakub Narebski wrote:
>> 
>> The goal is to first, improve performance; and second, to be possible
>> to have single place for all info (well, amost all info) needed to
>> generate projects list.
> 
> I'm not sure if I understand your objective correctly.  If this is 
> exclusively about performance, may I suggest you wait with this till I 
> have implemented caching?  Regenerating the project list might end up 
> being fast enough that it won't matter at all; so no reason to 
> complicate the code.
> 
> If it's about the convenience of maintaining project descriptions in a 
> central place, sure, that's fine.

It is about both, but I think mainly about convenience of maintaining 
(having) all static data about project in one place (well, almost all: 
there is README.html, but it is not visible in projects list page).

What we gain in performance generating projects list (when caching is 
disabled for some reason, like limited quota or/and not installed 
memcached), we might lose when generating project pages (with project 
description).

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: avoiding committing personal cruft
From: David @ 2008-06-21 15:53 UTC (permalink / raw)
  To: git
In-Reply-To: <e5e204700806210620m35fce27eh8eddaf7cb68f1986@mail.gmail.com>

On Sat, Jun 21, 2008 at 3:20 PM, James Sadler <freshtonic@gmail.com> wrote:
>
> The ide-branch has nothing in it except the cruft from the IDE and the
> paths leading up to that cruft.
> The master branch has a .gitignore that ignores the IDE files so I
> won't end up polluting master by accident.
>
> It's a manageable solution for now.  I tend to think of it
> conceptually as 'layering' two branches: I want the
> content of both present in the working tree.
>
> I was just wondering if anyone else has tried something similar.
>

Sounds like a normal use of topic branches. Branches rebased against
master, where you you keep changes you don't want to go into the main
branch at this time.

David.

^ permalink raw reply

* Re: [RFC/PATCH] gitweb: Extend project_index file format by project description
From: Lea Wiemann @ 2008-06-21 15:29 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200806211540.58929.jnareb@gmail.com>

Jakub Narebski wrote:
> This is an RFC mainly because I don't know if it wouldn't conflict
> with Lea Wiemann work on adding caching support to gitweb;

If you're talking about merge conflicts, it applies fine on my current 
working copy.  (There's trailing whitespace on the "@pr_info =" line, by 
the way.)

> The goal is to first, improve performance; and second, to be possible
> to have single place for all info (well, amost all info) needed to
> generate projects list.

I'm not sure if I understand your objective correctly.  If this is 
exclusively about performance, may I suggest you wait with this till I 
have implemented caching?  Regenerating the project list might end up 
being fast enough that it won't matter at all; so no reason to 
complicate the code.

If it's about the convenience of maintaining project descriptions in a 
central place, sure, that's fine.

-- Lea

^ permalink raw reply

* "git-pull --no-commit" should imply --no-ff...?
From: Stefan Richter @ 2008-06-21 14:08 UTC (permalink / raw)
  To: git

Hi list,

trying "git pull --no-commit . foo" for the first time, I was confused
that --no-commit was a no-op when the pull resulted in a fast-forward.
I.e. HEAD advanced the whole chain of commits to foo.  I expected it to
apply the diff of HEAD..foo but not commit them.

I then learned that "git pull --no-ff --no-commit . foo" does what I
wanted.  What good does it do to ignore --no-commit in the fast-forward
case unless --no-ff is given?

This is with git 1.5.4.5.
-- 
Stefan Richter
-=====-==--- -==- =-=-=
http://arcgraph.de/sr/

^ permalink raw reply

* [RFC/PATCH] gitweb: Extend project_index file format by project description
From: Jakub Narebski @ 2008-06-21 13:40 UTC (permalink / raw)
  To: git; +Cc: Lea Wiemann

Change format of $projects_list file from
  <URI-encoded path> SPC <URI-encoded owner> LF
to
  <URI-encoded path> SPC \
  <URI-encoded owner> [SPC <URI-encoded description>] LF
with optional project description.  Please remember that only single
line of repository (project) description is supported.  Note that SPC
can be replaced by any whitespace character.

This change required modifying git_get_projects_list() subroutine
(part when $projects_list is a file, and not a directory to be
scanned), and git_get_project_description() subroutine.

The 'project_index' action now creates projects list index file in the
new format, with project description.  Also, it now does only minimal
level of escaping / encoding.


While at it, add some comments describing changes and changed
subroutines.  Update and extend information about $projects_list
format in gitweb/README and in gitweb/INSTALL.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This is an RFC mainly because I don't know if it wouldn't conflict
with Lea Wiemann work on adding caching support to gitweb; if it would,
I'll send separately the parts that enhance documentation (modified
of course to not include new feature).

The goal is to first, improve performance; and second, to be possible
to have single place for all info (well, amost all info) needed to
generate projects list.

I plan to submit to contrib small Perl script which would generate
projects list given (as argument) $projectroot, with minimal
dependencies, and minimal footprint.  The question is how to name
it...

 gitweb/INSTALL     |   10 +++++--
 gitweb/README      |   50 +++++++++++++++++++++++++++++++----
 gitweb/gitweb.perl |   74 ++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 112 insertions(+), 22 deletions(-)

diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index f7194db..7e25a7f 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -140,9 +140,13 @@ Gitweb repositories
 
   Each line of the projects list file should consist of the url-encoded path
   to the project repository database (relative to projectroot), followed
-  by the url-encoded project owner on the same line (separated by a space).
-  Spaces in both project path and project owner have to be encoded as either
-  '%20' or '+'.
+  by the url-encoded project owner on the same line (separated by a space),
+  and optionally followed by the url-encoded project description (separated
+  by space).  Spaces in project path, project owner and project description
+  have to be encoded as either '%20' or '+'.  Other whitespace (separator),
+  plus sign '+' (used as replacement for spaces), and percent sign '%' (used
+  for encoding / escaping) have to be url-encoded, i.e. replaced by '%'
+  followed by two-digit character number in octal.
 
   You can generate the projects list index file using the project_index
   action (the 'TXT' link on projects list page) directly from gitweb.
diff --git a/gitweb/README b/gitweb/README
index 356ab7b..a32a177 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -157,9 +157,12 @@ not include variables usually directly set during build):
  * $projects_list
    Source of projects list, either directory to scan, or text file
    with list of repositories (in the "<URI-encoded repository path> SPC
-   <URI-encoded repository owner>" format).  Set to $GITWEB_LIST
-   during installation.  If empty, $projectroot is used to scan for
-   repositories.
+   <URI-encoded repository owner>" line format, or optionally with
+   project description in "<URI-encoded repository path> SPC
+   <URI-encoded repository owner> SPC <URI-encoded description>";
+   actually there can be any sequence of whitespace in place of SPC).
+   Set to $GITWEB_LIST during installation.  If empty, $projectroot is
+   used to scan for repositories.
  * $my_url, $my_uri
    URL and absolute URL of gitweb script; you might need to set those
    variables if you are using 'pathinfo' feature: see also below.
@@ -214,6 +217,40 @@ not include variables usually directly set during build):
    ('-M'); set it to ('-C') or ('-C', '-C') to also detect copies, or
    set it to () if you don't want to have renames detection.
 
+
+Projects list file format
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instead of having gitweb find repositories by scanning filesystem starting
+from $projectroot (or $projects_list, if it points to directory), you can
+provide list of projects by setting $projects_list to a text file with list
+of projects (and some additional info).  This file uses the following
+format:
+
+One record (for project / repository) per line, whitespace separated fields;
+does not support (at least for now) lines continuation (newline escaping).
+Leading and trailing whitespace are ignored, any run of whitespace can be
+used as field separator (rules for Perl's "split(' ', $line)".  Keyed by
+the first field, which is project name, i.e. path to repository GIT_DIR
+relative to $projectroot.  Fields use modified URI encoding, defined in
+RFC 3986, section 2.1 (Percent-Encoding), or rather "Query string encoding"
+(see http://en.wikipedia.org/wiki/Query_string#URL_encoding), the difference
+being that SPC (' ') can be encoded as '+' (and therefore '+' has to be also
+percent-encoded).  Reserved characters are: '%' (used for encoding), '+'
+(can be used to encode SPACE), all whitespace characters as defined in Perl,
+including SPC, TAB and LF, (used to separate fields in a record).
+
+Currently list of fields is
+ * <repository path>  - path to repository GIT_DIR, relative to $projectroot
+ * <repository owner> - displayed as repository owner, preferably full name,
+                        or email, or both
+ * [<description>]    - one line repository description, OPTIONAL
+
+You can additionally use $projects_list file together with to limit which
+repositories are visible, and together with $strict_export to limit access
+to repositories (see "Gitweb repositories" section in gitweb/INSTALL).
+
+
 Per-repository gitweb configuration
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -225,8 +262,8 @@ You can use the following files in repository:
  * README.html
    A .html file (HTML fragment) which is included on the gitweb project
    summary page inside <div> block element. You can use it for longer
-   description of a project, to provide links for example to projects
-   homepage, etc.
+   description of a project, to provide links (for example to project's
+   homepage), etc.
  * description (or gitweb.description)
    Short (shortened by default to 25 characters in the projects list page)
    single line description of a project (of a repository). Plain text file;
@@ -243,7 +280,8 @@ You can use the following files in repository:
  * gitweb.owner
    You can use the gitweb.owner repository configuration variable to set
    repository's owner. It is displayed in the project list and summary
-   page. If it's not set, filesystem directory's owner is used.
+   page. If it's not set, filesystem directory's owner is used
+   (via GECOS field / real name field from getpwiud(3)).
  * various gitweb.* config variables (in config)
    Read description of %feature hash for detailed list, and some
    descriptions.
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 9c0dfbd..58144e7 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1710,13 +1710,44 @@ sub git_get_path_by_hash {
 ## ......................................................................
 ## git utility functions, directly accessing git repository
 
+# this is helper function for git_get_project_description()
+sub git_get_project_description_from_list {
+	my $path = shift;
+
+	open(my $fd, $projects_list)
+		or return;
+	while (my $line = <$fd>) {
+		chomp $line;
+		my ($proj, undef, $descr) = split ' ', $line;
+		$proj = unescape($proj);
+		$descr = unescape($descr);
+		if ($proj eq $path) {
+			close $fd;
+			return $descr;
+		}
+	}
+	close $fd;
+	return;
+}
+
+# sources for project description are
+#  * project_list, if $project_list is a file, and it uses new format:
+#    <encoded path> SPC <encoded owner> SPC <encoded description> LF
+#  * $GIT_DIR/description file in project repository, if it exists
+#  * gitweb.description configuration variable for a project
 sub git_get_project_description {
 	my $path = shift;
+	my $descr;
+
+	if (-f $projects_list) {
+		$descr = git_get_project_description_from_list($path);
+		return $descr if (defined $descr); # try other sources if needed
+	}
 
 	$git_dir = "$projectroot/$path";
 	open my $fd, "$git_dir/description"
 		or return git_get_project_config('description');
-	my $descr = <$fd>;
+	$descr = <$fd>;
 	close $fd;
 	if (defined $descr) {
 		chomp $descr;
@@ -1782,20 +1813,25 @@ sub git_get_projects_list {
 		}, "$dir");
 
 	} elsif (-f $projects_list) {
-		# read from file(url-encoded):
+		# read from file (whitespace separated, url-encoded):
 		# 'git%2Fgit.git Linus+Torvalds'
 		# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
 		# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
+		# optionally with description
+		# 'git/git.git Junio+C+Hamano The+core+git+plumbing'
+		# 'libs/klibc/klibc.git H.+Peter+Anvin klibc+main+development+tree'
+		# 'linux/hotplug/udev.git Kay+Sievers udev+development+tree'
 		my %paths;
 		open my ($fd), $projects_list or return;
 	PROJECT:
 		while (my $line = <$fd>) {
 			chomp $line;
-			my ($path, $owner) = split ' ', $line;
+			my ($path, $owner, $descr) = split ' ', $line;
 			$path = unescape($path);
 			$owner = unescape($owner);
+			$descr = unescape($descr);
 			if (!defined $path) {
-				next;
+				next PROJECT;
 			}
 			if ($filter ne '') {
 				# looking for forks;
@@ -1826,9 +1862,14 @@ sub git_get_projects_list {
 			}
 			if (check_export_ok("$projectroot/$path")) {
 				my $pr = {
-					path => $path,
+					path =>  to_utf8($path),
 					owner => to_utf8($owner),
 				};
+				if (defined $descr) {
+					$descr = to_utf8($descr);
+					$pr->{'descr_long'} = $descr;
+					$pr->{'descr'} = chop_str($descr, $projects_list_description_width, 5);
+				}
 				push @list, $pr;
 				(my $forks_path = $path) =~ s/\.git$//;
 				$paths{$forks_path}++;
@@ -3981,21 +4022,28 @@ sub git_project_index {
 	print $cgi->header(
 		-type => 'text/plain',
 		-charset => 'utf-8',
-		-content_disposition => 'inline; filename="index.aux"');
+		-content_disposition => 'inline; filename="projects_index.aux"');
 
 	foreach my $pr (@projects) {
 		if (!exists $pr->{'owner'}) {
 			$pr->{'owner'} = git_get_project_owner("$pr->{'path'}");
+			$pr->{'owner'} = to_utf8($pr->{'owner'});
+		}
+		if (!exists $pr->{'descr_long'}) {
+			$pr->{'descr_long'} = git_get_project_description($pr->{'path'}) || "";
+			$pr->{'descr_long'} = to_utf8($pr->{'descr_long'});
 		}
 
-		my ($path, $owner) = ($pr->{'path'}, $pr->{'owner'});
-		# quote as in CGI::Util::encode, but keep the slash, and use '+' for ' '
-		$path  =~ s/([^a-zA-Z0-9_.\-\/ ])/sprintf("%%%02X", ord($1))/eg;
-		$owner =~ s/([^a-zA-Z0-9_.\-\/ ])/sprintf("%%%02X", ord($1))/eg;
-		$path  =~ s/ /\+/g;
-		$owner =~ s/ /\+/g;
+		my @pr_info = 
+			($pr->{'path'}, $pr->{'owner'}, $pr->{'descr_long'});
+		foreach (@pr_info) {
+			# quote only minimal set, only what has to be quoted
+			s/([+%])/sprintf("%%%02X", ord($1))/eg;
+			s/ /\+/g;
+			s/([[:space:]])/sprintf("%%%02X", ord($1))/eg;
+		}
 
-		print "$path $owner\n";
+		print join(' ', @pr_info)."\n";
 	}
 }
 
-- 
1.5.6

^ permalink raw reply related

* avoiding committing personal cruft
From: James Sadler @ 2008-06-21 13:20 UTC (permalink / raw)
  To: git

I couldn't think of a better subject, so bear with me while I explain.

Let's say I am contributing to some upstream project, and I am hacking on it
inside my local repo's master branch.  Let's also say that I enjoy
using my favourite IDE
which creates its own project files and whatnot, and I don't want to
commit that stuff with the
rest of the project code.  It has no place being accidentally
pushed/pulled upstream.  It's
my personal cruft, hence the subject line.

However, I *do* want to version control my personal cruft, and I can
do that on a separate
branch.  But I want the content of that other branch to exist in the
working tree alongside my
checkout of master.

My current solution basically involves versioning the IDE files on
another branch (named ide-branch),
and using 'git checkout ide-branch .' to overlay the files on top of
the currently checked-out branch (master).

The ide-branch has nothing in it except the cruft from the IDE and the
paths leading up to that cruft.
The master branch has a .gitignore that ignores the IDE files so I
won't end up polluting master by accident.

It's a manageable solution for now.  I tend to think of it
conceptually as 'layering' two branches: I want the
content of both present in the working tree.

I was just wondering if anyone else has tried something similar.


 James.



-- 
Calvin Coolidge  - "I have never been hurt by what I have not said."

^ permalink raw reply

* Re: Are C++ contributions welcome?
From: David Kastrup @ 2008-06-21 12:42 UTC (permalink / raw)
  To: git
In-Reply-To: <200806201754.56806.josemaria@jmgv.org>

Jose María Gómez Vergara <josemaria@jmgv.org> writes:

> To be honest, I like a lot projects made in C. I have been working
> with Qt and with Gtk and I must say that it is easy for me to
> understand Gtk that is in C than Qt that is in C++. Something I feel
> like if C++ design do unnecessary abstration. The thing is that due to
> my job, I am more familiar with C++ since the project in which I work
> at my job is a really big monster that seems to be easier to manage
> using an a litter high level language as C++ instead C.
>
> I would like to learn more C, but sometime I think I should focus in
> one language and learn as much as possible about it.

This is sort of like discussing the most suitable alphabet for writing
poetry.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Miklos Vajna @ 2008-06-21 12:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vwskjazql.fsf@gitster.siamese.dyndns.org>

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

On Sat, Jun 21, 2008 at 02:44:50AM -0700, Junio C Hamano <gitster@pobox.com> wrote:
> * nd/dashless (Wed Nov 28 23:21:57 2007 +0700) 1 commit
>  + Move all dashed-form commands to libexecdir
> 
> Scheduled for 1.6.0.
> 
> * jc/dashless (Sat Dec 1 22:09:22 2007 -0800) 2 commits
>  - Prepare execv_git_cmd() for removal of builtins from the
>    filesystem
>  - git-shell: accept "git foo" form
> 
> We do not plan to remove git-foo form completely from the filesystem at
> this point, but git-shell may need to be updated.

I may be wrong, but given that git-upload-pack/receive-pack is now not
in PATH, I think it will be problematic to do a pull/push in case the
server runs next, the client is 1.5.6 and the user has git-shell as
shell, for example.

Or have I missed something?

Thanks

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* git-relink status (or bug?)
From: Marc Zonzon @ 2008-06-21 10:36 UTC (permalink / raw)
  To: git

When trying to use git-relink, I found it quite disappointing when
going over packs. Git relink seem to make the assumption that there is
a unique mapping from object name to object identity, which is of
course acceptable for loose objects that are named with their sha-1
but false for .pack and .idx, to pack objects with the same name have
contains the same objects but may be not packed in the same order, or
compression.
Moreover .idx files can not be considered alone, but depends on the
associated .pack.

When it happen that you have two different packs with the same name
but of different sizes, git relink does not hard link the .packs
because the size differ, and hard link the idx. And your repository is
corrupted.

It happen when you clone a repository, repack the clone and relink the
clone to the original one.

I found very few information about git relink, but as it appears in
changelog of v1.5.4 I suppose it is not obsoleted.

What about the use of this script?

Marc

^ permalink raw reply

* What's in git.git (stable)
From: Junio C Hamano @ 2008-06-21 10:06 UTC (permalink / raw)
  To: git
In-Reply-To: <7vwsknyz9m.fsf@gitster.siamese.dyndns.org>

* The 'maint' branch has now preparing for 1.5.6.1, with these noncritical
  fixes.

Brandon Casey (2):
  git-merge.sh: fix typo in usage message: sucesses --> succeeds
  t7502-commit.sh: test_must_fail doesn't work with inline environment
    variables

Dan McGee (1):
  completion: add --graph to log command completion

Jan Krüger (1):
  Documentation: fix formatting in git-svn


* The 'master' branch has these since the last announcement
  in addition to the above.  Not much to see here (yet).

Cristian Peraferrer (1):
  Print errno upon failure to open the COMMIT_EDITMSG file

Jakub Narebski (1):
  t/README: Add 'Skipping Tests' section below 'Running Tests'

Lea Wiemann (1):
  test-lib.sh: add --long-tests option

Lukas Sandström (1):
  Add a helper script to send patches with Mozilla Thunderbird

Shawn O. Pearce (1):
  Correct documentation for git-push --mirror

Teemu Likonen (2):
  bash: Add more option completions for 'git log'
  Add target "install-html" the the top level Makefile

^ permalink raw reply

* Re: MinGW port pull request
From: Junio C Hamano @ 2008-06-21  9:46 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Git Mailing List, msysGit
In-Reply-To: <485B6510.3080201@viscovery.net>

Johannes Sixt <j.sixt@viscovery.net> writes:

> please pull the MinGW (Windows) port patch series from
>
> git://repo.or.cz/git/mingw/j6t.git for-junio

Took a look.  A quick impression.

 * Too many whitespace breakages in borrowed compat/regex.[ch] are very
   distracting.

 * It is a very nice touch to rename sample templates to make sure they
   are not executable (after all they are just samples).

 * Shouldn't my_mktime() if exported out of date.c be named a bit better?

 * The ifdef block in git.c::main() introduces decl-after-stmt which we
   tend to avoid, but it is much worse to solve it by adding another ifdef
   block just to enclose decl of char *bslash at the beginning of the
   function.  Perhaps enclose it in an extra block?

 * In sanitary_path_copy(), you left "break;" after /* (1) */ but now that
   "break" is not inside a switch() anymore, so you are breaking out of
   something else, aren't you?  -- Ah, the clean-up phase will be no-op in
   that case because src points at '\0'.  Tricky but looks correct ;-)

 * There seem to be an unrelated general fix in upload-pack.c

 * There are still too many ifdefs.  I am wondering if the changes to
   pager and process stuff is easier to manage in the longer term if they
   are made into completely separate files (i.e. instead of linking
   pager.o you would link mingw-pager.o).  I dunno.

 * There is an interaction with dr/ceiling topic that is already in 'next'
   that needs to be resolved before we merge this in 'next'.

Parked in 'pu' for now but with a broken merge resolution.

^ permalink raw reply

* Re: [PATCH 2/2] git-merge-recursive-{ours,theirs}
From: Junio C Hamano @ 2008-06-21  9:46 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: geoffrey.russell, sverre, Johannes Sixt, Miklos Vajna, git
In-Reply-To: <alpine.DEB.1.00.0806201351370.6439@racer>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> @@ -1379,11 +1401,18 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
>>  	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
>>  	int index_fd;
>>  
>> +	merge_recursive_variants = 0;
>>  	if (argv[0]) {
>>  		int namelen = strlen(argv[0]);
>>  		if (8 < namelen &&
>>  		    !strcmp(argv[0] + namelen - 8, "-subtree"))
>> -			subtree_merge = 1;
>> +			merge_recursive_variants = MERGE_RECURSIVE_SUBTREE;
>> +		else if (5 < namelen &&
>> +			 !strcmp(argv[0] + namelen - 5, "-ours"))
>> +			merge_recursive_variants = MERGE_RECURSIVE_OURS;
>> +		else if (7 < namelen &&
>> +			 !strcmp(argv[0] + namelen - 7, "-theirs"))
>> +			merge_recursive_variants = MERGE_RECURSIVE_THEIRS;
>
> This just cries out loud for a new function suffixcmp().

Actually, I think "git-merge-recursive-theirs" is a mistake.  We should
bite the bullet and give "git-merge" an ability to pass backend specific
parameters to "git-merge-recursive".  The new convention could be that
anything that begins with -X is passed to the backend.

E.g.

	git merge -Xfavor=theirs foo
        git merge -Xsubtree=/=gitk-git paulus

As you noticed already, subtree is just a funny optional behaviour
attached to recursive, so are theirs and ours.  The above two would invoke
git-merge-recursive like so:

	git merge-recursive -Xfavor=theirs <base> -- HEAD MERGE_HEAD
	git merge-recursive -Xsubtree=/=gitk-git <base> -- HEAD MERGE_HEAD

We could even mix these two if we are ambitious.

^ permalink raw reply

* Re: [PATCH 1/2] t3404: extra checks and s/! git/test_must_fail git/
From: Junio C Hamano @ 2008-06-21  9:46 UTC (permalink / raw)
  To: Stephan Beyer
  Cc: nanako3, Brandon Casey, git, Johannes Schindelin,
	Christian Couder
In-Reply-To: <20080621014636.GG7369@leksak.fem-net>

Stephan Beyer <s-beyer@gmx.net> writes:

>> > Perhaps I'm not consequent, but I thought that it's not worth it ;-)
>> 
>> Doesn't that logic make the other s/!/test_must_fail/ changes
>> also not worth it?  What is the reason behind the change?
>
> The s/!/test_must_fail/ is just an "extra" like
>  "Hey, you're currently standing, can you bring me some tea?"

Counting the places that were affected, I would not call which one is primary
change and which one is extra.  The later half of your patch is all about
test_must_fail isn't it?

I am all for making tests more careful, and I think more use of
test_must_fail makes quite a lot of sense.  Please don't do a half-ass job if
you are doing the conversion anyway.

About the commit log message, I tend to agree that your original subject
looked ugly and it would have been nicer to just say "t3404: more strict
tests for git-rebase" or something like that, but probably an empty commit
message body would have been Ok.

^ permalink raw reply

* Re: [RFC/PATCH v2] gitweb: respect $GITPERLLIB
From: Junio C Hamano @ 2008-06-21  9:46 UTC (permalink / raw)
  To: Lea Wiemann; +Cc: git
In-Reply-To: <1213990547-7585-2-git-send-email-LeWiemann@gmail.com>

Lea Wiemann <lewiemann@gmail.com> writes:

> gitweb/gitweb.cgi now respects $GITPERLLIB, like the Perl-based Git
> commands.
>
> Signed-off-by: Lea Wiemann <LeWiemann@gmail.com>
> ---
> Changed since v1: Added missing INSTLIBDIR initialization.
>
> I just noticed that as of now Gitweb isn't using any Perl modules, so
> this change is actually not necessary yet; hence I'm making it an RFC
> patch.  I'll probably squash this into a larger "gitweb: use new
> Git::Repo API" patch (which I'll publish in a few days).
>
> Comments on this change to the Makefile are still appreciated, of
> course. :)
>
> -- Lea
>
>  Makefile |   10 +++++++++-
>  1 files changed, 9 insertions(+), 1 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 85c0846..64eeac1 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1083,7 +1083,15 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
>  
>  gitweb/gitweb.cgi: gitweb/gitweb.perl
>  	$(QUIET_GEN)$(RM) $@ $@+ && \
> -	sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
> +	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
> +	sed -e '1{' \
> +	    -e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
> +	    -e '	h' \
> +	    -e '	s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \
> +	    -e '	H' \
> +	    -e '	x' \
> +	    -e '}' \
> +	    -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
>  	    -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
>  	    -e 's|++GIT_BINDIR++|$(bindir)|g' \
>  	    -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \

This part seems to duplicate quite a bit of sed insn used elsewhere, and
we may want to factor the common part out, perhaps like this...

 Makefile |   25 ++++++++++++++-----------
 1 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/Makefile b/Makefile
index 6a31c9f..d3f1bde 100644
--- a/Makefile
+++ b/Makefile
@@ -1063,25 +1063,28 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
 perl/perl.mak: GIT-CFLAGS perl/Makefile perl/Makefile.PL
 	$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
 
+PERL_USE_LIB_REWRITE = \
+	-e '1{' \
+	-e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+	-e '	h' \
+	-e '	s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \
+	-e '	H' \
+	-e '	x' \
+	-e '}' \
+	-e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
+	-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g'
+
 $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
 	$(QUIET_GEN)$(RM) $@ $@+ && \
 	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
-	sed -e '1{' \
-	    -e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
-	    -e '	h' \
-	    -e '	s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \
-	    -e '	H' \
-	    -e '	x' \
-	    -e '}' \
-	    -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
-	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-	    $@.perl >$@+ && \
+	sed $(PERL_USE_LIB_REWRITE) $@.perl >$@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
 
 gitweb/gitweb.cgi: gitweb/gitweb.perl
 	$(QUIET_GEN)$(RM) $@ $@+ && \
-	sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
+	sed $(PERL_USE_LIB_REWRITE) \
 	    -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
 	    -e 's|++GIT_BINDIR++|$(bindir)|g' \
 	    -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \

^ permalink raw reply related

* [PATCH 2/2] Introduce reduce_heads()
From: Junio C Hamano @ 2008-06-21  9:45 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git
In-Reply-To: <1214007784-4801-1-git-send-email-vmiklos@frugalware.org>

The new function reduce_heads() is given a list of commits, and removes
ones that can be reached from other commits in the list.  It is useful for
reducing the commits randomly thrown at the git-merge command and remove
redundant commits that the user shouldn't have given to it.

The implementation uses the get_merge_bases_many() introduced in the
previous commit.  If the merge base between one commit taken from the list
and the remaining commits is the commit itself, that means the commit is
reachable from some of the other commits.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 * The important part of this patch is the addition to commit.c to show
   how I would write your filter_independent().  The new command is not
   essential, but is included as a demonstration.

 Makefile               |    1 +
 builtin-reduce-heads.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 builtin.h              |    1 +
 commit.c               |   45 +++++++++++++++++++++++++++++++++++++++++++++
 commit.h               |    2 ++
 git.c                  |    1 +
 6 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 builtin-reduce-heads.c

diff --git a/Makefile b/Makefile
index b003e3e..d660756 100644
--- a/Makefile
+++ b/Makefile
@@ -522,6 +522,7 @@ BUILTIN_OBJS += builtin-pack-refs.o
 BUILTIN_OBJS += builtin-prune-packed.o
 BUILTIN_OBJS += builtin-prune.o
 BUILTIN_OBJS += builtin-push.o
+BUILTIN_OBJS += builtin-reduce-heads.o
 BUILTIN_OBJS += builtin-read-tree.o
 BUILTIN_OBJS += builtin-reflog.o
 BUILTIN_OBJS += builtin-remote.o
diff --git a/builtin-reduce-heads.c b/builtin-reduce-heads.c
new file mode 100644
index 0000000..ff6178d
--- /dev/null
+++ b/builtin-reduce-heads.c
@@ -0,0 +1,44 @@
+#include "cache.h"
+#include "commit.h"
+#include "strbuf.h"
+
+static void show_commit_list(struct commit_list *list)
+{
+	while (list) {
+		struct strbuf it;
+		struct commit *commit = list->item;
+
+		list = list->next;
+		strbuf_init(&it, 128);
+		parse_commit(commit);
+		pretty_print_commit(CMIT_FMT_ONELINE, commit, &it,
+				    0, NULL, NULL, 0, 0);
+		puts(it.buf);
+		strbuf_release(&it);
+	}
+}
+
+int cmd_reduce_heads(int ac, const char **av, const char *prefix)
+{
+	struct commit_list *list = NULL, **tail = &list;
+	int i;
+
+	for (i = 1; i < ac; i++) {
+		struct commit *commit;
+		unsigned char sha1[20];
+
+		if (get_sha1(av[i], sha1))
+			die("'%s' is not a valid ref.", av[i]);
+		commit = lookup_commit_reference(sha1);
+		if (!commit)
+			die("cannot find commit %s", av[i]);
+		tail = &commit_list_insert(commit, tail)->next;
+	}
+
+	show_commit_list(list);
+	putchar('\n');
+
+	list = reduce_heads(list);
+	show_commit_list(list);
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index b460b2d..b6fb163 100644
--- a/builtin.h
+++ b/builtin.h
@@ -72,6 +72,7 @@ extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_config(int argc, const char **argv, const char *prefix);
+extern int cmd_reduce_heads(int argc, const char **argv, const char *prefix);
 extern int cmd_rerere(int argc, const char **argv, const char *prefix);
 extern int cmd_reset(int argc, const char **argv, const char *prefix);
 extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
diff --git a/commit.c b/commit.c
index 4ee234d..0fc4acb 100644
--- a/commit.c
+++ b/commit.c
@@ -690,3 +690,48 @@ int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 	free_commit_list(bases);
 	return ret;
 }
+
+struct commit_list *reduce_heads(struct commit_list *heads)
+{
+	struct commit_list *p;
+	struct commit_list *result = NULL, **tail = &result;
+	struct commit **other;
+	size_t num_head, num_other;
+
+	if (!heads)
+		return NULL;
+
+	/* Avoid unnecessary reallocations */
+	for (p = heads, num_head = 0; p; p = p->next)
+		num_head++;
+	other = xcalloc(sizeof(*other), num_head);
+
+	/* For each commit, see if it can be reached by others */
+	for (p = heads; p; p = p->next) {
+		struct commit_list *q, *base;
+
+		num_other = 0;
+		for (q = heads; q; q = q->next) {
+			if (p == q)
+				continue;
+			other[num_other++] = q->item;
+		}
+		if (num_other) {
+			base = get_merge_bases_many(p->item, num_other, other, 1);
+		} else
+			base = NULL;
+		/*
+		 * If p->item does not have anything common with other
+		 * commits, there won't be any merge base.  If it is
+		 * reachable from some of the others, p->item will be
+		 * the merge base.  If its history is connected with
+		 * others, but p->item is not reachable by others, we
+		 * will get something other than p->item back.
+		 */
+		if (!base || (base->item != p->item))
+			tail = &(commit_list_insert(p->item, tail)->next);
+		free_commit_list(base);
+	}
+	free(other);
+	return result;
+}
diff --git a/commit.h b/commit.h
index 2d94d41..ec95102 100644
--- a/commit.h
+++ b/commit.h
@@ -138,4 +138,6 @@ static inline int single_parent(struct commit *commit)
 	return commit->parents && !commit->parents->next;
 }
 
+struct commit_list *reduce_heads(struct commit_list *heads);
+
 #endif /* COMMIT_H */
diff --git a/git.c b/git.c
index 59f0fcc..23b690d 100644
--- a/git.c
+++ b/git.c
@@ -338,6 +338,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "prune-packed", cmd_prune_packed, RUN_SETUP },
 		{ "push", cmd_push, RUN_SETUP },
 		{ "read-tree", cmd_read_tree, RUN_SETUP },
+		{ "reduce-heads", cmd_reduce_heads, RUN_SETUP },
 		{ "reflog", cmd_reflog, RUN_SETUP },
 		{ "remote", cmd_remote, RUN_SETUP },
 		{ "repo-config", cmd_config },
-- 
1.5.6.6.gd3e97

^ permalink raw reply related

* [PATCH 1/2] Introduce get_merge_bases_many()
From: Junio C Hamano @ 2008-06-21  9:45 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git
In-Reply-To: <1214007784-4801-1-git-send-email-vmiklos@frugalware.org>

This introduces a new function get_merge_bases_many() which is a natural
extension of two commit merge base computation.  It is given one commit
(one) and a set of other commits (twos), and computes the merge base of
one and a merge across other commits.

This is mostly useful to figure out the common ancestor when iterating
over heads during an octopus merge.  When making an octopus between
commits A, B, C and D, we first merge tree of A and B, and then try to
merge C with it.  If we were making pairwise merge, we would be recording
the tree resulting from the merge between A and B as a commit, say M, and
then the next round we will be computing the merge base between M and C.

         o---C...*
        /       .
       o---B...M
      /       .
     o---o---A

But during an octopus merge, we actually do not create a commit M.  In
order to figure out that the common ancestor to use for this merge,
instead of computing the merge base between C and M, we can call
merge_bases_many() with one set to C and twos containing A and B.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 commit.c |   56 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/commit.c b/commit.c
index e2d8624..4ee234d 100644
--- a/commit.c
+++ b/commit.c
@@ -525,26 +525,34 @@ static struct commit *interesting(struct commit_list *list)
 	return NULL;
 }
 
-static struct commit_list *merge_bases(struct commit *one, struct commit *two)
+static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
 {
 	struct commit_list *list = NULL;
 	struct commit_list *result = NULL;
+	int i;
 
-	if (one == two)
-		/* We do not mark this even with RESULT so we do not
-		 * have to clean it up.
-		 */
-		return commit_list_insert(one, &result);
+	for (i = 0; i < n; i++) {
+		if (one == twos[i])
+			/*
+			 * We do not mark this even with RESULT so we do not
+			 * have to clean it up.
+			 */
+			return commit_list_insert(one, &result);
+	}
 
 	if (parse_commit(one))
 		return NULL;
-	if (parse_commit(two))
-		return NULL;
+	for (i = 0; i < n; i++) {
+		if (parse_commit(twos[i]))
+			return NULL;
+	}
 
 	one->object.flags |= PARENT1;
-	two->object.flags |= PARENT2;
 	insert_by_date(one, &list);
-	insert_by_date(two, &list);
+	for (i = 0; i < n; i++) {
+		twos[i]->object.flags |= PARENT2;
+		insert_by_date(twos[i], &list);
+	}
 
 	while (interesting(list)) {
 		struct commit *commit;
@@ -592,21 +600,26 @@ static struct commit_list *merge_bases(struct commit *one, struct commit *two)
 	return result;
 }
 
-struct commit_list *get_merge_bases(struct commit *one,
-					struct commit *two, int cleanup)
+struct commit_list *get_merge_bases_many(struct commit *one,
+					 int n,
+					 struct commit **twos,
+					 int cleanup)
 {
 	struct commit_list *list;
 	struct commit **rslt;
 	struct commit_list *result;
 	int cnt, i, j;
 
-	result = merge_bases(one, two);
-	if (one == two)
-		return result;
+	result = merge_bases_many(one, n, twos);
+	for (i = 0; i < n; i++) {
+		if (one == twos[i])
+			return result;
+	}
 	if (!result || !result->next) {
 		if (cleanup) {
 			clear_commit_marks(one, all_flags);
-			clear_commit_marks(two, all_flags);
+			for (i = 0; i < n; i++)
+				clear_commit_marks(twos[i], all_flags);
 		}
 		return result;
 	}
@@ -624,12 +637,13 @@ struct commit_list *get_merge_bases(struct commit *one,
 	free_commit_list(result);
 
 	clear_commit_marks(one, all_flags);
-	clear_commit_marks(two, all_flags);
+	for (i = 0; i < n; i++)
+		clear_commit_marks(twos[i], all_flags);
 	for (i = 0; i < cnt - 1; i++) {
 		for (j = i+1; j < cnt; j++) {
 			if (!rslt[i] || !rslt[j])
 				continue;
-			result = merge_bases(rslt[i], rslt[j]);
+			result = merge_bases_many(rslt[i], 1, &rslt[j]);
 			clear_commit_marks(rslt[i], all_flags);
 			clear_commit_marks(rslt[j], all_flags);
 			for (list = result; list; list = list->next) {
@@ -651,6 +665,12 @@ struct commit_list *get_merge_bases(struct commit *one,
 	return result;
 }
 
+struct commit_list *get_merge_bases(struct commit *one, struct commit *two,
+				    int cleanup)
+{
+	return get_merge_bases_many(one, 1, &two, cleanup);
+}
+
 int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 {
 	struct commit_list *bases, *b;
-- 
1.5.6.6.gd3e97

^ permalink raw reply related

* Re: [PATCH] Introduce filter_independent() in commit.c
From: Junio C Hamano @ 2008-06-21  9:45 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: git
In-Reply-To: <1214007784-4801-1-git-send-email-vmiklos@frugalware.org>

Miklos Vajna <vmiklos@frugalware.org> writes:

> +struct commit_list *filter_independent(unsigned char *head,
> +	struct commit_list *heads)
> +{
> +	struct commit_list *b, *i, *j, *k, *bases = NULL, *ret = NULL;
> +	struct commit_list **pptr = &ret;
> +
> +	commit_list_insert(lookup_commit(head), &heads);

Isn't the special casing of head making this function less easier to reuse
in other contexts?  "show-branch --independent" is about getting N commits
and removing commits from that set that can be reachable from another
commit, so there is no need nor reason to treat one "head" in any special
way.

> +	for (i = heads; i; i = i->next) {
> +		for (j = heads; j; j = j->next) {
> +			if (i == j)
> +				continue;
> +			b = get_merge_bases(i->item, j->item, 1);
> +			for (k = b; k; k = k->next)
> +				commit_list_insert(k->item, &bases);
> +		}
> +	}

You run (N-1)*N merge-base computation to get all pairwise merge-bases
here.  As merge-base(A,B) == merge-base(B,A), this is computing the same
thing twice.

Isn't your "b" leaking?

> +	for (i = heads; i; i = i->next) {
> +		int found = 0;
> +		for (b = bases; b; b = b->next) {
> +			if (!hashcmp(i->item->object.sha1, b->item->object.sha1)) {
> +				found = 1;

Then you see if the given heads exactly match one of the merge bases you
found earlier.  But does this have to be in a separate pass?

Isn't your "bases" list leaking?

Even though you may be able to reduce more than 25 heads, you run N^2
merge base traversals, which means 625 merge base traversals for 25 heads;
show-branch engine can do the same thing with a single traversal.

Can't we do better than O(N^2)?

Let's step back a bit and think.  You have N commits (stop thinking about
"my head and N other heads" like your function signature suggests).  For
each one, you would want to see if it is reachable from any of the other
(N-1) commits, and if so, you would exclude it from the resulting set.
And you do that for all N commits and you are done.  You can relatively
easily do this with an O(N) traversals.

Now, if you have one commit and other (N-1) commits, is there a way to
efficiently figure out if that one commit is reachable from any of the
other (N-1) commits?

If there were a merge of these other (N-1) commits, and if you compute a
merge base between that merge commit and the one commit you are looking
at, what would you get?  Yes, you will get your commit back if and only if
it is reachable from some of these (N-1) commits.

If you recall the merge-base-many patch we discussed earlier, that is
exactly what it computes, isn't it?

^ permalink raw reply

* What's cooking in git.git (topics)
From: Junio C Hamano @ 2008-06-21  9:44 UTC (permalink / raw)
  To: git
In-Reply-To: <7v3anb19n7.fsf@gitster.siamese.dyndns.org>

Here are the topics that have been cooking.  Commits prefixed
with '-' are only in 'pu' while commits prefixed with '+' are
in 'next'.

The topics list the commits in reverse chronological order.

It already is beginning to become clear what 1.6.0 will look like.  What's
already in 'next' all are well intentioned (I do not guarantee they are
already bug-free --- that is what cooking them in 'next' is for) and are
good set of feature enhancements.  But bigger changes will be:

 * MinGW will be in.

 * /usr/bin/git-cat-file is no more.  The bulk of the git commands will
   move to /usr/libexec/git-core/ or somesuch.

 * git-merge will be rewritten in C.

Currently tip of 'pu' is broken and does not pass tests, as j6t/mingw has
interaction with dr/ceiling and jc/merge-theirs has interaction with
mv/merge-in-c.

----------------------------------------------------------------
[New Topics]

* jc/merge-theirs (Fri Jun 20 00:17:59 2008 -0700) 2 commits
 - git-merge-recursive-{ours,theirs}
 - git-merge-file --ours, --theirs

Punting a merge by discarding your own work in conflicting parts but still
salvaging the parts that are cleanly automerged.  It is likely that this
will result in nonsense mishmash, but somehow often people want this, so
here they are.  The interface to the backends may need to change, though.

* lt/racy-empty (Tue Jun 10 10:44:43 2008 -0700) 1 commit
 + racy-git: an empty blob has a fixed object name

* ph/mergetool (Mon Jun 16 17:33:41 2008 -0600) 1 commit
 + Remove the use of '--' in merge program invocation

* j6t/mingw (Sat Nov 17 20:48:14 2007 +0100) 38 commits
 - compat/pread.c: Add a forward declaration to fix a warning
 - Windows: Fix ntohl() related warnings about printf formatting
 - Windows: TMP and TEMP environment variables specify a temporary
   directory.
 - Windows: Make 'git help -a' work.
 - Windows: Work around an oddity when a pipe with no reader is
   written to.
 - Windows: Make the pager work.
 - When installing, be prepared that template_dir may be relative.
 - Windows: Use a relative default template_dir and ETC_GITCONFIG
 - Windows: Compute the fallback for exec_path from the program
   invocation.
 - Turn builtin_exec_path into a function.
 - Windows: Use a customized struct stat that also has the st_blocks
   member.
 - Windows: Add a custom implementation for utime().
 - Windows: Add a new lstat and fstat implementation based on Win32
   API.
 - Windows: Implement a custom spawnve().
 - Windows: Implement wrappers for gethostbyname(), socket(), and
   connect().
 - Windows: Work around incompatible sort and find.
 - Windows: Implement asynchronous functions as threads.
 - Windows: Disambiguate DOS style paths from SSH URLs.
 - Windows: A rudimentary poll() emulation.
 - Windows: Change the name of hook scripts to make them not
   executable.
 - Windows: Implement start_command().
 - Windows: A pipe() replacement whose ends are not inherited to
   children.
 - Windows: Wrap execve so that shell scripts can be invoked.
 - Windows: Implement setitimer() and sigaction().
 - Windows: Fix PRIuMAX definition.
 - Windows: Implement gettimeofday().
 - Windows: Handle absolute paths in
   safe_create_leading_directories().
 - Windows: Treat Windows style path names.
 - setup.c: Prepare for Windows directory separators.
 - Windows: Work around misbehaved rename().
 - Windows: always chmod(, 0666) before unlink().
 - Windows: A minimal implemention of getpwuid().
 - Windows: Implement a wrapper of the open() function.
 - Windows: Strip ".exe" from the program name.
 - Windows: Use the Windows style PATH separator ';'.
 - Add target architecture MinGW.
 - Compile some programs only conditionally.
 - Add compat/regex.[ch] and compat/fnmatch.[ch].

No explanation is necessary ;-).

* sn/static (Thu Jun 19 08:21:11 2008 +0900) 2 commits
 + config.c: make git_env_bool() static
 + environment.c: remove unused function

* lt/config-fsync (Wed Jun 18 15:18:44 2008 -0700) 4 commits
 + Add config option to enable 'fsync()' of object files
 + Split up default "i18n" and "branch" config parsing into helper
   routines
 + Split up default "user" config parsing into helper routine
 + Split up default "core" config parsing into helper routine

* lw/gitweb (Thu Jun 19 22:03:21 2008 +0200) 1 commit
 + gitweb: standarize HTTP status codes

* mv/merge-in-c (Fri Jun 20 01:22:36 2008 +0200) 11 commits
 - Add new test to ensure git-merge handles more than 25 refs.
 - Build in merge
 - Introduce filter_independent() in commit.c
 - Introduce get_octopus_merge_bases() in commit.c
 - git-fmt-merge-msg: make it usable from other builtins
 - Move read_cache_unmerged() to read-cache.c
 - parseopt: add a new PARSE_OPT_ARGV0_IS_AN_OPTION option
 - Add new test to ensure git-merge handles pull.twohead and
   pull.octopus
 - Move parse-options's skip_prefix() to git-compat-util.h
 - Move commit_list_count() to commit.c
 - Move split_cmdline() to alias.c

* jc/maint-combine-diff-pre-context (Wed Jun 18 23:59:41 2008 -0700) 1 commit
 + diff -c/--cc: do not include uninteresting deletion before leading
   context

* lt/maint-gitdir-relative (Thu Jun 19 12:34:06 2008 -0700) 1 commit
 + Make git_dir a path relative to work_tree in setup_work_tree()

----------------------------------------------------------------
[Actively Cooking]

* nd/dashless (Wed Nov 28 23:21:57 2007 +0700) 1 commit
 + Move all dashed-form commands to libexecdir

Scheduled for 1.6.0.

* jc/dashless (Sat Dec 1 22:09:22 2007 -0800) 2 commits
 - Prepare execv_git_cmd() for removal of builtins from the
   filesystem
 - git-shell: accept "git foo" form

We do not plan to remove git-foo form completely from the filesystem at
this point, but git-shell may need to be updated.

* sg/merge-options (Sun Apr 6 03:23:47 2008 +0200) 1 commit
 + merge: remove deprecated summary and diffstat options and config
   variables

* dr/ceiling (Mon May 19 23:49:34 2008 -0700) 4 commits
 + Eliminate an unnecessary chdir("..")
 + Add support for GIT_CEILING_DIRECTORIES
 + Fold test-absolute-path into test-path-utils
 + Implement normalize_absolute_path

* jn/web (Tue Jun 10 19:21:44 2008 +0200) 2 commits
 + gitweb: Separate generating 'sort by' table header
 + gitweb: Separate filling list of projects info

* rs/archive-ignore (Sun Jun 8 18:42:33 2008 +0200) 1 commit
 + Teach new attribute 'export-ignore' to git-archive

* rg/gitweb (Fri Jun 6 09:53:32 2008 +0200) 1 commit
 + gitweb: remove git_blame and rename git_blame2 to git_blame

* kh/update-ref (Tue Jun 3 01:34:53 2008 +0200) 2 commits
 + Make old sha1 optional with git update-ref -d
 + Clean up builtin-update-ref's option parsing

* mo/status-untracked (Thu Jun 5 14:47:50 2008 +0200) 3 commits
 + Add configuration option for default untracked files mode
 + Add argument 'no' commit/status option -u|--untracked-files
 + Add an optional <mode> argument to commit/status -u|--untracked-
   files option

* sr/tests (Sun Jun 8 16:04:35 2008 +0200) 3 commits
 + Hook up the result aggregation in the test makefile.
 + A simple script to parse the results from the testcases
 + Modify test-lib.sh to output stats to t/test-results/*

* jh/clone-packed-refs (Sun Jun 15 16:06:16 2008 +0200) 4 commits
 + Teach "git clone" to pack refs
 + Prepare testsuite for a "git clone" that packs refs
 + Move pack_refs() and friends into libgit
 + Incorporate fetched packs in future object traversal

This is useful when cloning from a repository with insanely large number
of refs.

* jc/reflog-expire (Sun Jun 15 23:48:46 2008 -0700) 1 commit
 - Per-ref reflog expiry configuration

Perhaps a good foundation for optionally unexpirable stash.  As 1.6.0 will
be a good time to make backward incompatible changes, we might make expiry
period of stash 'never' in new repositories.  Needs a concensus.

* lw/perlish (Thu Jun 19 22:32:49 2008 +0200) 2 commits
 + Git.pm: add test suite
 + t/test-lib.sh: add test_external and test_external_without_stderr

Beginning of regression tests for Perl part of the system.

* jk/test (Sat Jun 14 03:28:07 2008 -0400) 5 commits
 + enable whitespace checking of test scripts
 + avoid trailing whitespace in zero-change diffstat lines
 + avoid whitespace on empty line in automatic usage message
 + mask necessary whitespace policy violations in test scripts
 + fix whitespace violations in test scripts

Tightens whitespace rules for t/*.sh scripts.

* pb/fast-export (Wed Jun 11 13:17:04 2008 +0200) 1 commit
 + builtin-fast-export: Add importing and exporting of revision marks

----------------------------------------------------------------
[Graduated to "master"]

Nothing today but expect many small ones to come out of 'next' this
weekend.

----------------------------------------------------------------
[On Hold]

* jc/blame (Wed Jun 4 22:58:40 2008 -0700) 7 commits
 - blame: show "previous" information in --porcelain/--incremental
   format
 - git-blame: refactor code to emit "porcelain format" output
 + git-blame --reverse
 + builtin-blame.c: allow more than 16 parents
 + builtin-blame.c: move prepare_final() into a separate function.
 + rev-list --children
 + revision traversal: --children option

The blame that finds where each line in the original lines moved to.  This
may help a GSoC project that wants to gather statistical overview of the
history.  The final presentation may need tweaking (see the log message of
the commit ""git-blame --reverse" on the series).

The tip two commits are for peeling to see what's behind the blamed
commit, which we should be able to separate out into an independent topic
from the rest.

* jc/send-pack-tell-me-more (Thu Mar 20 00:44:11 2008 -0700) 1 commit
 - "git push": tellme-more protocol extension

Kicked back to 'pu' for now.

* js/rebase-i-sequencer (Sun Apr 27 02:55:50 2008 -0400) 17 commits
 - Use perl instead of tac
 - Fix t3404 assumption that `wc -l` does not use whitespace.
 - rebase -i: Use : in expr command instead of match.
 - rebase -i: update the implementation of 'mark' command
 - Add option --preserve-tags
 - Teach rebase interactive the tag command
 - Add option --first-parent
 - Do rebase with preserve merges with advanced TODO list
 - Select all lines with fake-editor
 - Unify the length of $SHORT* and the commits in the TODO list
 - Teach rebase interactive the merge command
 - Move redo merge code in a function
 - Teach rebase interactive the reset command
 - Teach rebase interactive the mark command
 - Move cleanup code into it's own function
 - Don't append default merge message to -m message
 - fake-editor: output TODO list if unchanged

It is very likely that this whole thing will be reverted from 'next' and
be replaced with the new sequenser series during 1.6.0 cycle.

* sj/merge (Sat May 3 16:55:47 2008 -0700) 6 commits
 - Introduce fast forward option only
 - Head reduction before selecting merge strategy
 - Restructure git-merge.sh
 - Introduce -ff=<fast forward option>
 - New merge tests
 - Documentation for joining more than two histories

This will interfere with Miklos's rewrite of merge to C.

* jk/renamelimit (Sat May 3 13:58:42 2008 -0700) 1 commit
 - diff: enable "too large a rename" warning when -M/-C is explicitly
   asked for

This would be the right thing to do for command line use, but gitk will be
hit due to tcl/tk's limitation, so I am holding this back for now.

* jc/cherry-pick (Wed Feb 20 23:17:06 2008 -0800) 3 commits
 - WIP: rethink replay merge
 - Start using replay-tree merge in cherry-pick
 - revert/cherry-pick: start refactoring call to merge_recursive

This is meant to improve cherry-pick's behaviour when renames are
involved, by not using merge-recursive (whose d/f conflict resolution is
quite broken), but unfortunately has stalled for some time now.

* jc/stripspace (Sun Mar 9 00:30:35 2008 -0800) 6 commits
 - git-am --forge: add Signed-off-by: line for the author
 - git-am: clean-up Signed-off-by: lines
 - stripspace: add --log-clean option to clean up signed-off-by:
   lines
 - stripspace: use parse_options()
 - Add "git am -s" test
 - git-am: refactor code to add signed-off-by line for the committer

Just my toy at this moment.

^ permalink raw reply

* Re: [PATCH] Move deletion of configure generated files to distclean
From: shire @ 2008-06-21  7:33 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: git
In-Reply-To: <20080621013547.GF7369@leksak.fem-net>

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

On Jun 20, 2008, at 6:35 PM, Stephan Beyer wrote:

> Hi,
>
> whitespace and linebreaks are broken in your patch.
> (Just noticed because I needed a quick patch to test something and I
> took yours.)
>

Doh, thanks!  It appears there's no good simple way around the email  
body being munged in os x's mail.app, and I was mislead in my initial  
test email to myself.  I'll either fix mail.app in the future or send  
via some other mailer, I apologize for the obvious mistake despite  
all the guidelines in the patches file.  I've gone ahead and just  
attached the patch to this email that should apply cleanly with git-am.


[-- Attachment #2: 0001-Move-deletion-of-configure-generated-files-to-distcl.patch --]
[-- Type: application/octet-stream, Size: 1026 bytes --]

From 6c3ec53f54ca346f7fff38ee4ef748cac3c0f488 Mon Sep 17 00:00:00 2001
From: Brian Shire <shire@99-204-10-66.area1.spcsdns.net>
Date: Fri, 20 Jun 2008 17:53:51 -0700
Subject: [PATCH] Move deletion of configure generated files to distclean

---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index b003e3e..f868b0b 100644
--- a/Makefile
+++ b/Makefile
@@ -1346,6 +1346,7 @@ dist-doc:
 ### Cleaning rules
 
 distclean: clean
+	$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
 	$(RM) configure
 
 clean:
@@ -1355,7 +1356,6 @@ clean:
 	$(RM) $(TEST_PROGRAMS)
 	$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
 	$(RM) -r autom4te.cache
-	$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
 	$(RM) -r $(GIT_TARNAME) .doc-tmp-dir
 	$(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
 	$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
-- 
1.5.6.dirty


^ permalink raw reply related

* Re: Is git-imap-send able to use SSL?
From: Alam Arias @ 2008-06-21  5:16 UTC (permalink / raw)
  To: git
In-Reply-To: <D3F1364D-68DC-457D-AC54-AE4B70B1B5AB@gmail.com>

On Fri, 20 Jun 2008 18:08:42 +0200
Cristian Peraferrer <corellian.c@gmail.com> wrote:

> I am trying to use git-imap-send to send a Draft to my GMail account  
> which uses SSL to connect, I have put the correct port (993 in that  
> case) in the config file but it seems it doesn't work. I figure that  
> git-imap-send is not able to connect using SSL.
> 
 well, there a patch by for SSL support for git-imap-send by Rob
Shearman "robertshearman@gmail.com" over two weeks ago but it did not
apply cleanly on master at the time, well, maybe I can send
my version of this patch? or do I need to ask Rob Shearman?

^ 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