Git development
 help / color / mirror / Atom feed
* [PATCH] autoconf: Use autoconf to write installation directories to config.mak
From: Jakub Narebski @ 2006-06-29  1:01 UTC (permalink / raw)
  To: git

This is beginning of patch series introducing installation configuration
using autoconf (and no other autotools) to git. The idea is to generate
config.mak using ./configure (generated from configure.ac) from
config.mak.in, so one can use autoconf as an _alternative_ to ordinary
Makefile, and creating one's own config.mak.

This patch includes minimal configure.ac and config.mak.in, so one 
can set installation directories using ./configure script
e.g. ./configure --prefix=/usr

Ignoring files generated by running autoconf and ./configure

Signed-off-by: Jakub Narebski <jnareb@gmail.com>

---

One of the ideas is to use in .spec RPM macro %configure which takes
care of setting all installation directories correctly.

Thoughts?

 .gitignore    |    4 ++++
 config.mak.in |   12 ++++++++++++
 configure.ac  |   11 +++++++++++
 3 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7b954d5..b0dd54d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -136,3 +136,7 @@ git-core.spec
 *.py[co]
 config.mak
 git-blame
+autom4te.cache
+config.log
+config.status
+configure
diff --git a/config.mak.in b/config.mak.in
new file mode 100644
index 0000000..82d80e2
--- /dev/null
+++ b/config.mak.in
@@ -0,0 +1,12 @@
+# git Makefile configuration, included in main Makefile
+# @configure_input@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+#gitexecdir = @libexecdir@/git-core/
+template_dir = @datadir@/git-core/templates/
+GIT_PYTHON_DIR = @datadir@/git-core/python
+
+srcdir = @srcdir@
+VPATH = @srcdir@
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..4003ff6
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,11 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([git], [1.4.0], [git@vger.kernel.org])
+
+AC_CONFIG_SRCDIR([git.c])
+
+# Output files
+AC_CONFIG_FILES([config.mak])
+AC_OUTPUT
-- 
1.4.0

^ permalink raw reply related

* Re: CFT: merge-recursive in C (updated)
From: Junio C Hamano @ 2006-06-29  2:41 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <20060629002547.GA27507@steel.home>

fork0@t-online.de (Alex Riesen) writes:

> this broke t6022-merge-rename.sh (the second test). It produces an
> index with this:
>
> .../t/trash$ git-diff-index white
> :100644 100644 2d603156dc5bdf6295c789cac08e3c9942a0b82a 0000000000000000000000000000000000000000 M      B
> :100644 100644 ba41fb96393979b22691106b06bf5231eab57b85 0000000000000000000000000000000000000000 M      N
>
> whereas git-merge-recursive (and the previous version, without pipe):
>
> .../t/trash$ git-diff-index white
> :100644 100644 2d603156dc5bdf6295c789cac08e3c9942a0b82a 0000000000000000000000000000000000000000 M      B
>
> I can see that "git update-index --add" is somehow different from a
> pipe to "git update-index --index-info", but not very clear. Does this
> "zero-sha1" mean that the file "N" is not in the index?

When diff-index and diff-files compare a tree entry or an index
entry with a file in the working tree, they do not compute the
blob hash value for the file in the working tree.  0{40} is used
on the RHS in such a case.  When the working tree file matches
the corresponding index entry, then we know RHS matches what is
in the index, so both sides have the blob hash value.

^ permalink raw reply

* Re: [RFC] Cache negative delta pairs
From: Junio C Hamano @ 2006-06-29  3:09 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20060628223744.GA24421@coredump.intra.peff.net>

Jeff King <peff@peff.net> writes:

> From repack to repack, we end up trying to delta many of the same object
> pairs, which is computationally expensive.
>...
> I found this especially to be a problem with repos that consist of many
> large, unrelated files (e.g., photos). For example, on my test repo
> (about 300 unrelated 1-2M jpgs), a 'git-repack -a' takes about 10
> minutes to complete. With the delta cache, subsequent repacks take only
> 13 seconds. Results are not quite as dramatic for "normal" repos, but
> there is still some speedup. Repacking a fully packed linux-2.6 repo
> went from 1m12s to 36s. Repacking the git repo goes from 5.6s to 3.0s.

Interesting idea.  I think this matters more because for a
repository with many unrelated undeltifiable files, we do the
computation for objects that results in _no_ delta.  For normal
nearly fully packed repositories, once an object is deltified
against something else, subsequent repacking of the same set of
objects (or a superset thereof) will very likely reuse the delta
without recomputation, so as long as each object _can_ be
deltified with at least _one_ other object, you should not see
improvement on them.

So I am curious where the speed-up comes from for "normal" repos
in your experiments.  If it turns out that in "normal" repos the
objects that hit your negative cache are stored undeltified,
then that suggests that it might be worthwhile to consider using
a cache of "inherently undeltifiable objects", In other words, a
negative cache of O(N) entries, instead of O(N^2) entries,

Another interpretation of your result is that we may be using a
delta window that is unnecessarily too deep, and your negative
cache is collecting less optimum candidates that we attempt to
deltify against "just in case".  Can you easily instrument your
code to see where in the sorted delta candidate list the pairs
that hit your the negative cache are?  That is, in find_deltas()
function, we have "while (--j > 0)" loop that attempts to delta
with the entry that is j (modulo window size) entries away from
the current one, then j-1, j-2, ...; I am interested in the
distribution of "j" value for the pair "n,m" that hits your
negative cache for normal repositories, and I am speculating
that the value would probably be small relative to the delta
window size.

Another idea is to have a cache of "paths at which inherently
undeltifiable objects live in".  For example, we currently do
not delta OpenOffice documents (*.odt, *.odp, etc) very well.
If one has a repository that tracks the history of "file.odp",
we know each revision of "file.odp" would not delta against any
other version anyway, and could skip attempting to deltify them.

Your message contained string "*pt-in" in the commentary part
(replace asterisk with lowercase o) and was discarded by vger
mailing list software because that was a taboo word.  If you
would want to pursue this I would suggest to resend your
original patch after rephrasing that part.

>  - size. The cache is a packed sequence of binary sha1 pairs. I was
>    concerned that it would grow too large (obviously for n blobs you can
>    end up with n^2/2 entries), but it doesn't seem unreasonable for most
>    repos (either you don't have a lot of files, or if you do, they delta
>    reasonably well). My test repo's cache is only 144K. The git cache is
>    about 2.7M. The linux-2.6 cache is 22M.

The fully-packed object database is 6.2M pack so you are talking
about 40% bloat; the kernel is 115M so the overhead is 19%.

^ permalink raw reply

* Re: [RFC] Cache negative delta pairs
From: Jeff King @ 2006-06-29  3:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4py4y7wo.fsf@assigned-by-dhcp.cox.net>

On Wed, Jun 28, 2006 at 08:09:43PM -0700, Junio C Hamano wrote:

> Interesting idea.  I think this matters more because for a
> repository with many unrelated undeltifiable files, we do the
> computation for objects that results in _no_ delta.  For normal

Yes, precisely.

> So I am curious where the speed-up comes from for "normal" repos
> in your experiments.  If it turns out that in "normal" repos the

I assumed they were either:
  - blobs of files with only a single revision
  - blobs with one "island" revision which is so different from previous
    revisions that it isn't worth a delta
You can get a (very rough) estimate on the former:
  $ cd linux-2.6 && git-rev-list --objects --all \
     | grep / | cut -d' ' -f2 | sort | uniq -u | wc -l
  8364

As I said, we may also be catching possible deltas at the edge of the
pack depth. I should maybe put the cache check closer to the
create_delta call.

> objects that hit your negative cache are stored undeltified,
> then that suggests that it might be worthwhile to consider using
> a cache of "inherently undeltifiable objects", In other words, a
> negative cache of O(N) entries, instead of O(N^2) entries,

That would certainly be preferable, though I'm not convinced there
aren't objects which are deltifiable, but not right now (e.g., a file
with only one revision, but which will later get a revision).

I'm not sure what would make a file inherently undeltifiable. But you
could put the O(N) cache in front of the other cache, and reduce the
size of N for the O(N^2) cache. 

> deltify against "just in case".  Can you easily instrument your
> code to see where in the sorted delta candidate list the pairs
> that hit your the negative cache are?  That is, in find_deltas()

I'll look into that...

> Another idea is to have a cache of "paths at which inherently
> undeltifiable objects live in".  For example, we currently do
> not delta OpenOffice documents (*.odt, *.odp, etc) very well.
> If one has a repository that tracks the history of "file.odp",
> we know each revision of "file.odp" would not delta against any
> other version anyway, and could skip attempting to deltify them.

I thought about that, but I was trying to avoid "clever" heuristics that
can often be wrong. Case in point: my repo consists mainly of jpegs,
most of which will not delta. But for a few, I edited the exif header
and they delta'd nicely against their previous revision.

> Your message contained string "*pt-in" in the commentary part
> (replace asterisk with lowercase o) and was discarded by vger
> mailing list software because that was a taboo word.  If you

Oops, I didn't know we were filtering. I'll resend in a moment.

> >    reasonably well). My test repo's cache is only 144K. The git cache is
> >    about 2.7M. The linux-2.6 cache is 22M.
> The fully-packed object database is 6.2M pack so you are talking
> about 40% bloat; the kernel is 115M so the overhead is 19%.

Yes, obviously if you're interested in maximal space saving, this is
stupid for the classic git repo case (though it makes sense for repos
with few but very large blobs). However, if you assume that:
  1. Packing is inherently space-saving and more-or-less required on
     large repos like linux-2.6 (which is 1.8G unpacked and 115M packed)
  2. It saves time (36 seconds per repack on linux-2.6)
then a more reasonable question is "do you want to spend 22M to save 30
seconds every time you repack -a?". Or, to really cook the numbers, you
can say that the cache is only wasting 1% versus an unpacked repo. :)

I think it's reasonable that this should be an optional feature. For
some repos, it turns them from almost unusable to very fast. For others,
it's a questionable space-time tradeoff (and for some pathological
cases, it would probably turn the repo from usable to unusable).

-Peff

^ permalink raw reply

* [RFC] Cache negative delta pairs
From: Jeff King @ 2006-06-29  3:58 UTC (permalink / raw)
  To: git
In-Reply-To: <7v4py4y7wo.fsf@assigned-by-dhcp.cox.net>

>From repack to repack, we end up trying to delta many of the same object
pairs, which is computationally expensive.  This patch makes a
persistent cache, $GIT_DIR/delta-cache, which contains pairs of sha1
hashes (the presence of a pair indicates that it's not worth trying to
delta those two objects).

Signed-off-by: Jeff King <peff@peff.net>
---

[This is a repost, since the original got caught by the list filter.]

I found this especially to be a problem with repos that consist of many
large, unrelated files (e.g., photos). For example, on my test repo
(about 300 unrelated 1-2M jpgs), a 'git-repack -a' takes about 10
minutes to complete. With the delta cache, subsequent repacks take only
13 seconds. Results are not quite as dramatic for "normal" repos, but
there is still some speedup. Repacking a fully packed linux-2.6 repo
went from 1m12s to 36s. Repacking the git repo goes from 5.6s to 3.0s.

Here are some of my thoughts:

 - speed. The implementation is quite fast. The sha1 pairs are stored
   sorted, and we mmap and binary search them. Certainly the extra time
   spent in lookup is justified by avoiding the delta attempts.

 - size. The cache is a packed sequence of binary sha1 pairs. I was
   concerned that it would grow too large (obviously for n blobs you can
   end up with n^2/2 entries), but it doesn't seem unreasonable for most
   repos (either you don't have a lot of files, or if you do, they delta
   reasonably well). My test repo's cache is only 144K. The git cache is
   about 2.7M. The linux-2.6 cache is 22M.

   Theoretically, I could bound the cache size and boot old entries.
   However, that means storing age information, which increases the
   required size. I think keeping it simple is best.

 - correctness. Currently the code uses the output of try_delta for
   negative caching. Should the cache checking be moved inside try_delta
   instead? This would give more control over which reasons to mark a
   delta negative (I believe right now hitting the depth limit will
   cause a negative mark; we should perhaps only do so if the content
   itself makes the delta unpalatable).
 
 - optionalness. Currently the delta-cache is always used. Since it is a
   space-time tradeoff, maybe it should be optional (it will have
   negligible performance and horrible size impact on a repo that
   consists of many very small but unrelated objects).  Possible methods
   include:
     - enable cache saves only if .git/delta-cache is present; turn it
       on initially with 'touch .git/delta-cache'
     - config variable

 Makefile       |    4 +-
 delta-cache.c  |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 delta-cache.h  |   11 +++++
 pack-objects.c |   11 +++++
 4 files changed, 142 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index cde619c..39c4308 100644
--- a/Makefile
+++ b/Makefile
@@ -202,7 +202,7 @@ LIB_H = \
 	blob.h cache.h commit.h csum-file.h delta.h \
 	diff.h object.h pack.h pkt-line.h quote.h refs.h \
 	run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
-	tree-walk.h log-tree.h dir.h
+	tree-walk.h log-tree.h dir.h delta-cache.h
 
 DIFF_OBJS = \
 	diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -217,7 +217,7 @@ LIB_OBJS = \
 	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 pager.o tree-walk.o xdiff-interface.o \
-	alloc.o $(DIFF_OBJS)
+	alloc.o delta-cache.o $(DIFF_OBJS)
 
 BUILTIN_OBJS = \
 	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
diff --git a/delta-cache.c b/delta-cache.c
new file mode 100644
index 0000000..d132867
--- /dev/null
+++ b/delta-cache.c
@@ -0,0 +1,119 @@
+#include "delta-cache.h"
+#include "cache.h"
+
+static const unsigned char* disk_cache = 0;
+static unsigned disk_cache_len = 0;
+static unsigned char* mem_cache = 0;
+static unsigned mem_cache_len = 0;
+static unsigned mem_cache_alloc = 0;
+
+#define GETCACHE(c, n) (c+(40*n))
+
+static void disk_cache_init()
+{
+	static int done = 0;
+	int fd;
+	struct stat st;
+
+	if (done) return;
+	done = 1;
+
+	fd = open(git_path("delta-cache"), O_RDONLY);
+	if (fd < 0)
+		return;
+	if (fstat(fd, &st) || (st.st_size == 0)) {
+		close(fd);
+		return;
+	}
+	disk_cache = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	close(fd);
+	if (disk_cache != MAP_FAILED)
+		disk_cache_len = st.st_size / 40;
+}
+
+static int
+check_cache(const unsigned char* c, unsigned len, const unsigned char s[40])
+{
+	int left, right, mid, cmp;
+
+	left = 0;
+	right = len - 1;
+	while (left <= right) {
+		mid = left + (right - left) / 2;
+		cmp = memcmp(s, GETCACHE(c, mid), 40);
+		if(cmp == 0) return 1;
+		else if(cmp <  0) right = mid - 1;
+		else left = mid + 1;
+	}
+	return 0;
+}
+
+extern int
+delta_cache_check(const unsigned char a[20], const unsigned char b[20])
+{
+	unsigned char search[40];
+
+	disk_cache_init();
+	memcpy(search, a, 20);
+	memcpy(search+20, b, 20);
+	return check_cache(disk_cache, disk_cache_len, search);
+}
+
+extern void
+delta_cache_mark(const unsigned char a[20], const unsigned char b[20])
+{
+	if (mem_cache_len == mem_cache_alloc) {
+		mem_cache_alloc = mem_cache_alloc ? mem_cache_alloc * 2 : 16;
+		mem_cache = xrealloc(mem_cache, mem_cache_alloc * 40);
+	}
+	memcpy(GETCACHE(mem_cache, mem_cache_len), a, 20);
+	memcpy(GETCACHE(mem_cache, mem_cache_len)+20, b, 20);
+	mem_cache_len++;
+}
+
+static int
+compare_sha1pair(const void *a, const void *b)
+{
+	return memcmp(a, b, 40);
+}
+
+static int
+merge_write(int fd, const unsigned char* p1, unsigned n1,
+		    const unsigned char* p2, unsigned n2)
+{
+#define EMIT(p, x) do { \
+	if (xwrite(fd, GETCACHE(p, x), 40) < 0) return -1; x++; \
+	} while(0)
+
+	int i = 0, j = 0, cmp;
+	while (i < n1 && j < n2) {
+		cmp = memcmp(GETCACHE(p1, i), GETCACHE(p2, j), 40);
+		if (cmp < 0) EMIT(p1, i);
+		else EMIT(p2, j);
+	}
+	while (i < n1) EMIT(p1, i);
+	while (j < n2) EMIT(p2, j);
+#undef EMIT
+	return 0;
+}
+
+extern void
+delta_cache_save(void)
+{
+	int fd;
+	char tmpfile[PATH_MAX];
+
+	strcpy(tmpfile, git_path("delta-cache.%u", getpid()));
+	fd = open(tmpfile, O_WRONLY|O_EXCL|O_CREAT, 0666);
+	if (fd < 0)
+		return;
+
+	qsort(mem_cache, mem_cache_len, 40, compare_sha1pair);
+	if (merge_write(fd, mem_cache, mem_cache_len,
+			    disk_cache, disk_cache_len) < 0) {
+		close(fd);
+		return;
+	}
+
+	rename(tmpfile, git_path("delta-cache"));
+}
diff --git a/delta-cache.h b/delta-cache.h
new file mode 100644
index 0000000..19201be
--- /dev/null
+++ b/delta-cache.h
@@ -0,0 +1,11 @@
+#ifndef DELTA_CACHE_H
+#define DELTA_CACHE_H
+
+extern int
+delta_cache_check(const unsigned char a[20], const unsigned char b[20]);
+extern void
+delta_cache_mark(const unsigned char a[20], const unsigned char b[20]);
+extern void
+delta_cache_save(void);
+
+#endif /* DELTA_CACHE_H */
diff --git a/pack-objects.c b/pack-objects.c
index bed2497..46b9775 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -8,6 +8,7 @@ #include "delta.h"
 #include "pack.h"
 #include "csum-file.h"
 #include "tree-walk.h"
+#include "delta-cache.h"
 #include <sys/time.h>
 #include <signal.h>
 
@@ -1083,14 +1084,21 @@ static void find_deltas(struct object_en
 		j = window;
 		while (--j > 0) {
 			unsigned int other_idx = idx + j;
+			int r;
 			struct unpacked *m;
 			if (other_idx >= window)
 				other_idx -= window;
 			m = array + other_idx;
 			if (!m->entry)
 				break;
-			if (try_delta(n, m, m->index, depth) < 0)
+			if (delta_cache_check(n->entry->sha1, m->entry->sha1))
+				continue;
+			r = try_delta(n, m, m->index, depth);
+			if (r < 0)
 				break;
+			if (r == 0)
+				delta_cache_mark(n->entry->sha1,
+						 m->entry->sha1);
 		}
 		/* if we made n a delta, and if n is already at max
 		 * depth, leaving it in the window is pointless.  we
@@ -1342,5 +1350,6 @@ int main(int argc, char **argv)
 	if (progress)
 		fprintf(stderr, "Total %d, written %d (delta %d), reused %d (delta %d)\n",
 			nr_result, written, written_delta, reused, reused_delta);
+	delta_cache_save();
 	return 0;
 }
-- 
1.4.1.rc1.g3000

^ permalink raw reply related

* Re: [RFC] Cache negative delta pairs
From: Jeff King @ 2006-06-29  4:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4py4y7wo.fsf@assigned-by-dhcp.cox.net>

On Wed, Jun 28, 2006 at 08:09:43PM -0700, Junio C Hamano wrote:

> that hit your the negative cache are?  That is, in find_deltas()
> function, we have "while (--j > 0)" loop that attempts to delta
> with the entry that is j (modulo window size) entries away from
> the current one, then j-1, j-2, ...; I am interested in the
> distribution of "j" value for the pair "n,m" that hits your
> negative cache for normal repositories, and I am speculating
> that the value would probably be small relative to the delta
> window size.

Just to make sure I am understanding you correctly, you're interested in
the distribution of 'j' each time we skip a delta for being negative
(or each time we mark a negative, but that should simply equal the
lookup times for the next run). The instrumentation I added simply
prints the value of j each time we skip a delta. The counts are
surprisingly uniform (this is for linux-2.6):
  57209 j=1
  57213 j=2
  57217 j=3
  57221 j=4
  57225 j=5
  57229 j=6
  57233 j=7
  57237 j=8
  57241 j=9
  57245 j=10
They're so uniform (and in order by j!) that I feel like I must have done
something wrong...

-Peff

^ permalink raw reply

* Re: [RFC] Cache negative delta pairs
From: Jeff King @ 2006-06-29  4:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060629035849.GA30749@coredump.intra.peff.net>

On Wed, Jun 28, 2006 at 11:58:49PM -0400, Jeff King wrote:

>    about 2.7M. The linux-2.6 cache is 22M.
>    [...]
>  - correctness. Currently the code uses the output of try_delta for
>    negative caching. Should the cache checking be moved inside try_delta
>    instead? This would give more control over which reasons to mark a

I tried moving the cache check/mark to wrap the call to create_delta in
try_delta. The speedup is the same (since all of the CPU time is spent
in create_delta anyway), and the linux-2.6 cache size dropped to 18M.
I also think this is probably more correct (it ignores every reason not
to delta EXCEPT create_delta failing).

The distribution of the window parameter 'j' is similarly uniform:
  44900 j=2
  44907 j=3
  44943 j=1
  45001 j=4
  45014 j=5
  45023 j=6
  45063 j=7
  45158 j=8
  45288 j=9
  45466 j=10

Patch on top of my other one is below.

-Peff

-- >8 --
pack-objects: move delta-cache check/mark closer to create_delta

Signed-off-by: Jeff King <peff@peff.net>
---
 pack-objects.c |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/pack-objects.c b/pack-objects.c
index 46b9775..83ccc8a 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -1014,9 +1014,13 @@ static int try_delta(struct unpacked *tr
 	if (sizediff >= max_size)
 		return 0;
 
+	if (delta_cache_check(src->entry->sha1, trg->entry->sha1))
+		return 0;
 	delta_buf = create_delta(src_index, trg->data, size, &delta_size, max_size);
-	if (!delta_buf)
+	if (!delta_buf) {
+		delta_cache_mark(src->entry->sha1, trg->entry->sha1);
 		return 0;
+	}
 
 	trg_entry->delta = src_entry;
 	trg_entry->delta_size = delta_size;
@@ -1084,21 +1088,14 @@ static void find_deltas(struct object_en
 		j = window;
 		while (--j > 0) {
 			unsigned int other_idx = idx + j;
-			int r;
 			struct unpacked *m;
 			if (other_idx >= window)
 				other_idx -= window;
 			m = array + other_idx;
 			if (!m->entry)
 				break;
-			if (delta_cache_check(n->entry->sha1, m->entry->sha1))
-				continue;
-			r = try_delta(n, m, m->index, depth);
-			if (r < 0)
+			if (try_delta(n, m, m->index, depth) < 0)
 				break;
-			if (r == 0)
-				delta_cache_mark(n->entry->sha1,
-						 m->entry->sha1);
 		}
 		/* if we made n a delta, and if n is already at max
 		 * depth, leaving it in the window is pointless.  we
-- 
1.4.1.rc1.g0458-dirty

^ permalink raw reply related

* xdiff: generate "anti-diffs" aka what is common to two files
From: Linus Torvalds @ 2006-06-29  4:57 UTC (permalink / raw)
  To: Davide Libenzi, Junio C Hamano, Git Mailing List


This fairly trivial patch adds a new XDL_EMIT_xxx flag to tell libxdiff 
that we don't want to generate the _diff_ between two files, we want to 
see the lines that are _common_ to two files.

So when you set XDL_EMIT_COMMON, xdl_diff() will do everything exactly 
like it used to do, but the output records it generates just contain the 
lines that aren't part of the diff.

This is for doing things like generating the common base case for a file 
that was added in both branches.

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

Davide, I say it's a "fairly trivial patch", but quite frankly, I'm 
winging it. I'm not that comfortable with the libxdiff internal workings, 
so while this seems to work for me and make sense, can you please take a 
quick look.

Junio: the patch that actually _uses_ this comes next. It's based on my 
previous "throw-away" example patches, if you want me to base it on 
something else, please holler.

diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 2ce10b4..c9f8178 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -39,6 +39,7 @@ #define XDL_PATCH_MODEMASK ((1 << 8) - 1
 #define XDL_PATCH_IGNOREBSPACE (1 << 8)
 
 #define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_COMMON (1 << 1)
 
 #define XDL_MMB_READONLY (1 << 0)
 
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index ad5bfb1..3604ca1 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -100,6 +100,21 @@ static void xdl_find_func(xdfile_t *xf, 
 }
 
 
+int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+		    xdemitconf_t const *xecfg) {
+	xdfile_t *xdf = &xe->xdf1;
+	const char *rchg = xdf->rchg;
+	long ix;
+
+	for (ix = 0; ix < xdf->nrec; ix++) {
+		if (rchg[ix])
+			continue;
+		if (xdl_emit_record(xdf, ix, "", ecb))
+			return -1;
+	}
+	return 0;
+}		
+
 int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 		  xdemitconf_t const *xecfg) {
 	long s1, s2, e1, e2, lctx;
@@ -107,6 +122,9 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
 	char funcbuf[40];
 	long funclen = 0;
 
+	if (xecfg->flags & XDL_EMIT_COMMON)
+		return xdl_emit_common(xe, xscr, ecb, xecfg);
+
 	for (xch = xche = xscr; xch; xch = xche->next) {
 		xche = xdl_get_hunk(xch, xecfg);
 

^ permalink raw reply related

* Improved three-way blob merging code
From: Linus Torvalds @ 2006-06-29  5:06 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List; +Cc: Davide Libenzi


This fleshes out the code that generates a three-way merge of a set of 
blobs.

It still actually does the three-way merge using an external executable 
(ie just calling "merge"), but the interfaces have been cleaned up a lot 
and are now fully based on the 'mmfile_t' interface, so if libxdiff were 
to ever grow a compatible three-way-merge, it could probably be directly
plugged in.

It also uses the previous XDL_EMIT_COMMON functionality extension to 
libxdiff to generate a made-up base file for the merge for the case where 
no base file previously existed. This should be equivalent to what we 
currently do in git-merge-one-file.sh:

	diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add

except it should be much simpler and can be done using the direct libxdiff 
interfaces.

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

It would be lovely if libxdiff did a 3-way merge on its own, but this 
basically approximates it within that three_way_filemerge() function 
using external functionality.

The caller is, of course, still expected to do all the other proper magic 
(ie do things like resolve renames, mode differences, and all the trivial 
cases), and the example merge-tree.c code I posted earlier is obviously 
_not_ careful enough to be a real merge routine.

But we all have to start somewhere.


diff --git a/merge-file.c b/merge-file.c
index 4fedd6b..f32c653 100644
--- a/merge-file.c
+++ b/merge-file.c
@@ -1,19 +1,19 @@
 #include "cache.h"
 #include "run-command.h"
+#include "xdiff-interface.h"
 #include "blob.h"
 
 static void rm_temp_file(const char *filename)
 {
 	unlink(filename);
+	free((void *)filename);
 }
 
-static const char *write_temp_file(struct blob *blob)
+static const char *write_temp_file(mmfile_t *f)
 {
 	int fd;
 	const char *tmp = getenv("TMPDIR");
-	unsigned long size;
-	char *filename, type[20];
-	void *buf;
+	char *filename;
 
 	if (!tmp)
 		tmp = "/tmp";
@@ -22,13 +22,9 @@ static const char *write_temp_file(struc
 	if (fd < 0)
 		return NULL;
 	filename = strdup(filename);
-	buf = read_sha1_file(blob->object.sha1, type, &size);
-	if (buf) {
-		if (size != xwrite(fd, buf, size)) {
-			rm_temp_file(filename);
-			return NULL;
-		}
-		free(buf);
+	if (f->size != xwrite(fd, f->ptr, f->size)) {
+		rm_temp_file(filename);
+		return NULL;
 	}
 	close(fd);
 	return filename;
@@ -53,55 +49,118 @@ static void *read_temp_file(const char *
 	return buf;
 }
 
-void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
+static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
 {
-	const char *t1, *t2, *t3;
+	void *buf;
+	unsigned long size;
 	char type[20];
 
-	if (base) {
-		int code;
-		void *res;
-
-		/*
-		 * Removed in either branch?
-		 *
-		 * NOTE! This depends on the caller having done the
-		 * proper warning about removing a file that got
-		 * modified in the other branch!
-		 */
-		if (!our || !their)
-			return NULL;
-		t1 = write_temp_file(base);
-		t2 = write_temp_file(our);
-		t3 = write_temp_file(their);
-		res = NULL;
-		if (t1 && t2 && t3) {
-			code = run_command("merge", t2, t1, t3, NULL);
-			if (!code || code == -1)
-				res = read_temp_file(t2, size);
-		}
-		rm_temp_file(t1);
-		rm_temp_file(t2);
-		rm_temp_file(t3);
-		return res;
+	buf = read_sha1_file(obj->object.sha1, type, &size);
+	if (!buf)
+		return -1;
+	if (strcmp(type, blob_type))
+		return -1;
+	f->ptr = buf;
+	f->size = size;
+	return 0;
+}
+
+static void free_mmfile(mmfile_t *f)
+{
+	free(f->ptr);
+}
+
+static void *three_way_filemerge(mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
+{
+	void *res;
+	const char *t1, *t2, *t3;
+
+	t1 = write_temp_file(base);
+	t2 = write_temp_file(our);
+	t3 = write_temp_file(their);
+	res = NULL;
+	if (t1 && t2 && t3) {
+		int code = run_command("merge", t2, t1, t3, NULL);
+		if (!code || code == -1)
+			res = read_temp_file(t2, size);
 	}
+	rm_temp_file(t1);
+	rm_temp_file(t2);
+	rm_temp_file(t3);
+	return res;
+}
 
-	if (!our)
-		return read_sha1_file(their->object.sha1, type, size);
-	if (!their)
-		return read_sha1_file(our->object.sha1, type, size);
+static int common_outf(void *priv_, mmbuffer_t *mb, int nbuf)
+{
+	int i;
+	mmfile_t *dst = priv_;
+
+	for (i = 0; i < nbuf; i++) {
+		memcpy(dst->ptr + dst->size, mb[i].ptr, mb[i].size);
+		dst->size += mb[i].size;
+	}
+	return 0;
+}
+
+static int generate_common_file(mmfile_t *res, mmfile_t *f1, mmfile_t *f2)
+{
+	unsigned long size = f1->size < f2->size ? f1->size : f2->size;
+	void *ptr = xmalloc(size);
+	xpparam_t xpp;
+	xdemitconf_t xecfg;
+	xdemitcb_t ecb;
+
+	xpp.flags = XDF_NEED_MINIMAL;
+	xecfg.ctxlen = 3;
+	xecfg.flags = XDL_EMIT_COMMON;
+	ecb.outf = common_outf;
+
+	res->ptr = ptr;
+	res->size = 0;
+
+	ecb.priv = res;
+	return xdl_diff(f1, f2, &xpp, &xecfg, &ecb);
+}
+
+void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
+{
+	void *res = NULL;
+	mmfile_t f1, f2, common;
 
 	/*
-	 * Added in both!
-	 *
-	 * This is nasty.
-	 *
-	 * We should do something like 
+	 * Removed in either branch?
 	 *
-	 *	git diff our their | git-apply --no-add
-	 *
-	 * to generate a "minimal common file" to be used
-	 * as a base. Right now we punt.
+	 * NOTE! This depends on the caller having done the
+	 * proper warning about removing a file that got
+	 * modified in the other branch!
 	 */
-	return NULL;
+	if (!our || !their) {
+		char type[20];
+		if (base)
+			return NULL;
+		if (!our)
+			our = their;
+		return read_sha1_file(our->object.sha1, type, size);
+	}
+
+	if (fill_mmfile_blob(&f1, our) < 0)
+		goto out_no_mmfile;
+	if (fill_mmfile_blob(&f2, their) < 0)
+		goto out_free_f1;
+
+	if (base) {
+		if (fill_mmfile_blob(&common, base) < 0)
+			goto out_free_f2_f1;
+	} else {
+		if (generate_common_file(&common, &f1, &f2) < 0)
+			goto out_free_f2_f1;
+	}
+	res = three_way_filemerge(&common, &f1, &f2, size);
+	free_mmfile(&common);
+out_free_f2_f1:
+	free_mmfile(&f2);
+out_free_f1:
+	free_mmfile(&f1);
+out_no_mmfile:
+	return res;
 }

^ permalink raw reply related

* Re: xdiff: generate "anti-diffs" aka what is common to two files
From: Junio C Hamano @ 2006-06-29  6:04 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0606282149060.12404@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Junio: the patch that actually _uses_ this comes next. It's based on my 
> previous "throw-away" example patches, if you want me to base it on 
> something else, please holler.

Nah, I appreciate that you did it this way, because it gave me a
test case to "git-am" your two patches into a temporary branch
and "pull --squash" that into lt/merge-tree branch ;-).

	git am ./+LT.mbox
        ... two patches, applied with --whitespace=strip ...
	git tag -f CG
        git reset --hard HEAD^^
        git pull --squash . tag CG
        git commig -C CG
        git tag -d CG

^ permalink raw reply

* [ANNOUNCE] GIT 1.4.1-rc2
From: Junio C Hamano @ 2006-06-29  6:40 UTC (permalink / raw)
  To: git; +Cc: linux-kernel

The tip of "master" branch has been tagged as GIT 1.4.1-rc2.
Many fixes since v1.4.1-rc1 was done, but most notable are:

 - git-cvsimport to manage multiple branches are (hopefully)
   fixed now (Martin and Johannes).

 - git-rebase learned how to use 3-way merge backends by
   "git-rebase --merge" (Eric Wong).

 - git-svn updates (Eric Wong).

 - "git-commit -m" breakage was fixed (me).

Hopefully we can merge the format-patch fixes from Johannes,
which is still cooking in "next", and do the real 1.4.1 release
this weekend.

^ permalink raw reply

* What's in git.git
From: Junio C Hamano @ 2006-06-29  6:41 UTC (permalink / raw)
  To: git

Hopefully 'master' which I tagged and pushed out as v1.4.1-rc2
is very close to the final.  I would like to merge format-patch
fixes by Johannes, see nobody yells at me for a few days, and
call it 1.4.1 this weekend.

Thanks to Pavel Roskin and Marco Roeland, the Perly Git series
by Pasky should be in much better shape now.  Timo's diff output
format options updates is looking better and I am gaining
confidence in it, especially after I've done small testsuite and
fixed things here and there.  I would want a bit more tests to
cover wider combinations to avoid regression but basically it
looks ready.  These two series are still in "pu" and I'd like to
pull them into "next" after 1.4.1.

A late comer is Linus's merge-tree/merge-files work.  I'm
parking it on "pu" but haven't read it through yet.

----------------------------------------------------------------

* The 'master' branch has these since the last announcement.

   Andreas Ericsson:
      git wrapper: fix command name in an error message.

   Dennis Stosberg:
      Solaris needs inclusion of signal.h for signal()
      Fix pkt-line.h to compile with a non-GCC compiler
      Fix expr usage for FreeBSD

   Eric Wong:
      rebase: allow --merge option to handle patches merged upstream
      rebase: cleanup rebasing with --merge
      rebase: allow --skip to work with --merge
      git-svn: SVN 1.1.x library compatibility
      git-svn: several graft-branches improvements
      git-svn: add the commit-diff command
      git-svn: add --follow-parent and --no-metadata options to fetch
      git-svn: be verbose by default on fetch/commit, add -q/--quiet option
      rebase: get rid of outdated MRESOLVEMSG
      rebase: check for errors from git-commit

   Jeff King:
      quote.c: silence compiler warnings from EMIT macro

   Johannes Schindelin:
      Teach diff about -b and -w flags
      cvsimport: always set $ENV{GIT_INDEX_FILE} to $index{$branch}
      Save errno in handle_alias()

   Junio C Hamano:
      git-merge --squash
      diff --color: use $GIT_DIR/config
      combine-diff.c: type sanity
      connect.c: remove unused parameters from tcp_connect and proxy_connect
      connect.c: check the commit buffer boundary while parsing.
      t/README: start testing porcelainish
      checkout -m: fix read-tree invocation

   Martin Langhoff:
      cvsimport: setup indexes correctly for ancestors and incremental imports
      cvsimport - cleanup of the multi-indexes handling

   Matthias Lederhofer:
      correct documentation for git grep

   Timo Hirvonen:
      Make some strings const


* The 'next' branch, in addition, has these.

   Johannes Schindelin:
      add diff_flush_patch_id() to calculate the patch id
      format-patch: introduce "--ignore-if-in-upstream"
      t4014: fix for whitespace from "wc -l"
      format-patch: use clear_commit_marks() instead of some ad-hockery

   Junio C Hamano:
      Makefile: add framework to verify and bench sha1 implementations.
      test-sha1: test hashing large buffer
      git-repack: Be careful when updating the same pack as an existing one.
      t4013: add tests for diff/log family output options.
      t4014: add format-patch --ignore-if-in-upstream test
      t4013: add more tests around -c and --cc
      t4014: fix test commit labels.
      diff.c: fix get_patch_id()

   Linus Torvalds:
      xdiff: generate "anti-diffs" aka what is common to two files


* The 'pu' branch, in addition, has these.

   Dennis Stosberg:
      "test" in Solaris' /bin/sh does not support -e
      Makefile fix for Solaris
      Add possibility to pass CFLAGS and LDFLAGS specific to the perl subdir

   Junio C Hamano:
      Fix some more diff options changes.
      t4013 test updates for new output code.
      combine-diff.c: type sanity.
      Perl interface: add build-time configuration to allow building with -fPIC
      Perl interface: make testsuite work again.
      perl: fix make clean
      Git.pm: tentative fix to test the freshly built Git.pm
      Perly Git: arrange include path settings properly.
      Makefile: Set USE_PIC on x86-64

   Linus Torvalds:
      Prepare "git-merge-tree" for future work
      Improved three-way blob merging code

   Matthias Lederhofer:
      GIT_TRACE: show which built-in/external commands are executed

   Petr Baudis:
      Introduce Git.pm (v4)
      Git.pm: Implement Git::exec_path()
      Git.pm: Call external commands using execv_git_cmd()
      Git.pm: Implement Git::version()
      Add Error.pm to the distribution
      Git.pm: Better error handling
      Git.pm: Handle failed commands' output
      Git.pm: Enhance the command_pipe() mechanism
      Git.pm: Implement options for the command interface
      Git.pm: Add support for subdirectories inside of working copies
      Convert git-mv to use Git.pm
      Git.pm: assorted build related fixes.
      Git.pm: Try to support ActiveState output pipe
      Git.pm: Swap hash_object() parameters
      Git.pm: Fix Git->repository("/somewhere/totally/elsewhere")
      Git.pm: Support for perl/ being built by a different compiler

   Timo Hirvonen:
      Merge with_raw, with_stat and summary variables to output_format
      Make --raw option available for all diff commands
      Set default diff output format after parsing command line
      DIFF_FORMAT_RAW is not default anymore
      Add msg_sep to diff_options
      Don't xcalloc() struct diffstat_t
      whatchanged: Default to DIFF_FORMAT_RAW
      Print empty line between raw, stat, summary and patch
      diff-tree: Use ---\n as a message separator
      log --raw: Don't descend into subdirectories by default
      Fix diff-tree -s
      --name-only, --name-status, --check and -s are mutually exclusive
      Remove awkward compatibility warts
      Fix a mixed declarations and code warning

   Unknown:
      A better-scheduled PPC SHA-1 implementation.

^ permalink raw reply

* Re: Problem with GITK
From: Uwe Zeisberger @ 2006-06-29  7:06 UTC (permalink / raw)
  To: Paolo Ciarrocchi; +Cc: Git Mailing List
In-Reply-To: <4d8e3fd30606281340n147821e2hcbd4ccaf9551173f@mail.gmail.com>

Hi Paolo,

Paolo Ciarrocchi wrote:
> there is a strange orange line in the following screenshot from gitk:
> http://paolo.ciarrocchi.googlepages.com/Screenshotgit.png
> 
> paolo@Italia:~/linux-2.6$ git version
> git version 1.4.1.rc1.g47e5

Maybe

	http://www.gelato.unsw.edu.au/archives/git/0604/19509.html

can help you!?

Best regards
Uwe

-- 
Uwe Zeisberger

exit vi, lesson IV:
Z Z

NB: may write current file

^ permalink raw reply

* Re: [PATCH] autoconf: Use autoconf to write installation directories to config.mak
From: Uwe Zeisberger @ 2006-06-29  7:18 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200606290301.51657.jnareb@gmail.com>

Jakub Narebski wrote:
> This is beginning of patch series introducing installation configuration
> using autoconf (and no other autotools) to git. The idea is to generate
> config.mak using ./configure (generated from configure.ac) from
> config.mak.in, so one can use autoconf as an _alternative_ to ordinary
> Makefile, and creating one's own config.mak.
> 
> This patch includes minimal configure.ac and config.mak.in, so one 
> can set installation directories using ./configure script
> e.g. ./configure --prefix=/usr

autoconf does to much things, even with that little configure.ac.  (But
I agree, it's much better than automake :-)

E.g.

	./configure --prefix=$HOME/usr --mandir=$HOME/usr/share/man

is supported by the configure script, but the manpages are installed in
$HOME/usr/man all the same.

BTW: Even if I specify mandir=... in config.mak, it is not respected,
because only the toplevel Makefile includes config.mak.  (I didn't test
it, but I think I could export mandir in config.mak ...)

Best regards
Uwe

-- 
Uwe Zeisberger

http://www.google.com/search?q=1+hertz+in+sec**-1

^ permalink raw reply

* Re: Improved three-way blob merging code
From: Alex Riesen @ 2006-06-29  7:43 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List, Davide Libenzi
In-Reply-To: <Pine.LNX.4.64.0606282157210.12404@g5.osdl.org>

On 6/29/06, Linus Torvalds <torvalds@osdl.org> wrote:
> +static void *three_way_filemerge(mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
> +{
...
> +       if (t1 && t2 && t3) {
> +               int code = run_command("merge", t2, t1, t3, NULL);

This does not use the labels of merge(1) and the merged file will contain
the names of temporary files at conflict places, which is very confusing if
you happen to loose context while doing a merge with lots of conflicts.

^ permalink raw reply

* Re: CFT: merge-recursive in C (updated)
From: Alex Riesen @ 2006-06-29  8:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Schindelin, Fredrik Kuivinen, Linus Torvalds
In-Reply-To: <7vzmfwy97w.fsf@assigned-by-dhcp.cox.net>

[cc list restored, I'm lost in the maze of git update-index, all cache
changing functions looking almost the same]

On 6/29/06, Junio C Hamano <junkio@cox.net> wrote:
> > this broke t6022-merge-rename.sh (the second test). It produces an
> > index with this:
> >
> > .../t/trash$ git-diff-index white
> > :100644 100644 2d603156dc5bdf6295c789cac08e3c9942a0b82a 0000000000000000000000000000000000000000 M      B
> > :100644 100644 ba41fb96393979b22691106b06bf5231eab57b85 0000000000000000000000000000000000000000 M      N
> >
> > whereas git-merge-recursive (and the previous version, without pipe):
> >
> > .../t/trash$ git-diff-index white
> > :100644 100644 2d603156dc5bdf6295c789cac08e3c9942a0b82a 0000000000000000000000000000000000000000 M      B
> >
> > I can see that "git update-index --add" is somehow different from a
> > pipe to "git update-index --index-info", but not very clear. Does this
> > "zero-sha1" mean that the file "N" is not in the index?
>
> When diff-index and diff-files compare a tree entry or an index
> entry with a file in the working tree, they do not compute the
> blob hash value for the file in the working tree.  0{40} is used
> on the RHS in such a case.  When the working tree file matches
> the corresponding index entry, then we know RHS matches what is
> in the index, so both sides have the blob hash value.

Ok. Am I correct in the assumption, that if the file in working tree has
the same SHA1 as LHS, than the next "git-update-index --refresh" will
remove the entry from git-diff-index output?
This is what actually happens, if I do "git-update-index --refresh", so I
suspect that I have an SHA1 update gone missing somewhere.

^ permalink raw reply

* [PATCH] cogito: export user env in tutorial-script
From: Gerrit Pape @ 2006-06-29  8:58 UTC (permalink / raw)
  To: git

The GIT_* environment variables set in switch_user() must be exported to be
available to the programs run afterwards.

Signed-off-by: Gerrit Pape <pape@smarden.org>

---

 Documentation/tutorial-script/script.sh |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

f4d96a4ceda9b7ac7e2e29f4b017edf60360904c
diff --git a/Documentation/tutorial-script/script.sh b/Documentation/tutorial-script/script.sh
index b99e3c9..b0e49c8 100755
--- a/Documentation/tutorial-script/script.sh
+++ b/Documentation/tutorial-script/script.sh
@@ -52,10 +52,10 @@ switch_user () {
 		*) echo "I don't know you, $1"; exit 1;;
 	esac
 	HOME=$(pwd)
-	GIT_AUTHOR_NAME="$1"
-	GIT_AUTHOR_EMAIL="$1@example.com"
-	GIT_COMMITTER_NAME="$1"
-	GIT_COMMITTER_EMAIL="$1@example.com"
+	export GIT_AUTHOR_NAME="$1"
+	export GIT_AUTHOR_EMAIL="$1@example.com"
+	export GIT_COMMITTER_NAME="$1"
+	export GIT_COMMITTER_EMAIL="$1@example.com"
 }
 
 
-- 
1.3.3

^ permalink raw reply related

* [PATCH] cogito: selftests need bash
From: Gerrit Pape @ 2006-06-29  8:58 UTC (permalink / raw)
  To: git

Force bash for selftest scripts, as they fail with posix sh.

Signed-off-by: Gerrit Pape <pape@smarden.org>

---

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

0f3a68d543ebb55564bb4edca8a26722f6de8da8
diff --git a/t/Makefile b/t/Makefile
index 6882e23..b8e6eec 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -8,7 +8,7 @@ #GIT_TEST_OPTS=--verbose --debug
 T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
 
 all:
-	@$(foreach t,$T,echo "*** $t ***"; sh $t $(GIT_TEST_OPTS) || exit; )
+	@$(foreach t,$T,echo "*** $t ***"; bash $t $(GIT_TEST_OPTS) || exit; )
 	@rm -fr trash
 
 clean:
-- 
1.3.3

^ permalink raw reply related

* Re: [PATCH] Makefile: set USE_PIC on Linux x86_64 for linking with Git.pm
From: Sergey Vlasov @ 2006-06-29  9:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Marco Roeland, git, pasky
In-Reply-To: <7vbqsdynvu.fsf@assigned-by-dhcp.cox.net>

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

On Wed, 28 Jun 2006 14:24:37 -0700 Junio C Hamano wrote:

> Marco Roeland <marco.roeland@xs4all.nl> writes:
> 
> > Even for Linux someone mentioned that probably i386 is the exception in
> > _not_ needing the -fPIC linkage. It might even be specific to the Perl
> > "xs" implementation specifics?

In general, -fPIC is required when building shared libraries.  On some
systems (e.g., Linux/i386) you can get away without -fPIC, but with a
penalty on memory use and load time: non-PIC code will need relocations,
therefore its pages will no longer be shared between different
processes, and relocations will be performed immediately after loading
the shared library.

> USE_PIC is for pleasing Perly git and nothing else right now.
> 
> > So I should have added "Works for me (TM)"! ;-)
> 
> That would have been more explicit way to tell me that this is a
> partial solution and I should solicit help from people on other
> platforms.
> 
> By the way, I had an impression that compiling things with -fPIC
> when not necessary was generally a bad idea from performance
> point of view.  If that is the case we might want to compile,
> under USE_PIC, everything with -fPIC in a separate area to
> compile and link with Git.xs, without affecting the C-only core
> code.

This is exactly what libtool does (if both static and shared libraries
are compiled, each file is compiled twice - once with -fPIC -DPIC, and
once without these options).

But I suspect that even libtool won't help with Perl anyway, unless we
create a proper libgit.so and then link our Perl extension with it.

> I suspect this would largely depend on the architecture.  I ran
> git-fsck-objects compiled with and without -fPIC (after "make
> clean" to rebuild everything) on a fully packed copy of the
> linux-2.6 repository on my x86_64 box, and did not see
> meaningful differences:
> 
> : gitster; /usr/bin/time ../git.junio/git-fsck-objects-no-pic --full
> 109.71user 5.01system 1:54.89elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
> 0inputs+0outputs (14major+1834967minor)pagefaults 0swaps
> : gitster; /usr/bin/time ../git.junio/git-fsck-objects-with-pic --full
> 109.05user 4.97system 1:54.08elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
> 0inputs+0outputs (0major+1834981minor)pagefaults 0swaps
> : gitster;

This is because most of time is spent inside SHA-1 and zlib routines,
which are the same in these cases.  Using mozilla-sha1 code might show
some difference.

And the effect of -fPIC on x86_64 is smaller than on i386, because
x86_64 has 2x more registers than i386, therefore loss of one register
is less noticeable.

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

^ permalink raw reply

* Re: [RFC] GIT user survey
From: Jakub Narebski @ 2006-06-29  9:49 UTC (permalink / raw)
  To: git
In-Reply-To: <20060624221523.GA4335@spinlock.ch>

Matthias Kestenholz <lists@spinlock.ch> wrote:
> Adrien Beau (adrienbeau@gmail.com) wrote:
>> 
>> The results of the Mercurial survey have been posted there:
>> http://www.selenic.com/mercurial/wiki/index.cgi/UserSurvey
>> 
>> An interesting read.
> 
> I find the answers to the question, what people most like to see
> improved interesting: The improvement which got mentioned most often
> was "merge across rename", something which git does already.
> 
> It seems, that partial checkouts and truncated history are the
> only things left to implement for git from this list.

I think that at least some of the infrastructure for partial checkouts
is in place due to preliminary work for subproject (gitlink or bind)
support in git: git-read-tree and git-write-tree --prefix=<prefix>/
option suppport. But I might be mistaken.

Truncating history "by hand" is possible even now, using graft file.
There is recurring talk about "shallow clones", lately about "lazy clones".
There were mentioned here also split-history idea and sparse clone idea.  

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH 1/2] rebase: check for errors from git-commit
From: Eric Wong @ 2006-06-28  9:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wt94oom.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
> 
> >  I've grown used to having 'set -e' at the beginning of my shell
> >  scripts.  IMHO it'd be a good idea to start moving towards this
> >  eventually (even though shell scripts seem to be getting phased-out
> >  somewhat).
> >
> >  git-rebase.sh |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/git-rebase.sh b/git-rebase.sh
> > index 9ad1c44..47c8e8f 100755
> > --- a/git-rebase.sh
> > +++ b/git-rebase.sh
> > @@ -59,8 +59,8 @@ continue_merge () {
> >  
> >  	if test -n "`git-diff-index HEAD`"
> >  	then
> > +		git-commit -C "`cat $dotest/current`" || die 'Commit failed'
> >  		printf "Committed: %0${prec}d" $msgnum
> > -		git-commit -C "`cat $dotest/current`"
> 
> Anticipating failure from "git-commit" is the right thing to do,
> but this is a "Now what?" situation.  What is the expected
> course of action to recover from this for the end user, and how
> can we phrase the error message to help that process?

I would expect git-commit to show the correct error message (or the
pre-commit hook), die "$RESOLVEMSG" might be a better option, though.

-- 
Eric Wong

^ permalink raw reply

* Re: CFT: merge-recursive in C (updated)
From: Alex Riesen @ 2006-06-28  9:34 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Junio C Hamano, Fredrik Kuivinen,
	Linus Torvalds
In-Reply-To: <20060627223249.GA8177@steel.home>

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

On 6/28/06, Alex Riesen <fork0@t-online.de> wrote:
> Johannes Schindelin, Tue, Jun 27, 2006 18:42:51 +0200:
> > > - use a pipe to "git-update-index --index-info" instead of using command
> > > line

...and to take it a step further, a patch (0002) to avoid too many calls to
git-write-tree and to git-update-index. Brought merge times on my test
monster (~25k files) down to 2min 30sec (from something around 11 min).
The 0001 patch is just C++ comments.

[-- Attachment #2: 0001-update-comments-and-remove-C.txt --]
[-- Type: text/plain, Size: 13049 bytes --]

From 36147880afad3a2d53f6474bec069e29d82a74a8 Mon Sep 17 00:00:00 2001
From: Riesen <ARiesen@oekap852.hbi.ad.harman.com>
Date: Wed, 28 Jun 2006 09:46:47 +0200
Subject: update comments and remove C++ //...
---
 graph.c           |   14 ++++--
 merge-recursive.c |  131 +++++++++++++++++++++++++----------------------------
 path-list.c       |    2 -
 3 files changed, 72 insertions(+), 75 deletions(-)

diff --git a/graph.c b/graph.c
index fa2bfee..1a28302 100644
--- a/graph.c
+++ b/graph.c
@@ -5,7 +5,7 @@ #include "cache.h"
 #include "commit.h"
 #include "graph.h"
 
-// does not belong here
+/* does not belong here */
 struct tree *git_write_tree()
 {
 #if 0
@@ -189,8 +189,10 @@ struct node_list *node_list_find_node(co
 	return (struct node_list*)p;
 }
 
-// a & b. a and are invalid after the call,
-// the result will contain all the common nodes
+/*
+ * a & b. a and are invalid after the call,
+ * the result will contain all the common nodes
+ */
 struct node_list *node_list_intersect(struct node_list *a,
 				      struct node_list *b)
 {
@@ -214,7 +216,7 @@ struct node *graph_add_node(struct graph
 {
 	struct node_list **bucket;
 	if ( node->virtual )
-		// virtual nodes hashed by lowest byte of virtual_id
+		/* virtual nodes hashed by lowest byte of virtual_id */
 		bucket = graph->commits + (node->virtual_id & 0xff);
 	else
 		bucket = graph->commits + node->commit->object.sha1[0];
@@ -249,4 +251,6 @@ void node_list_print(const char *msg, co
 }
 #endif
 
-// vim: sw=8 noet
+/*
+vim: sw=8 noet
+*/
diff --git a/merge-recursive.c b/merge-recursive.c
index 9bbb426..ba5b024 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1,7 +1,7 @@
-//
-// Recursive Merge algorithm stolen from git-merge-recursive.py by
-// Fredrik Kuivinen.
-//
+/*
+ * Recursive Merge algorithm stolen from git-merge-recursive.py by
+ * Fredrik Kuivinen.
+ */
 #include <stdarg.h>
 #include <string.h>
 #include <assert.h>
@@ -47,7 +47,7 @@ struct index_entry
 
 struct index_entry *index_entry_alloc(const char *path)
 {
-	size_t n = strlen(path); // index_entry::path has room for \0
+	size_t n = strlen(path); /* index_entry::path has room for \0 */
 	struct index_entry *p = xmalloc(sizeof(struct index_entry) + n);
 	if ( !p )
 		return NULL;
@@ -102,14 +102,16 @@ static void setup_index(int temp)
 	setenv("GIT_INDEX_FILE", idx, 1);
 }
 
-// This is a global variable which is used in a number of places but
-// only written to in the 'merge' function.
-
-// index_only == 1    => Don't leave any non-stage 0 entries in the cache and
-//                       don't update the working directory.
-//               0    => Leave unmerged entries in the cache and update
-//                       the working directory.
-static int index_only = 0; // cacheOnly
+/*
+ * This is a global variable which is used in a number of places but
+ * only written to in the 'merge' function.
+ *
+ * index_only == 1    => Don't leave any non-stage 0 entries in the cache and
+ *                       don't update the working directory.
+ *               0    => Leave unmerged entries in the cache and update
+ *                       the working directory.
+ */
+static int index_only = 0;
 
 static int git_read_tree(const struct tree *tree)
 {
@@ -157,10 +159,10 @@ struct merge_tree_result merge_trees(str
 
 static int fget_sha1(unsigned char *sha, FILE *fp, int *ch);
 
-// The entry point to the merge code
-
-// Merge the commits h1 and h2, return the resulting virtual
-// commit object and a flag indicating the cleaness of the merge.
+/*
+ * Merge the commits h1 and h2, return the resulting virtual
+ * commit object and a flag indicating the cleaness of the merge.
+ */
 static
 struct merge_result merge(struct node *h1,
 			  struct node *h2,
@@ -262,7 +264,7 @@ typedef int (*read_tree_rt_fn_t)(const c
 				 unsigned mode,
 				 void *data);
 
-// git-ls-tree -r -t <tree>
+/* git-ls-tree -r -t <tree> */
 static int read_tree_rt(struct tree *tree,
 			const char *base,
 			int baselen,
@@ -391,8 +393,10 @@ static int find_entry(const char *sha,
 	return READ_TREE_RECURSIVE;
 }
 
-// Returns a CacheEntry object which doesn't have to correspond to
-// a real cache entry in Git's index.
+/*
+ * Returns a index_entry instance which doesn't have to correspond to
+ * a real cache entry in Git's index.
+ */
 struct index_entry *index_entry_from_db(const char *path,
 					struct tree *o,
 					struct tree *a,
@@ -404,24 +408,18 @@ struct index_entry *index_entry_from_db(
 	data.sha = e->stages[1].sha;
 	data.mode = &e->stages[1].mode;
 	if ( read_tree_rt(o, "", 0, find_entry, &data) != READ_TREE_FOUND ) {
-		// fprintf(stderr, "1: %s:%s not found\n",
-		// 	sha1_to_hex(o->object.sha1), path);
 		memcpy(e->stages[1].sha, null_sha1, 20);
 		e->stages[1].mode = 0;
 	}
 	data.sha = e->stages[2].sha;
 	data.mode = &e->stages[2].mode;
 	if ( read_tree_rt(a, "", 0, find_entry, &data) != READ_TREE_FOUND ) {
-		// fprintf(stderr, "2: %s:%s not found\n",
-		// 	sha1_to_hex(a->object.sha1), path);
 		memcpy(e->stages[2].sha, null_sha1, 20);
 		e->stages[2].mode = 0;
 	}
 	data.sha = e->stages[3].sha;
 	data.mode = &e->stages[3].mode;
 	if ( read_tree_rt(b, "", 0, find_entry, &data) != READ_TREE_FOUND ) {
-		// fprintf(stderr, "3: %s:%s not found\n",
-		// 	sha1_to_hex(b->object.sha1), path);
 		memcpy(e->stages[3].sha, null_sha1, 20);
 		e->stages[3].mode = 0;
 	}
@@ -469,8 +467,11 @@ static int fget_sha1(unsigned char *sha,
 		return -1;
 	return 0;
 }
-// Create a dictionary mapping file names to CacheEntry objects. The
-// dictionary contains one entry for every path with a non-zero stage entry.
+
+/*
+ * Create a dictionary mapping file names to CacheEntry objects. The
+ * dictionary contains one entry for every path with a non-zero stage entry.
+ */
 struct index_entry *unmergedCacheEntries()
 {
 	struct index_entry *unmerged = NULL;
@@ -484,17 +485,17 @@ struct index_entry *unmergedCacheEntries
 		char stage = '0';
 		char path[PATH_MAX];
 		int p;
-		// mode
+		/* mode */
 		if ( fget_mode(&mode, fp, &ch) )
 			goto wait_eol;
 		if ( '\x20' != ch )
 			goto wait_eol;
-		// SHA1
+		/* SHA1 */
 		if ( fget_sha1(sha, fp, &ch) )
 			goto wait_eol;
 		if ( '\x20' != ch )
 			goto wait_eol;
-		// stage
+		/* stage */
 		if ( (ch = fgetc(fp)) != EOF ) {
 			stage = ch;
 			if ( ch < '1' || ch > '3' )
@@ -502,7 +503,7 @@ struct index_entry *unmergedCacheEntries
 		}
 		if ( (ch = fgetc(fp)) == EOF || '\t' != ch )
 			goto wait_eol;
-		// path
+		/* path */
 		for ( p = 0; (ch = fgetc(fp)) != EOF; ++p ) {
 			path[p] = ch;
 			if ( !ch )
@@ -515,7 +516,6 @@ struct index_entry *unmergedCacheEntries
 		}
 		if ( ch )
 			goto wait_eol;
-		// printf("unmerged %08o %s %c %s\n",mode,sha1_to_hex(sha),stage,path);
 		struct index_entry *e = index_entry_get(&unmerged, path);
 		e->stages[stage - '1' + 1].mode = mode;
 		memcpy(e->stages[stage - '1' + 1].sha, sha, 20);
@@ -583,10 +583,12 @@ void free_rename_entries(struct rename_e
 	}
 }
 
-// Get information of all renames which occured between 'oTree' and
-// 'tree'. We need the three trees in the merge ('oTree', 'aTree' and
-// 'bTree') to be able to associate the correct cache entries with
-// the rename information. 'tree' is always equal to either aTree or bTree.
+/*
+ * Get information of all renames which occured between 'oTree' and
+ * 'tree'. We need the three trees in the merge ('oTree', 'aTree' and
+ * 'bTree') to be able to associate the correct cache entries with
+ * the rename information. 'tree' is always equal to either aTree or bTree.
+ */
 struct rename_entry *getRenames(struct tree *tree,
 				struct tree *oTree,
 				struct tree *aTree,
@@ -831,7 +833,6 @@ void updateFileExt(FILE *fp,
 	}
 	if ( updateCache )
 	{
-		// XXX just always use "git update-index --index-info"?
 		fprintf(fp, "%06o %s\t%s", mode, sha1_to_hex(sha), path);
 		fputc('\0', fp);
 	}
@@ -846,8 +847,8 @@ void updateFile(FILE *fp,
 	updateFileExt(fp, sha, mode, path, index_only || clean, !index_only);
 }
 
-// Low level file merging, update and removal
-// ------------------------------------------
+/* Low level file merging, update and removal */
+
 struct merge_file_info
 {
 	unsigned char sha[20];
@@ -991,9 +992,6 @@ int processRenames(struct rename_entry *
 		   const char *branchNameB)
 {
 	int cleanMerge = 1;
-	//    printf("process renames %s:%s -> %s:%s\n",
-	//	   branchNameA, renamesA ? renamesA->src: "(none)",
-	//	   branchNameB, renamesB ? renamesB->dst: "(none)");
 
 	struct path_list srcNames = {NULL, 0, 0};
 	const struct rename_entry *sre;
@@ -1033,7 +1031,7 @@ int processRenames(struct rename_entry *
 		ren1->processed = 1;
 
 		if ( ren2 ) {
-			// Renamed in 1 and renamed in 2
+			/* Renamed in 1 and renamed in 2 */
 			if ( strcmp(ren1->src, ren2->src) != 0 )
 				die("ren1.srcName != ren2.srcName");
 			ren2->dst_entry->processed = 1;
@@ -1097,7 +1095,7 @@ int processRenames(struct rename_entry *
 				updateFile(fp, mfi.clean, mfi.sha, mfi.mode, ren1->dst);
 			}
 		} else {
-			// Renamed in 1, maybe changed in 2
+			/* Renamed in 1, maybe changed in 2 */
 			removeFile(fp, 1, ren1->src);
 
 			unsigned char srcShaOtherBranch[20], dstShaOtherBranch[20];
@@ -1224,15 +1222,15 @@ static int sha_eq(const unsigned char *a
 	return a && b && memcmp(a, b, 20) == 0;
 }
 
-// Per entry merge function
-// ------------------------
-// Merge one cache entry.
+/* Per entry merge function */
 int processEntry(struct index_entry *entry,
 		 const char *branch1Name,
 		 const char *branch2Name)
 {
-	//    printf("processing entry, clean cache: %s\n", index_only ? "yes": "no");
-	//    print_index_entry("\tpath: ", entry);
+	/*
+	printf("processing entry, clean cache: %s\n", index_only ? "yes": "no");
+	print_index_entry("\tpath: ", entry);
+	*/
 	int cleanMerge = 1;
 	const char *path = entry->path;
 	unsigned char *oSha = has_sha(entry->stages[1].sha);
@@ -1244,18 +1242,17 @@ int processEntry(struct index_entry *ent
 	FILE *fp = git_update_index_pipe();
 
 	if ( oSha && (!aSha || !bSha) ) {
-		//
-		// Case A: Deleted in one
-		//
+		/* Case A: Deleted in one */
 		if ( (!aSha && !bSha) ||
 		     (sha_eq(aSha, oSha) && !bSha) ||
 		     (!aSha && sha_eq(bSha, oSha)) ) {
-			// Deleted in both or deleted in one and unchanged in the other
+			/* Deleted in both or deleted in one and
+			 * unchanged in the other */
 			if ( aSha )
 				output("Removing %s", path);
 			removeFile(fp, 1, path);
 		} else {
-			// Deleted in one and changed in the other
+			/* Deleted in one and changed in the other */
 			cleanMerge = 0;
 			if ( !aSha ) {
 				output("CONFLICT (delete/modify): %s deleted in %s "
@@ -1274,9 +1271,7 @@ int processEntry(struct index_entry *ent
 
 	} else if ( (!oSha && aSha && !bSha) ||
 		    (!oSha && !aSha && bSha) ) {
-		//
-		// Case B: Added in one.
-		//
+		/* Case B: Added in one. */
 		const char *addBranch;
 		const char *otherBranch;
 		unsigned mode;
@@ -1309,9 +1304,7 @@ int processEntry(struct index_entry *ent
 			updateFile(fp, 1, sha, mode, path);
 		}
 	} else if ( !oSha && aSha && bSha ) {
-		//
-		// Case C: Added in both (check for same permissions).
-		//
+		/* Case C: Added in both (check for same permissions). */
 		if ( sha_eq(aSha, bSha) ) {
 			if ( aMode != bMode ) {
 				cleanMerge = 0;
@@ -1321,7 +1314,7 @@ int processEntry(struct index_entry *ent
 				output("CONFLICT: adding with permission: %06o", aMode);
 				updateFile(fp, 0, aSha, aMode, path);
 			} else {
-				// This case is handled by git-read-tree
+				/* This case is handled by git-read-tree */
 				assert(0 && "This case must be handled by git-read-tree");
 			}
 		} else {
@@ -1337,9 +1330,7 @@ int processEntry(struct index_entry *ent
 		}
 
 	} else if ( oSha && aSha && bSha ) {
-		//
-		// case D: Modified in both, but differently.
-		//
+		/* case D: Modified in both, but differently. */
 		output("Auto-merging %s\n", path);
 		struct merge_file_info mfi;
 		mfi = mergeFile(path, oSha, oMode,
@@ -1472,15 +1463,15 @@ struct graph *graph_build(struct node_li
 			break;
 		if (EOF == ch)
 			break;
-		// a commit
+		/* a commit */
 		struct node *node = graph_node_bysha(graph, sha);
 		if (!node)
 		{
 			node = node_alloc(lookup_commit(sha));
 			graph_add_node(graph, node);
 		}
-		// ...and its parents. I assume a parent cannot be mentioned
-		// before the children.
+		/* ...and its parents. I assume a parent cannot be mentioned
+		   before the children. */
 		struct node_list *parents = NULL;
 		while ('\n' != ch) {
 			if (fget_sha1(sha, fp, &ch)) {
@@ -1573,4 +1564,6 @@ int main(int argc, char *argv[])
 	return result.clean ? 0: 1;
 }
 
-// vim: sw=8 noet
+/*
+vim: sw=8 noet
+*/
diff --git a/path-list.c b/path-list.c
index fbfc103..95395ab 100644
--- a/path-list.c
+++ b/path-list.c
@@ -67,7 +67,7 @@ int path_list_has_path(const struct path
 	return exact_match;
 }
 
-// in place
+/* in place */
 void path_list_union_update(struct path_list *dst, const struct path_list *src)
 {
 	char **new_paths;
-- 
1.4.1.rc1.g8b09-dirty


[-- Attachment #3: 0002-fix-processEntries-to-avoid-multiple-calls-to-write-tree-and-update-index.txt --]
[-- Type: text/plain, Size: 5295 bytes --]

From b2fbfc22526fb2a1f56ef56836b7412c53524e60 Mon Sep 17 00:00:00 2001
From: Riesen <ARiesen@oekap852.hbi.ad.harman.com>
Date: Wed, 28 Jun 2006 10:45:05 +0200
Subject: fix processEntries to avoid multiple calls to write-tree and update-index
---
 merge-recursive.c |   47 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index ba5b024..5b7ed51 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -19,6 +19,13 @@ #include "run-command.h"
 #include "graph.h"
 #include "path-list.h"
 
+#define DEBUG
+#ifdef DEBUG
+#define debug(args, ...) fprintf(stderr, args, ## __VA_ARGS__)
+#else
+#define debug(args, ...)
+#endif
+
 #define for_each_commit(p,list) for ( p = (list); p; p = p->next )
 
 struct merge_result
@@ -345,9 +352,14 @@ int getFilesAndDirs(struct tree *tree,
 	path_list_clear(dirs, 1);
 	data.files = files;
 	data.dirs = dirs;
-	if ( read_tree_rt(tree, "", 0, save_files_dirs, &data) != 0 )
+	debug("getFilesAndDirs ...\n");
+	if ( read_tree_rt(tree, "", 0, save_files_dirs, &data) != 0 ) {
+		debug("\tgetFilesAndDirs done (0)\n");
 		return 0;
-	return path_list_count(files) + path_list_count(dirs);
+	}
+	int n = path_list_count(files) + path_list_count(dirs);
+	debug("\tgetFilesAndDirs done (%d)\n", n);
+	return n;
 }
 
 struct index_entry *index_entry_find(struct index_entry *ents, const char *path)
@@ -478,6 +490,7 @@ struct index_entry *unmergedCacheEntries
 	FILE *fp = popen("git-ls-files -z --unmerged", "r");
 	if ( !fp )
 		return NULL;
+	debug("unmergedCacheEntries...\n");
 	int ch;
 	while ( !feof(fp) ) {
 		unsigned mode;
@@ -524,6 +537,7 @@ struct index_entry *unmergedCacheEntries
 		while ( (ch = fgetc(fp)) != EOF && ch );
 	}
 	pclose(fp);
+	debug("\tunmergedCacheEntries done\n");
 	return unmerged;
 }
 
@@ -595,6 +609,7 @@ struct rename_entry *getRenames(struct t
 				struct tree *bTree,
 				struct index_entry **entries)
 {
+	debug("getRenames ...\n");
 	struct rename_entry *renames = NULL;
 	struct rename_entry **rptr = &renames;
 	struct diff_options opts;
@@ -639,6 +654,7 @@ struct rename_entry *getRenames(struct t
 	}
 	opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 	diff_flush(&opts);
+	debug("\tgetRenames done\n");
 	return renames;
 }
 
@@ -991,6 +1007,7 @@ int processRenames(struct rename_entry *
 		   const char *branchNameA,
 		   const char *branchNameB)
 {
+	debug("processRenames...\n");
 	int cleanMerge = 1;
 
 	struct path_list srcNames = {NULL, 0, 0};
@@ -1207,6 +1224,7 @@ int processRenames(struct rename_entry *
 	if (pclose(fp)) {
 		die("git update-index --index-info failed");
 	}
+	debug("\tprocessRenames done\n");
 	return cleanMerge;
 }
 
@@ -1223,7 +1241,8 @@ static int sha_eq(const unsigned char *a
 }
 
 /* Per entry merge function */
-int processEntry(struct index_entry *entry,
+int processEntry(FILE *fp,
+		 struct index_entry *entry,
 		 const char *branch1Name,
 		 const char *branch2Name)
 {
@@ -1239,7 +1258,6 @@ int processEntry(struct index_entry *ent
 	unsigned oMode = entry->stages[1].mode;
 	unsigned aMode = entry->stages[2].mode;
 	unsigned bMode = entry->stages[3].mode;
-	FILE *fp = git_update_index_pipe();
 
 	if ( oSha && (!aSha || !bSha) ) {
 		/* Case A: Deleted in one */
@@ -1353,8 +1371,6 @@ int processEntry(struct index_entry *ent
 	} else
 		die("Fatal merge failure, shouldn't happen.");
 
-	if (pclose(fp))
-		die("updating entry failed in git update-index");
 	return cleanMerge;
 }
 
@@ -1373,6 +1389,7 @@ struct merge_tree_result merge_trees(str
 		return result;
 	}
 
+	debug("merge_trees ...\n");
 	code = git_merge_trees(index_only ? "-i": "-u", common, head, merge);
 
 	if ( code != 0 )
@@ -1397,17 +1414,22 @@ struct merge_tree_result merge_trees(str
 		renamesMerge = getRenames(merge, common, head, merge, &entries);
 		result.clean = processRenames(renamesHead, renamesMerge,
 					      branch1Name, branch2Name);
+		debug("\tprocessing entries...\n");
+		FILE *fp = git_update_index_pipe();
 		struct index_entry *e;
 		for ( e = entries; e; e = e->next ) {
 			if ( e->processed )
 				continue;
-			if ( !processEntry(e, branch1Name, branch2Name) )
+			if ( !processEntry(fp, e, branch1Name, branch2Name) )
 				result.clean = 0;
-			if ( result.clean || index_only )
-				result.tree = git_write_tree();
-			else
-				result.tree = NULL;
 		}
+		if (pclose(fp))
+			die("updating entry failed in git update-index");
+		if ( result.clean || index_only )
+			result.tree = git_write_tree();
+		else
+			result.tree = NULL;
+		debug("\t\tprocessing entries done\n");
 		free_rename_entries(&renamesMerge);
 		free_rename_entries(&renamesHead);
 		free_index_entries(&entries);
@@ -1419,6 +1441,7 @@ struct merge_tree_result merge_trees(str
 		       sha1_to_hex(result.tree->object.sha1));
 	}
 
+	debug("\tmerge_trees done\n");
 	return result;
 }
 
@@ -1558,7 +1581,9 @@ int main(int argc, char *argv[])
 		struct node_list *commits = NULL;
 		node_list_insert(h1, &commits);
 		node_list_insert(h2, &commits->next);
+		debug("building graph...\n");
 		struct graph *graph = graph_build(commits);
+		debug("\tbuilding graph...\n");
 		result = merge(h1, h2, branch1, branch2, graph, 0, NULL);
 	}
 	return result.clean ? 0: 1;
-- 
1.4.1.rc1.g8b09-dirty


^ permalink raw reply related

* Re: [PATCH] Makefile: set USE_PIC on Linux x86_64 for linking with Git.pm
From: Josef Weidendorfer @ 2006-06-29  9:58 UTC (permalink / raw)
  To: Sergey Vlasov; +Cc: Junio C Hamano, Marco Roeland, git, pasky
In-Reply-To: <20060629130400.c280de67.vsu@altlinux.ru>

On Thursday 29 June 2006 11:04, Sergey Vlasov wrote:
> And the effect of -fPIC on x86_64 is smaller than on i386, because
> x86_64 has 2x more registers than i386, therefore loss of one register
> is less noticeable.

According to the x86_64 ABI, x86_64 has no explicit GOT pointer.
Meaning: no additional register needed at all, as x86_64 has IP-relative
addressing. Thus, compiling with -fPIC on x86_64 probably has no
negative implications at all (?).

Josef

^ permalink raw reply

* [PATCH] autoconf: Use autoconf to check for libraries: openssl/crypto, curl, expat
From: Jakub Narebski @ 2006-06-29 11:59 UTC (permalink / raw)
  To: git
In-Reply-To: <200606290301.51657.jnareb@gmail.com>

./configure script checks now if the following libraries are present:
 * -lcrypto (checks for SHA1_Init, sets NO_OPENSSL=YesPlease if not found)
 * -lcurl   (checks for curl_easy_setopt, sets NO_CURL=YesPlease if not found)
 * -lexpat  (checks for XML_ParserCreate, sets NO_EXPAT=YesPlease if not found)

Appropriate lines in config.mak are generated using MY_APPEND_LINE macro by adding
lines to temporary file config.mak.append

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---

Second patch in series introducing nonintrusive autoconf support to
git build process.

I'm not that sure about -lcrypto equals openssl.

 configure.ac |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4003ff6..55d7a9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,21 @@ AC_INIT([git], [1.4.0], [git@vger.kernel
 
 AC_CONFIG_SRCDIR([git.c])
 
+# Definitions of macros
+# MY_APPEND_LINE(LINE)
+# --------------------
+# Append LINE to file config.mak.append
+AC_DEFUN([MY_APPEND_LINE],
+[[echo "$1" >> config.mak.append]])# AC_APPEND_LINE
+
+# Checks for libraries.
+AC_MSG_NOTICE(CHECKS for libraries)
+AC_CHECK_LIB([crypto], [SHA1_Init],,MY_APPEND_LINE(NO_OPENSSL=YesPlease))
+AC_CHECK_LIB([curl], [curl_easy_setopt],,MY_APPEND_LINE(NO_CURL=YesPlease))
+AC_CHECK_LIB([expat], [XML_ParserCreate],,MY_APPEND_LINE(NO_EXPAT=YesPlease))
+
 # Output files
-AC_CONFIG_FILES([config.mak])
+AC_CONFIG_FILES([config.mak:config.mak.in:config.mak.append], 
+[rm -f config.mak.append], 
+[echo >> config.mak.append])
 AC_OUTPUT
-- 
1.4.0

^ permalink raw reply related

* Re: [PATCH] autoconf: Use autoconf to write installation directories to config.mak
From: Matthias Lederhofer @ 2006-06-29 12:46 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200606290301.51657.jnareb@gmail.com>

> This is beginning of patch series introducing installation configuration
> using autoconf (and no other autotools) to git. The idea is to generate
> config.mak using ./configure (generated from configure.ac) from
> config.mak.in, so one can use autoconf as an _alternative_ to ordinary
> Makefile, and creating one's own config.mak.

Are you sure this should be named config.mak? From INSTALL:
> You can place local settings in config.mak and the Makefile
> will include them.  Note that config.mak is not distributed;
> the name is reserved for local settings.

So with another filename either include it
- before config.mak: the user may override ./configure options with
  config.mak
- after config.mak: ./configure overrides config.mak
At least do not overwrite config.mak if it exists.

^ 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