<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/git.git/tree-diff.c, branch v1.6.4.5</title>
<subtitle>Git
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/git.git/atom?h=v1.6.4.5</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/atom?h=v1.6.4.5'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/'/>
<updated>2009-07-02T02:40:47Z</updated>
<entry>
<title>Merge branch 'ne/maint-1.6.0-diff-tree-t-r-show-directory'</title>
<updated>2009-07-02T02:40:47Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2009-07-02T02:40:47Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=4197195bee15f120e99d797b22108fd274235fd7'/>
<id>urn:sha1:4197195bee15f120e99d797b22108fd274235fd7</id>
<content type='text'>
* ne/maint-1.6.0-diff-tree-t-r-show-directory:
  diff-tree -r -t: include added/removed directories in the output
</content>
</entry>
<entry>
<title>diff-tree -r -t: include added/removed directories in the output</title>
<updated>2009-06-14T00:06:09Z</updated>
<author>
<name>Nick Edelen</name>
<email>sirnot@gmail.com</email>
</author>
<published>2009-06-14T00:06:09Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=df533f34a31890a43baaf00d03c0a7fa51886bc5'/>
<id>urn:sha1:df533f34a31890a43baaf00d03c0a7fa51886bc5</id>
<content type='text'>
We used to include only the modified and typechanged directories
in the ouptut, but for consistency's sake, we should also include
added and removed ones as well.

This makes the output more consistent, but it may break existing scripts
that expect to see the current output which has long been the established
behaviour.

Signed-off-by: Nick Edelen &lt;sirnot@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Fix typos / spelling in comments</title>
<updated>2009-04-23T02:02:12Z</updated>
<author>
<name>Mike Ralphson</name>
<email>mike@abacus.co.uk</email>
</author>
<published>2009-04-17T18:13:30Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=3ea3c215c02dc4a4e7d0881c25b2223540960797'/>
<id>urn:sha1:3ea3c215c02dc4a4e7d0881c25b2223540960797</id>
<content type='text'>
Signed-off-by: Mike Ralphson &lt;mike@abacus.co.uk&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>tree_entry_interesting: a pathspec only matches at directory boundary</title>
<updated>2009-04-02T02:35:16Z</updated>
<author>
<name>Björn Steinbrink</name>
<email>B.Steinbrink@gmx.de</email>
</author>
<published>2009-03-31T15:05:01Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=f0946cb826b9b6c01976860fdd9dfd498ce0ec5e'/>
<id>urn:sha1:f0946cb826b9b6c01976860fdd9dfd498ce0ec5e</id>
<content type='text'>
Previously the code did a simple prefix match, which means that a
path in a directory "frotz/" would have matched with pathspec "f".

Signed-off-by: Björn Steinbrink &lt;B.Steinbrink@gmx.de&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>'git foo' program identifies itself without dash in die() messages</title>
<updated>2008-08-31T16:39:19Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2008-08-31T16:39:19Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=7e44c93558e7c0b12624d76cf07753d0480ed96a'/>
<id>urn:sha1:7e44c93558e7c0b12624d76cf07753d0480ed96a</id>
<content type='text'>
This is a mechanical conversion of all '*.c' files with:

	s/((?:die|error|warning)\("git)-(\S+:)/$1 $2/;

The result was manually inspected and no false positive was found.

Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Fix buffer overflow in git diff</title>
<updated>2008-07-16T21:03:24Z</updated>
<author>
<name>Dmitry Potapov</name>
<email>dpotapov@gmail.com</email>
</author>
<published>2008-07-16T14:54:02Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=fd55a19eb1d49ae54008d932a65f79cd6fda45c9'/>
<id>urn:sha1:fd55a19eb1d49ae54008d932a65f79cd6fda45c9</id>
<content type='text'>
If PATH_MAX on your system is smaller than a path stored, it may cause
buffer overflow and stack corruption in diff_addremove() and diff_change()
functions when running git-diff

Signed-off-by: Dmitry Potapov &lt;dpotapov@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Fix small memory leaks induced by diff_tree_setup_paths</title>
<updated>2007-12-12T18:59:22Z</updated>
<author>
<name>Mike Hommey</name>
<email>mh@glandium.org</email>
</author>
<published>2007-12-11T21:59:55Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=03b69c7606267bc978c69cf88fcd7a8edf8175bc'/>
<id>urn:sha1:03b69c7606267bc978c69cf88fcd7a8edf8175bc</id>
<content type='text'>
Run diff_tree_release_paths in the appropriate places, and add a test to
avoid NULL dereference. Better safe than sorry.

Signed-off-by: Mike Hommey &lt;mh@glandium.org&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Make the diff_options bitfields be an unsigned with explicit masks.</title>
<updated>2007-11-12T00:54:15Z</updated>
<author>
<name>Pierre Habouzit</name>
<email>madcoder@debian.org</email>
</author>
<published>2007-11-10T19:05:14Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=8f67f8aefb1b751073f8b36fae8be8f72eb93f4a'/>
<id>urn:sha1:8f67f8aefb1b751073f8b36fae8be8f72eb93f4a</id>
<content type='text'>
reverse_diff was a bit-value in disguise, it's merged in the flags now.

Signed-off-by: Pierre Habouzit &lt;madcoder@debian.org&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Fix diffcore-break total breakage</title>
<updated>2007-10-21T05:59:42Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2007-10-20T19:31:31Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=6dd4b66fdecc2ffdc68758b6c4e059fcaaca512b'/>
<id>urn:sha1:6dd4b66fdecc2ffdc68758b6c4e059fcaaca512b</id>
<content type='text'>
Ok, so on the kernel list, some people noticed that "git log --follow"
doesn't work too well with some files in the x86 merge, because a lot of
files got renamed in very special ways.

In particular, there was a pattern of doing single commits with renames
that looked basically like

 - rename "filename.h" -&gt; "filename_64.h"
 - create new "filename.c" that includes "filename_32.h" or
   "filename_64.h" depending on whether we're 32-bit or 64-bit.

which was preparatory for smushing the two trees together.

Now, there's two issues here:

 - "filename.c" *remained*. Yes, it was a rename, but there was a new file
   created with the old name in the same commit. This was important,
   because we wanted each commit to compile properly, so that it was
   bisectable, so splitting the rename into one commit and the "create
   helper file" into another was *not* an option.

   So we need to break associations where the contents change too much.
   Fine. We have the -B flag for that. When we break things up, then the
   rename detection will be able to figure out whether there are better
   alternatives.

 - "git log --follow" didn't with with -B.

Now, the second case was really simple: we use a different "diffopt"
structure for the rename detection than the basic one (which we use for
showing the diffs). So that second case is trivially fixed by a trivial
one-liner that just copies the break_opt values from the "real" diffopts
to the one used for rename following. So now "git log -B --follow" works
fine:

	diff --git a/tree-diff.c b/tree-diff.c
	index 26bdbdd..7c261fd 100644
	--- a/tree-diff.c
	+++ b/tree-diff.c
	@@ -319,6 +319,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
	 	diff_opts.detect_rename = DIFF_DETECT_RENAME;
	 	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
	 	diff_opts.single_follow = opt-&gt;paths[0];
	+	diff_opts.break_opt = opt-&gt;break_opt;
	 	paths[0] = NULL;
	 	diff_tree_setup_paths(paths, &amp;diff_opts);
	 	if (diff_setup_done(&amp;diff_opts) &lt; 0)

however, the end result does *not* work. Because our diffcore-break.c
logic is totally bogus!

In particular:

 - it used to do

	if (base_size &lt; MINIMUM_BREAK_SIZE)
		return 0; /* we do not break too small filepair */

   which basically says "don't bother to break small files". But that
   "base_size" is the *smaller* of the two sizes, which means that if some
   large file was rewritten into one that just includes another file, we
   would look at the (small) result, and decide that it's smaller than the
   break size, so it cannot be worth it to break it up! Even if the other
   side was ten times bigger and looked *nothing* like the samell file!

   That's clearly bogus. I replaced "base_size" with "max_size", so that
   we compare the *bigger* of the filepair with the break size.

 - It calculated a "merge_score", which was the score needed to merge it
   back together if nothing else wanted it. But even if it was *so*
   different that we would never want to merge it back, we wouldn't
   consider it a break! That makes no sense. So I added

	if (*merge_score_p &gt; break_score)
		return 1;

   to make it clear that if we wouldn't want to merge it at the end, it
   was *definitely* a break.

 - It compared the whole "extent of damage", counting all inserts and
   deletes, but it based this score on the "base_size", and generated the
   damage score with

	delta_size = src_removed + literal_added;
	damage_score = delta_size * MAX_SCORE / base_size;

   but that makes no sense either, since quite often, this will result in
   a number that is *bigger* than MAX_SCORE! Why? Because base_size is
   (again) the smaller of the two files we compare, and when you start out
   from a small file and add a lot (or start out from a large file and
   remove a lot), the base_size is going to be much smaller than the
   damage!

   Again, the fix was to replace "base_size" with "max_size", at which
   point the damage actually becomes a sane percentage of the whole.

With these changes in place, not only does "git log -B --follow" work for
the case that triggered this in the first place, ie now

	git log -B --follow arch/x86/kernel/vmlinux_64.lds.S

actually gives reasonable results. But I also wanted to verify it in
general, by doing a full-history

	git log --stat -B -C

on my kernel tree with the old code and the new code.

There's some tweaking to be done, but generally, the new code generates
much better results wrt breaking up files (and then finding better rename
candidates). Here's a few examples of the "--stat" output:

 - This:
	include/asm-x86/Kbuild        |    2 -
	include/asm-x86/debugreg.h    |   79 +++++++++++++++++++++++++++++++++++------
	include/asm-x86/debugreg_32.h |   64 ---------------------------------
	include/asm-x86/debugreg_64.h |   65 ---------------------------------
	4 files changed, 68 insertions(+), 142 deletions(-)

      Becomes:

	include/asm-x86/Kbuild                        |    2 -
	include/asm-x86/{debugreg_64.h =&gt; debugreg.h} |    9 +++-
	include/asm-x86/debugreg_32.h                 |   64 -------------------------
	3 files changed, 7 insertions(+), 68 deletions(-)

 - This:
	include/asm-x86/bug.h    |   41 +++++++++++++++++++++++++++++++++++++++--
	include/asm-x86/bug_32.h |   37 -------------------------------------
	include/asm-x86/bug_64.h |   34 ----------------------------------
	3 files changed, 39 insertions(+), 73 deletions(-)

      Becomes

	include/asm-x86/{bug_64.h =&gt; bug.h} |   20 +++++++++++++-----
	include/asm-x86/bug_32.h            |   37 -----------------------------------
	2 files changed, 14 insertions(+), 43 deletions(-)

Now, in some other cases, it does actually turn a rename into a real
"delete+create" pair, and then the diff is usually bigger, so truth in
advertizing: it doesn't always generate a nicer diff. But for what -B was
meant for, I think this is a big improvement, and I suspect those cases
where it generates a bigger diff are tweakable.

So I think this diff fixes a real bug, but we might still want to tweak
the default values and perhaps the exact rules for when a break happens.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Shawn O. Pearce &lt;spearce@spearce.org&gt;
</content>
</entry>
<entry>
<title>Fix up "git log --follow" a bit..</title>
<updated>2007-06-23T06:37:21Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2007-06-21T17:22:59Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/git.git/commit/?id=9f38e1ef7e7992ca490b9b419f52fb4d11efb0e4'/>
<id>urn:sha1:9f38e1ef7e7992ca490b9b419f52fb4d11efb0e4</id>
<content type='text'>
This fixes "git log --follow" to hopefully not leak memory any more, and
also cleans it up a bit to look more like some of the other functions that
use "diff_queued_diff" (by *not* using it directly as a global in the
code, but by instead just taking a pointer to the diff queue and using
that).

As to "diff_queued_diff", I think it would be better off not as a global
at all, but as being just an entry in the "struct diff_options" structure,
but that's a separate issue, and there may be some subtle reason for why
it's currently a global.

Anyway, no real changes. Instead of having a magical first entry in the
diff-queue, we now end up just keeping the diff-queue clean, and keeping
our "preferred" file pairing in an internal "choice" variable. That makes
it easy to switch the choice around when we find a better one.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
</feed>
