Commit Graph

17 Commits

Author SHA1 Message Date
20239bae94 git-pickaxe: work properly in a subdirectory.
We forgot to add prefix to the given path.

[jc: interestingly enough, Jeff King had the same idea after I
 pushed mine out to "pu", and his patch was cleaner, so I dropped
 mine.]

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-11-02 00:11:30 -08:00
0d981c67d8 git-pickaxe: cache one already found path per commit.
Depending on how bushy the commit DAG is, this saves calls to
the internal diff-tree for fork-point commits.  For example,
annotating Makefile in the kernel repository saves about a third
of such diff-tree calls.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-31 01:00:01 -08:00
f69e743d97 git-pickaxe: split find_origin() into find_rename() and find_origin().
When a merge adds a new file from the second parent, the
earlier code tried to find renames in the first parent before
noticing that the vertion from the second parent was added
without modification.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-30 17:17:41 -08:00
ae86ad6575 git-pickaxe: tighten sanity checks.
When compiled for debugging, make sure that refcnt sanity check
code detects underflows in origin reference counting.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-30 14:27:52 -08:00
f5f75c652b git-pickaxe: refcount origin correctly in find_copy_in_parent()
This makes "git-pickaxe -C master -- revision.c" to finish with
proper refcounts for all origins.  I am reasonably happy with
it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-29 23:56:12 -08:00
2c40f98439 git-pickaxe: allow -Ln,m as well as -L n,m
The command rejects -L1,10 as an invalid line range specifier
and I got frustrated enough by it, so this makes it allow both
forms of input.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-29 23:50:55 -08:00
54a4c6173e git-pickaxe: WIP to refcount origin structure.
The origin structure is allocated for each commit and path while
the code traverse down it is copied into different blame entries.
To avoid leaks, try refcounting them.

This still seems to leak, which I haven't tracked down fully yet.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-29 15:29:25 -08:00
aec8fa1f58 git-pickaxe: swap comparison loop used for -C
When assigning blames for code movements across file boundaries,
we used to iterate over blame entries (i.e. groups of lines to
be blamed) in the outer loop and compared each entry with paths
in the parent commit in an inner loop.  This meant that we
opened the blob data from each path number of times.

Reorganize the loop so that we read the same path only once, and
compare it against all relevant blame entries.

This should perform better, but seems to give mixed results,
though.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-21 03:30:53 -07:00
f6c0e19102 git-pickaxe: get rid of wasteful find_origin().
After finding out which path in the parent to scan to pass
blames, using get_tree_entry() to extract the blob information
again was quite wasteful, since diff-tree already gave us that
information.  Separate the function to create an origin out as
get_origin().

You'll never know what is more efficient unless you try and/or
think hard.  I somehow thought that extracting one known path
out of commit's tree is cheaper than running a diff-tree for the
current path between the commit and its parent, but it is not
the case.  In real, non-toy projects, most commits do not touch
the path you are interested in, and if the path is a few levels
away from the toplevel, whole-subdirectory comparison logic
diff-tree allows us to skip opening lower subdirectories.

This commit rewrites find_origin() function to use a single-path
diff-tree to see if the parent has the same blob as the current
suspect, which is cheaper than extracting the blob information
using get_tree_entry() and comparing it with what the current
suspect has.  This shaves about 6% overhead when annotating
kernel/sched.c in the Linux kernel repository on my machine.
The saving rises to 25% for arch/i386/kernel/Makefile.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-21 02:56:33 -07:00
46014766bd git-pickaxe: do not confuse two origins that are the same.
It used to be that we can compare the address of the origin
structure to determine if they are the same because they are
always registered with scoreboard.  After introduction of the
loop to try finding the best split, that is not true anymore.

The current code has rather serious leaks with origin structure,
but more importantly it gets confused when two origins that
points at the same commit and same path.

We might eventually have to refcount and gc origin, but let's
fix the correctness issue first.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-21 00:41:38 -07:00
612702e8ea git-pickaxe: do not keep commit buffer.
We need the commit buffer data while generating the final result,
but until then we do not need them.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 23:49:41 -07:00
4a0fc95f18 git-pickaxe: introduce heuristics to avoid "trivial" chunks
This adds scoring logic to blame_entry to prevent blames on very
trivial chunks (e.g. lots of empty lines, indent followed by a
closing brace) from being passed down to unrelated lines in the
parent.

The current heuristics are quite simple and may need to be
tweaked later, but we need to start somewhere.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 18:48:23 -07:00
5ff62c3002 git-pickaxe: improve "best match" heuristics
Instead of comparing number of lines matched, look at the
matched characters and count alnums, so that we do not pass
blame on not-so-interesting lines, such as an empty line and
a line that is indentation followed by a closing brace.

Add an option --score-debug to show the score of each
blame_entry while we cook this further on the "next" branch.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 18:48:23 -07:00
1ca6ca876e git-pickaxe: fix nth_line()
We would want to be able to refer to the end of the file as
"the beginning of Nth line" for a file that is N lines long.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 18:48:18 -07:00
18abd745a0 git-pickaxe -C: blame cut-and-pasted lines.
This completes the initial round of git-pickaxe.  In addition to
the detection of line movements we already have, this finds new
lines that were created by moving or cutting-and-pasting lines
from different files in the parent.

With this,

	git pickaxe -f -n -C v1.4.0 -- revision.c

finds that a major part of that file actually came from
rev-list.c when Linus split the latter at commit ae563642 and
blames them to earlier commits that touch rev-list.c.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 00:30:44 -07:00
d24bba8008 git-pickaxe -M: blame line movements within a file.
This makes pickaxe more intelligent than the classic blame.

A typical example is a change that moves one static C function
from lower part of the file to upper part of the same file,
because you added a new caller in the middle.

The versions in the parent and the child would look like this:

        parent            child

        A                 static foo() {
        B                 ...
        C                 }
        D                 A
        E                 B
        F                 C
        G                 D
        static foo() {    ... call foo();
        ...               E
        }                 F
        H                 G
                          H

With the classic blame algorithm, we can blame lines A B C D E F
G and H to the parent.  The child is guilty of introducing the
line "... call foo();", and the blame is placed on the child.
However, the classic blame algorithm fails to notice that the
implementation of foo() at the top of the file is not new, and
moved from the lower part of the parent.

This commit introduces detection of such line movements, and
correctly blames the lines that were simply moved in the file to
the parent.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-20 00:27:05 -07:00
cee7f245dc git-pickaxe: blame rewritten.
Currently it does what git-blame does, but only faster.

More importantly, its internal structure is designed to support
content movement (aka cut-and-paste) more easily by allowing
more than one paths to be taken from the same commit.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-19 22:42:49 -07:00