1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-09 04:26:08 +02:00
Commit Graph

250 Commits

Author SHA1 Message Date
Kirill Smelkov 51af1886c7 combine-diff: move show_log_first logic/action out of paths scanning
Judging from sample outputs and tests nothing changes in diff -c output,
and this change will help later patches, when we'll be refactoring paths
scanning into its own function with several variants - the
show_log_first logic / code will stay common to all of them.

NOTE: only now we have to take care to explicitly not show anything if
    parents array is empty, as in fact there are some clients in Git code,
    which calls diff_tree_combined() in such a way.

Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24 14:46:11 -08:00
Junio C Hamano 7b1004b0ba combine-diff: simplify intersect_paths() further
Linus once said:

    I actually wish more people understood the really core low-level
    kind of coding. Not big, complex stuff like the lockless name
    lookup, but simply good use of pointers-to-pointers etc. For
    example, I've seen too many people who delete a singly-linked
    list entry by keeping track of the "prev" entry, and then to
    delete the entry, doing something like

	if (prev)
	    prev->next = entry->next;
	else
	    list_head = entry->next;

    and whenever I see code like that, I just go "This person
    doesn't understand pointers". And it's sadly quite common.

    People who understand pointers just use a "pointer to the entry
    pointer", and initialize that with the address of the
    list_head. And then as they traverse the list, they can remove
    the entry without using any conditionals, by just doing a "*pp =
    entry->next".

Applying that simplification lets us lose 7 lines from this function
even while adding 2 lines of comment.

I was tempted to squash this into the original commit, but because
the benchmarking described in the commit log is without this
simplification, I decided to keep it a separate follow-up patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24 14:44:57 -08:00
Kirill Smelkov af82c7880f combine-diff: combine_diff_path.len is not needed anymore
The field was used in order to speed-up name comparison and also to
mark removed paths by setting it to 0.

Because the updated code does significantly less strcmp and also
just removes paths from the list and free right after we know a path
will not be needed, it is not needed anymore.

Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24 14:44:57 -08:00
Kirill Smelkov 8518ff8fab combine-diff: optimize combine_diff_path sets intersection
When generating combined diff, for each commit, we intersect diff
paths from diff(parent_0,commit) to diff(parent_i,commit) comparing
all paths pairs, i.e. doing it the quadratic way. That is correct,
but could be optimized.

Paths come from trees in sorted (= tree) order, and so does diff_tree()
emits resulting paths in that order too. Now if we look at diffcore
transformations, all of them, except diffcore_order, preserve resulting
path ordering:

    - skip_stat_unmatch, grep, pickaxe, filter
                            -- just skip elements -> order stays preserved

    - break                 -- just breaks diff for a path, adding path
                               dup after the path -> order stays preserved

    - detect rename/copy    -- resulting paths are emitted sorted
                               (verified empirically)

So only diffcore_order changes diff paths ordering.

But diffcore_order meaning affects only presentation - i.e. only how to
show the diff, so we could do all the internal computations without
paths reordering, and order only resultant paths set. This is faster,
since, if we know two paths sets are all ordered, their intersection
could be done in linear time.

This patch does just that.

Timings for `git log --raw --no-abbrev --no-renames` without `-c` ("git log")
and with `-c` ("git log -c") before and after the patch are as follows:

                linux.git v3.10..v3.11

            log     log -c

    before  1.9s    20.4s
    after   1.9s    16.6s

                navy.git    (private repo)

            log     log -c

    before  0.83s   15.6s
    after   0.83s    2.1s

P.S.

I think linux.git case is sped up not so much as the second one, since
in navy.git, there are more exotic (subtree, etc) merges.

P.P.S.

My tracing showed that the rest of the time (16.6s vs 1.9s) is usually
spent in computing huge diffs from commit to second parent. Will try to
deal with it, if I'll have time.

P.P.P.S.

For combine_diff_path, ->len is not needed anymore - will remove it in
the next noisy cleanup path, to maintain good signal/noise ratio here.

Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24 14:44:57 -08:00
Junio C Hamano b02f5aeda6 Merge branch 'jl/submodule-mv'
"git mv A B" when moving a submodule A does "the right thing",
inclusing relocating its working tree and adjusting the paths in
the .gitmodules file.

* jl/submodule-mv: (53 commits)
  rm: delete .gitmodules entry of submodules removed from the work tree
  mv: update the path entry in .gitmodules for moved submodules
  submodule.c: add .gitmodules staging helper functions
  mv: move submodules using a gitfile
  mv: move submodules together with their work trees
  rm: do not set a variable twice without intermediate reading.
  t6131 - skip tests if on case-insensitive file system
  parse_pathspec: accept :(icase)path syntax
  pathspec: support :(glob) syntax
  pathspec: make --literal-pathspecs disable pathspec magic
  pathspec: support :(literal) syntax for noglob pathspec
  kill limit_pathspec_to_literal() as it's only used by parse_pathspec()
  parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN
  parse_pathspec: make sure the prefix part is wildcard-free
  rename field "raw" to "_raw" in struct pathspec
  tree-diff: remove the use of pathspec's raw[] in follow-rename codepath
  remove match_pathspec() in favor of match_pathspec_depth()
  remove init_pathspec() in favor of parse_pathspec()
  remove diff_tree_{setup,release}_paths
  convert common_prefix() to use struct pathspec
  ...
2013-09-09 14:36:15 -07:00
Junio C Hamano 4ab4a6dfb4 Merge branch 'tr/log-full-diff-keep-true-parents'
Output from "git log --full-diff -- <pathspec>" looked strange,
because comparison was done with the previous ancestor that touched
the specified <pathspec>, causing the patches for paths outside the
pathspec to show more than the single commit has changed.

Tweak "git reflog -p" for the same reason using the same mechanism.

* tr/log-full-diff-keep-true-parents:
  log: use true parents for diff when walking reflogs
  log: use true parents for diff even when rewriting
2013-09-09 14:33:16 -07:00
Thomas Rast 53d00b39ce log: use true parents for diff even when rewriting
When using pathspec filtering in combination with diff-based log
output, parent simplification happens before the diff is computed.
The diff is therefore against the *simplified* parents.

This works okay, arguably by accident, in the normal case:
simplification reduces to one parent as long as the commit is TREESAME
to it.  So the simplified parent of any given commit must have the
same tree contents on the filtered paths as its true (unfiltered)
parent.

However, --full-diff breaks this guarantee, and indeed gives pretty
spectacular results when comparing the output of

  git log --graph --stat ...
  git log --graph --full-diff --stat ...

(--graph internally kicks in parent simplification, much like
--parents).

To fix it, store a copy of the parent list before simplification (in a
slab) whenever --full-diff is in effect.  Then use the stored parents
instead of the simplified ones in the commit display code paths.  The
latter do not actually check for --full-diff to avoid duplicated code;
they just grab the original parents if save_parents() has not been
called for this revision walk.

For ordinary commits it should be obvious that this is the right thing
to do.

Merge commits are a bit subtle.  Observe that with default
simplification, merge simplification is an all-or-nothing decision:
either the merge is TREESAME to one parent and disappears, or it is
different from all parents and the parent list remains intact.
Redundant parents are not pruned, so the existing code also shows them
as a merge.

So if we do show a merge commit, the parent list just consists of the
rewrite result on each parent.  Running, e.g., --cc on this in
--full-diff mode is not very useful: if any commits were skipped, some
hunks will disagree with all sides of the merge (with one side,
because commits were skipped; with the others, because they didn't
have those changes in the first place).  This triggers --cc showing
these hunks spuriously.

Therefore I believe that even for merge commits it is better to show
the diffs wrt. the original parents.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Thomas Rast <trast@inf.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-01 10:25:48 -07:00
Ondřej Bílka 98e023dea4 many small typofixes
Signed-off-by: Ondřej Bílka <neleai@seznam.cz>
Reviewed-by: Marc Branchaud <marcnarc@xiplink.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-29 12:32:25 -07:00
Nguyễn Thái Ngọc Duy bd1928df1d remove diff_tree_{setup,release}_paths
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-15 10:56:09 -07:00
Junio C Hamano a1ddd11452 Merge branch 'cb/log-follow-with-combined'
* cb/log-follow-with-combined:
  fix segfault with git log -c --follow
2013-06-11 13:30:36 -07:00
Junio C Hamano edc7f0abcb Merge branch 'mk/combine-diff-context-horizon-fix'
"git diff -c -p" was not showing a deleted line from a hunk when
another hunk immediately begins where the earlier one ends.

* mk/combine-diff-context-horizon-fix:
  combine-diff.c: Fix output when changes are exactly 3 lines apart
2013-06-02 15:56:46 -07:00
Clemens Buchacher 46ec510ac0 fix segfault with git log -c --follow
In diff_tree_combined we make a copy of diffopts. In
try_to_follow_renames, called via diff_tree_sha1, we free and
re-initialize diffopts->pathspec->items. Since we did not make a deep
copy of diffopts in diff_tree_combined, the original diffopts does not
get the update. By the time we return from diff_tree_combined,
rev->diffopt->pathspec->items points to an invalid memory address. We
get a segfault next time we try to access that pathspec.

Instead, along with the copy of diffopts, make a copy pathspec->items as
well.

We would also have to make a copy of pathspec->raw to keep it consistent
with pathspec->items, but nobody seems to rely on that.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-28 11:26:24 -07:00
Matthijs Kooijman aac385717a combine-diff.c: Fix output when changes are exactly 3 lines apart
When a deletion is followed by exactly 3 (or whatever the number of
context lines) unchanged lines, followed by another change, the combined
diff output would hide the first deletion, resulting in a malformed
diff.

This happened because the 3 lines before each change are painted
interesting, but also marked as no_pre_delete to prevent showing deletes
that were previously marked as uninteresting. This behaviour was
introduced in c86fbe53 (diff -c/--cc: do not include uninteresting
deletion before leading context). However, as a side effect, this could
also mark deletes that were already interesting as no_pre_delete. This
would happen only if the delete was exactly 3 lines away from the next
change, since lines farther away would not be touched by the "paint
three lines before the change" code and lines closer would be painted
by the "merge two adjacent hunks" code instead, which does not set the
no_pre_delete flag.

This commit fixes this problem by only setting the no_pre_delete flag
for changes that were previously uninteresting.

Signed-off-by: Matthijs Kooijman <matthijs@stdin.nl>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-15 12:02:04 -07:00
Antoine Pelisse 99d3206010 combine-diff: coalesce lost lines optimally
This replaces the greedy implementation to coalesce lost lines by using
dynamic programming to find the Longest Common Subsequence.

The O(n²) time complexity is obviously bigger than previous
implementation but it can produce shorter diff results (and most likely
easier to read).

List of lost lines is now doubly-linked because we reverse-read it when
reading the direction matrix.

Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-25 14:52:33 -07:00
Antoine Pelisse fa04ae0be8 Allow combined diff to ignore white-spaces
The combined diff --cc output does not honor options to ignore
whitespace changes (-b, -w, and --ignore-space-at-eol).

Correct this by passing diff flags to diff engine, so that combined
diff behaves as normal diff does with spaces, and by coalescing
lines that are removed from both (or more) parents, honoring the
same rule to ignore whitespace changes.

With this change, a conflict-less merge done using a ignore-*
strategy option will not show any conflict if shown in combined-diff
using the same option.

Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-14 14:43:34 -07:00
Junio C Hamano a1d68bea89 Merge branch 'jk/diff-graph-cleanup'
Refactors a lot of repetitive code sequence from the graph drawing
code and adds it to the combined diff output.

* jk/diff-graph-cleanup:
  combine-diff.c: teach combined diffs about line prefix
  diff.c: use diff_line_prefix() where applicable
  diff: add diff_line_prefix function
  diff.c: make constant string arguments const
  diff: write prefix to the correct file
  graph: output padding for merge subsequent parents
2013-02-14 10:29:59 -08:00
John Keeping 41ee2ad6cb combine-diff.c: teach combined diffs about line prefix
When running "git log --graph --cc -p" the diff output for merges is not
indented by the graph structure, unlike the diffs of non-merge commits
(added in commit 7be5761 - diff.c: Output the text graph padding before
each diff line).

Fix this by teaching the combined diff code to output diff_line_prefix()
before each line.

Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-12 11:42:07 -08:00
Junio C Hamano 7766705198 combine-diff: lift 32-way limit of combined diff
The "raw" format of combine-diff output is supposed to have as many
colons as there are parents at the beginning, then blob modes for
these parents, and then object names for these parents.

We weren't however prepared to handle a more than 32-way merge and
did not show the correct number of colons in such a case.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-03 13:08:18 -08:00
Junio C Hamano 03adeeaad6 Merge branch 'jk/maint-null-in-trees' into maint-1.7.11
"git diff" had a confusion between taking data from a path in the
working tree and taking data from an object that happens to have
name 0{40} recorded in a tree.

* jk/maint-null-in-trees:
  fsck: detect null sha1 in tree entries
  do not write null sha1s to on-disk index
  diff: do not use null sha1 as a sentinel value
2012-09-10 15:24:54 -07:00
Junio C Hamano 3b753148b6 Merge branch 'jk/maint-null-in-trees'
We do not want a link to 0{40} object stored anywhere in our objects.

* jk/maint-null-in-trees:
  fsck: detect null sha1 in tree entries
  do not write null sha1s to on-disk index
  diff: do not use null sha1 as a sentinel value
2012-08-27 11:54:28 -07:00
Jeff King e54501004a diff: do not use null sha1 as a sentinel value
The diff code represents paths using the diff_filespec
struct. This struct has a sha1 to represent the sha1 of the
content at that path, as well as a sha1_valid member which
indicates whether its sha1 field is actually useful. If
sha1_valid is not true, then the filespec represents a
working tree file (e.g., for the no-index case, or for when
the index is not up-to-date).

The diff_filespec is only used internally, though. At the
interfaces to the diff subsystem, callers feed the sha1
directly, and we create a diff_filespec from it. It's at
that point that we look at the sha1 and decide whether it is
valid or not; callers may pass the null sha1 as a sentinel
value to indicate that it is not.

We should not typically see the null sha1 coming from any
other source (e.g., in the index itself, or from a tree).
However, a corrupt tree might have a null sha1, which would
cause "diff --patch" to accidentally diff the working tree
version of a file instead of treating it as a blob.

This patch extends the edges of the diff interface to accept
a "sha1_valid" flag whenever we accept a sha1, and to use
that flag when creating a filespec. In some cases, this
means passing the flag through several layers, making the
code change larger than would be desirable.

One alternative would be to simply die() upon seeing
corrupted trees with null sha1s. However, this fix more
directly addresses the problem (while bogus sha1s in a tree
are probably a bad thing, it is really the sentinel
confusion sending us down the wrong code path that is what
makes it devastating). And it means that git is more capable
of examining and debugging these corrupted trees. For
example, you can still "diff --raw" such a tree to find out
when the bogus entry was introduced; you just cannot do a
"--patch" diff (just as you could not with any other
corrupted tree, as we do not have any content to diff).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-07-29 15:04:32 -07:00
Junio C Hamano f84e8b6069 Merge branch 'rs/combine-diff-zero-context-at-the-beginning'
Fixes an age old corner case bug in combine diff (only triggered with -U0
and the hunk at the beginning of the file needs to be shown).

By René Scharfe
* rs/combine-diff-zero-context-at-the-beginning:
  combine-diff: fix loop index underflow
2012-04-16 12:41:59 -07:00
René Scharfe e5e9b56528 combine-diff: fix loop index underflow
If both la and context are zero at the start of the loop, la wraps around
and we end up reading from memory far away.  Skip the loop in that case
instead.

Reported-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-25 21:35:52 -07:00
René Scharfe 82889295e7 pass struct commit to diff_tree_combined_merge()
Instead of passing the hash of a commit and then searching that
same commit in the single caller, simply pass the commit directly.

Signed-off-by: René Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-17 18:22:29 -08:00
René Scharfe 0041f09de6 use struct sha1_array in diff_tree_combined()
Maintaining an array of hashes is easier using sha1_array than
open-coding it.  This patch also fixes a leak of the SHA1 array
in  diff_tree_combined_merge().

Signed-off-by: René Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-17 18:21:37 -08:00
Junio C Hamano f946b465d7 Merge branch 'jk/color-and-pager'
* jk/color-and-pager:
  want_color: automatically fallback to color.ui
  diff: don't load color config in plumbing
  config: refactor get_colorbool function
  color: delay auto-color decision until point of use
  git_config_colorbool: refactor stdout_is_tty handling
  diff: refactor COLOR_DIFF from a flag into an int
  setup_pager: set GIT_PAGER_IN_USE
  t7006: use test_config helpers
  test-lib: add helper functions for config
  t7006: modernize calls to unset

Conflicts:
	builtin/commit.c
	parse-options.c
2011-08-28 21:19:16 -07:00
Junio C Hamano e78f829143 Merge branch 'jc/combine-diff-callback'
* jc/combine-diff-callback:
  combine-diff: support format_callback
2011-08-28 21:15:33 -07:00
Junio C Hamano 25e5e2bf85 combine-diff: support format_callback
This teaches combine-diff machinery to feed a combined merge to a callback
function when DIFF_FORMAT_CALLBACK is specified.

So far, format callback functions are not used for anything but 2-way
diffs. A callback is given a diff_queue_struct, which is an array of
diff_filepair. As its name suggests, a diff_filepair is a _pair_ of
diff_filespec that represents a single preimage and a single postimage.

Since "diff -c" is to compare N parents with a single merge result and
filter out any paths whose result match one (or more) of the parent(s),
its output has to be able to represent N preimages and 1 postimage. For
this reason, a callback function that inspects a diff_filepair that
results from this new infrastructure can and is expected to view the
preimage side (i.e. pair->one) as an array of diff_filespec. Each element
in the array, except for the last one, is marked with "has_more_entries"
bit, so that the same callback function can be used for 2-way diffs and
combined diffs.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-20 23:03:06 -07:00
Jeff King f1c9626105 diff: refactor COLOR_DIFF from a flag into an int
This lets us store more than just a bit flag for whether we
want color; we can also store whether we want automatic
colors. This can be useful for making the automatic-color
decision closer to the point of use.

This mostly just involves replacing DIFF_OPT_* calls with
manipulations of the flag. The biggest exception is that
calls to DIFF_OPT_TST must check for "o->use_color > 0",
which lets an "unknown" value (i.e., the default) stay at
"no color". In the previous code, a value of "-1" was not
propagated at all.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-18 14:35:53 -07:00
Junio C Hamano 660578d4da Merge branch 'jc/maint-combined-diff-work-tree'
* jc/maint-combined-diff-work-tree:
  diff -c/--cc: do not mistake "resolved as deletion" as "use working tree"

Conflicts:
	combine-diff.c
2011-08-17 17:25:59 -07:00
Junio C Hamano 9969454435 diff -c/--cc: do not mistake "resolved as deletion" as "use working tree"
The combined diff machinery can be used to compare:

 - a merge commit with its parent commits;
 - a working-tree file with multiple stages in an unmerged index; or
 - a working-tree file with the HEAD and the index.

The internal function combine-diff.c:show_patch_diff() checked if it needs
to read the "result" from the working tree by looking at the object name
of the result --- if it is null_sha1, it read from the working tree.

This mistook a merge that records a deletion as the conflict resolution
as if it is a cue to read from the working tree. Pass this information
explicitly from the caller instead.

Noticed and reported by Johan Herland.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-04 12:05:47 -07:00
Jeff King 0508fe533d combine-diff: respect textconv attributes
When doing a combined diff, we did not respect textconv attributes at
all. This generally lead to us printing "Binary files differ" when we
could show a combined diff of the converted text.

This patch converts file contents according to textconv attributes. The
implementation is slightly ugly; because the textconv code is tightly
linked with the diff_filespec code, we temporarily create a diff_filespec
during conversion. In practice, though, this should not create a
performance problem.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-24 09:08:17 -07:00
Jeff King 4d5f347199 combine-diff: handle binary files as binary
The combined diff code path is totally different from the
regular diff code path, and didn't handle binary files at
all. The results of a combined diff on a binary file could
range from annoying (since we spewed binary garbage,
possibly upsetting the user's terminal), to wrong (embedded
NULs caused us to show incorrect diffs, with lines truncated
at the NUL character), to potential security problems
(embedded NULs could interfere with "-z" output, possibly
defeating policy hooks which parse diff output).

Instead, we consider a combined diff to be binary if any of
the input blobs is binary. To show a binary combined diff,
we indicate "Binary blobs differ"; the "index" meta line
will show which parents had which blob.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-23 15:43:43 -07:00
Jeff King c95b99bb5d combine-diff: calculate mode_differs earlier
One loop combined both the patch generation and checking
whether there was any mode change to report. Let's factor
that into two separate loops, as we may care about the mode
change even if we are not generating patches (e.g., because
we are showing a binary diff, which will come in a future
patch).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-23 15:40:51 -07:00
Jeff King 7c978a068f combine-diff: split header printing into its own function
This is a pretty big logical chunk, so it makes the function
a bit more readable to have it split out. In addition, it
will make it easier to add an alternate code path for binary
diffs in a future patch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-23 15:39:33 -07:00
Junio C Hamano 60335534a6 Merge branch 'rs/diff-no-minimal' into maint
* rs/diff-no-minimal:
  git diff too slow for a file
2010-06-21 05:38:50 -07:00
Junio C Hamano 39b5977b13 Merge branch 'rs/diff-no-minimal'
* rs/diff-no-minimal:
  git diff too slow for a file
2010-06-13 11:20:46 -07:00
René Scharfe dfea79004c remove ecb parameter from xdi_diff_outf()
xdi_diff_outf() overrides the structure members of its last parameter,
ignoring any value that callers pass in.  It's no surprise then that all
callers pass a pointer to an uninitialized structure.  They also don't
read it after the call, so the parameter is neither used for input nor
for output.   Turn it into a local variable of xdi_diff_outf().

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-04 15:19:14 -07:00
René Scharfe 582aa00bdf git diff too slow for a file
Ever since the xdiff library had been introduced to git, all its callers
have used the flag XDF_NEED_MINIMAL.  It makes sure that the smallest
possible diff is produced, but that takes quite some time if there are
lots of differences that can be expressed in multiple ways.

This flag makes a difference for only 0.1% of the non-merge commits in
the git repo of Linux, both in terms of diff size and execution time.
The patches there are mostly nice and small.

SungHyun Nam however reported a case in a different repo where a diff
took more than 20 times longer to generate with XDF_NEED_MINIMAL than
without.  Rebasing became really slow.

This patch removes this flag from all callers.  The default of xdiff is
saner because it has minimal to no impact in the normal case of small
diffs and doesn't incur that much of a speed penalty for large ones.

A follow-up patch may introduce a command line option to set the flag if
the user needs it, similar to GNU diff's -d/--minimal.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-02 07:59:50 -07:00
Thomas Rast 2179870803 combined diff: correctly handle truncated file
Consider an evil merge of two commits A and B, both of which have a
file 'foo', but the merge result does not have that file.

The combined-diff code learned in 4462731 (combine-diff: do not punt
on removed or added files., 2006-02-06) to concisely show only the
removal, since that is the evil part and the previous contents are
presumably uninteresting.

However, to diagnose an empty merge result, it overloaded the variable
that holds the file's length.  This means that the check also triggers
for truncated files.  Consequently, such files were not shown in the
diff at all despite the merge being clearly evil.

Fix this by adding a new variable that distinguishes whether the file
was deleted (which is the case 4462731 handled) or truncated.  In the
truncated case, we show the full combined diff again, which is rather
spammy but at least does not hide the evilness.

Reported-by: David Martínez Martí <desarrollo@gestiweb.com>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-17 10:23:59 -07:00
Bert Wesarg 89cb73a19a Give the hunk comment its own color
Inspired by the coloring of quilt.

Introduce a separate color and paint the hunk comment part, i.e. the name
of the function, in a separate color "diff.func" (defaults to plain).

Whitespace between hunk header and hunk comment is printed in plain color.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-28 10:05:44 -08:00
Junio C Hamano 248b6c0609 Merge branch 'maint'
* maint:
  Trailing whitespace and no newline fix
  diff --cc: a lost line at the beginning of the file is shown incorrectly
  combine-diff.c: fix performance problem when folding common deleted lines
2009-07-22 21:56:46 -07:00
Junio C Hamano b810cbbde9 diff --cc: a lost line at the beginning of the file is shown incorrectly
When combine-diff inspected the diff from one parent to the merge result,
it misinterpreted a header in the form @@ -l,k +0,0 @@.

This hunk header means that K lines were removed from the beginning of the
file, so the lost lines must be queued to the sline that represents the
first line of the merge result, but we incremented our pointer incorrectly
and ended up queuing it to the second line, which in turn made the lossage
appear _after_ the first line.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-22 15:38:22 -07:00
Junio C Hamano 55d5d5bab7 combine-diff.c: fix performance problem when folding common deleted lines
For a deleted line in a patch with the parent we are looking at, the
append_lost() function finds the same line among a run of lines that were
deleted from the same location by patches from parents we previously
checked.  This is so that patches with two parents

    @@ -1,4 +1,3 @@    @@ -1,4 +1,3 @@
     one                   one
    -two                  -two
     three                 three
    -quatro               -fyra
    +four                 +four

can be coalesced into this sequence, reusing one line that describes the
removal of "two" for both parents.

   @@@ -1,4 -1,4 +1,3 @@@
     one
   --two
     three
   - quatro
    -frya
   ++four

While reading the second patch (that removes "two" and then "fyra"), after
finding where removal of the "two" matches, we need to find existing
removal of "fyra" (if exists) in the removal list, but the match has to
happen after all the existing matches (in this case "two").  The code used
a naïve O(n^2) algorithm to compute this by scanning the whole removal
list over and over again.

This patch remembers where the next scan should be started in the existing
removal list to avoid this.

Noticed by Linus Torvalds.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-22 15:37:55 -07:00
Thomas Rast 0721c314a5 Use die_errno() instead of die() when checking syscalls
Lots of die() calls did not actually report the kind of error, which
can leave the user confused as to the real problem.  Use die_errno()
where we check a system/library call that sets errno on failure, or
one of the following that wrap such calls:

  Function              Passes on error from
  --------              --------------------
  odb_pack_keep         open
  read_ancestry         fopen
  read_in_full          xread
  strbuf_read           xread
  strbuf_read_file      open or strbuf_read_file
  strbuf_readlink       readlink
  write_in_full         xwrite

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-27 11:14:53 -07:00
Felipe Contreras 4b25d091ba Fix a bunch of pointer declarations (codestyle)
Essentially; s/type* /type */ as per the coding guidelines.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-01 15:17:31 -07:00
Junio C Hamano d1c8c0c8c4 Merge branch 'maint'
* maint:
  diff -c -p: do not die on submodules

Conflicts:
	combine-diff.c
2009-04-29 16:50:31 -07:00
Junio C Hamano 934747323c Merge branch 'maint-1.6.0' into maint-1.6.1
* maint-1.6.0:
  diff -c -p: do not die on submodules
2009-04-29 13:43:13 -07:00
Junio C Hamano 7dae8b21c2 diff -c -p: do not die on submodules
The combine diff logic knew only about blobs (and their checked-out form
in the work tree, either regular files or symlinks), and barfed when fed
submodules.  This "externalizes" gitlinks in the same way as the normal
patch generation codepath does (i.e. "Subproject commit Xxx\n") to fix the
issue.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-29 12:49:52 -07:00
Junio C Hamano a9bfe81309 Merge branch 'kb/checkout-optim'
* kb/checkout-optim:
  Revert "lstat_cache(): print a warning if doing ping-pong between cache types"
  checkout bugfix: use stat.mtime instead of stat.ctime in two places
  Makefile: Set compiler switch for USE_NSEC
  Create USE_ST_TIMESPEC and turn it on for Darwin
  Not all systems use st_[cm]tim field for ns resolution file timestamp
  Record ns-timestamps if possible, but do not use it without USE_NSEC
  write_index(): update index_state->timestamp after flushing to disk
  verify_uptodate(): add ce_uptodate(ce) test
  make USE_NSEC work as expected
  fix compile error when USE_NSEC is defined
  check_updates(): effective removal of cache entries marked CE_REMOVE
  lstat_cache(): print a warning if doing ping-pong between cache types
  show_patch_diff(): remove a call to fstat()
  write_entry(): use fstat() instead of lstat() when file is open
  write_entry(): cleanup of some duplicated code
  create_directories(): remove some memcpy() and strchr() calls
  unlink_entry(): introduce schedule_dir_for_removal()
  lstat_cache(): swap func(length, string) into func(string, length)
  lstat_cache(): generalise longest_match_lstat_cache()
  lstat_cache(): small cleanup and optimisation
2009-03-17 18:54:31 -07:00
Benjamin Kramer fd13b21f52 Move local variables to narrower scopes
These weren't used outside and can be safely moved

Signed-off-by: Benjamin Kramer <benny.kra@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 20:52:23 -08:00
Kjetil Barvik 91fcbcbdcd show_patch_diff(): remove a call to fstat()
Currently inside show_patch_diff() we have an fstat() call after an
ok lstat() call.  Since before the call to fstat() we have already
tested for the link case with S_ISLNK(), the fstat() can be removed.

Signed-off-by: Kjetil Barvik <barvik@broadpark.no>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-09 20:59:26 -08:00
Junio C Hamano 912342d9d6 combine-diff.c: use strbuf_readlink()
When showing combined diff using work tree contents, use strbuf_readlink()
to read symbolic links.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-12-17 13:36:35 -08:00
Brian Downing 9ccd0a88ac Always initialize xpparam_t to 0
We're going to be adding some parameters to this, so we can't have
any uninitialized data in it.

Signed-off-by: Brian Downing <bdowning@lavos.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-25 12:09:31 -07:00
Brandon Casey f285a2d7ed Replace calls to strbuf_init(&foo, 0) with STRBUF_INIT initializer
Many call sites use strbuf_init(&foo, 0) to initialize local
strbuf variable "foo" which has not been accessed since its
declaration. These can be replaced with a static initialization
using the STRBUF_INIT macro which is just as readable, saves a
function call, and takes up fewer lines.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2008-10-12 12:36:19 -07:00
Junio C Hamano e69a6f47c4 Merge branch 'jc/diff-prefix'
* jc/diff-prefix:
  diff: vary default prefix depending on what are compared
2008-09-18 20:30:07 -07:00
Junio C Hamano fdfb4cfadc Merge branch 'jc/hide-cr-in-diff-from-less'
* jc/hide-cr-in-diff-from-less:
  diff: Help "less" hide ^M from the output
2008-09-07 23:45:40 -07:00
Junio C Hamano a5a818ee48 diff: vary default prefix depending on what are compared
With a new configuration "diff.mnemonicprefix", "git diff" shows the
differences between various combinations of preimage and postimage trees
with prefixes different from the standard "a/" and "b/".  Hopefully this
will make the distinction stand out for some people.

    "git diff" compares the (i)ndex and the (w)ork tree;
    "git diff HEAD" compares a (c)ommit and the (w)ork tree;
    "git diff --cached" compares a (c)ommit and the (i)ndex;
    "git-diff HEAD:file1 file2" compares an (o)bject and a (w)ork tree entity;
    "git diff --no-index a b" compares two non-git things (1) and (2).

Because these mnemonics now have meanings, they are swapped when reverse
diff is in effect and this feature is enabled.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-30 20:53:24 -07:00
Junio C Hamano 3928097020 diff: Help "less" hide ^M from the output
When the tracked contents have CRLF line endings, colored diff output
shows "^M" at the end of output lines, which is distracting, even though
the pager we use by default ("less") knows to hide them.

The problem is that "less" hides a carriage-return only at the end of the
line, immediately before a line feed.  The colored diff output does not
take this into account, and emits four element sequence for each line:

   - force this color;
   - the line up to but not including the terminating line feed;
   - reset color
   - line feed.

By including the carriage return at the end of the line in the second
item, we are breaking the smart our pager has in order not to show "^M".
This can be fixed by changing the sequence to:

   - force this color;
   - the line up to but not including the terminating end-of-line;
   - reset color
   - end-of-line.

where end-of-line is either a single linefeed or a CRLF pair.  When the
output is not colored, "force this color" and "reset color" sequences are
both empty, so we won't have this problem with or without this patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-30 20:34:45 -07:00
Junio C Hamano 49d3536594 Merge branch 'maint' to sync with 1.6.0.1 2008-08-24 14:50:44 -07:00
Alexander Gavrilov 5e568f9e30 Respect core.autocrlf in combined diff
Fix git-diff to make it produce useful 3-way diffs for merge conflicts in
repositories with autocrlf enabled. Otherwise it always reports that the
whole file was changed, because it uses the contents from the working tree
without necessary conversion.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-23 23:59:20 -07:00
Junio C Hamano 8a3f524bf2 xdiff-interface: hide the whole "xdiff_emit_state" business from the caller
This further enhances xdi_diff_outf() interface so that it takes two
common parameters: the callback function that processes one line at a
time, and a pointer to its application specific callback data structure.
xdi_diff_outf() creates its own "xdiff_emit_state" structure and stashes
these two away inside it, which is used by the lowest level output
function in the xdiff_outf() callchain, consume_one(), to call back to the
application layer.  With this restructuring, we lift the requirement that
the caller supplied callback data structure embeds xdiff_emit_state
structure as its first member.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-14 00:30:26 -07:00
Brian Downing c99db9d292 Make xdi_diff_outf interface for running xdiff_outf diffs
To prepare for the need to initialize and release resources for an
xdi_diff with the xdiff_outf output function, make a new function to
wrap this usage.

Old:

	ecb.outf = xdiff_outf;
	ecb.priv = &state;
	...
	xdi_diff(file_p, file_o, &xpp, &xecfg, &ecb);

New:

	xdi_diff_outf(file_p, file_o, &state.xm, &xpp, &xecfg, &ecb);

Signed-off-by: Brian Downing <bdowning@lavos.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-13 23:10:23 -07:00
Junio C Hamano bc9c3e0b93 Merge branch 'jc/maint-combine-diff-pre-context'
* jc/maint-combine-diff-pre-context:
  diff -c/--cc: do not include uninteresting deletion before leading context
2008-06-22 14:33:56 -07:00
Junio C Hamano c86fbe5332 diff -c/--cc: do not include uninteresting deletion before leading context
When we include a few uninteresting lines before the interesting ones as
context, we are only interested in seeing the surviving lines themselves
and not the deleted lines that are before them.  Mark the added leading
context lines in give_context() and not show deleted lines form them.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-18 23:59:41 -07:00
Heikki Orsila c697ad143b Cleanup xread() loops to use read_in_full()
Signed-off-by: Heikki Orsila <heikki.orsila@iki.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-05-03 22:15:25 -07:00
Adam Simpkins 028656552b Remove dead code: show_log() sep argument and diff_options.msg_sep
These variables were made unnecessary by commit
3969cf7db1.

Signed-off-by: Adam Simpkins <adam@adamsimpkins.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-05-03 11:48:03 -07:00
Heikki Orsila f0ec47b8e7 Die for an early EOF in a file reading loop
The resulting data is zero terminated after the read loop, but
the subsequent loop that scans for '\n' will overrun the buffer.

Signed-off-by: Heikki Orsila <heikki.orsila@iki.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-27 22:24:55 -07:00
Junio C Hamano d56250911f Fix rewrite_diff() name quoting.
This moves the logic to quote two paths (prefix + path) in
C-style introduced in the previous commit from the
dump_quoted_path() in combine-diff.c to quote.c, and uses it to
fix rewrite_diff() that never C-quoted the pathnames correctly.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-12-26 17:13:36 -08:00
Junio C Hamano 462a15bc82 combine-diff: Fix path quoting
Earlier when showing combined diff, the filenames on the ---/+++
header lines were quoted incorrectly.  a/ (or b/) prefix was
output literally and then the path was output, with c-quoting.

This fixes the quoting logic, and while at it, adjusts the code
to use the customizable prefix (a_prefix and b_prefix)
introduced recently.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-12-26 16:51:19 -08:00
Junio C Hamano c279d7e986 xdl_diff: identify call sites.
This inserts a new function xdi_diff() that currently does not
do anything other than calling the underlying xdl_diff() to the
callchain of current callers of xdl_diff() function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-12-13 23:04:26 -08:00
Pierre Habouzit 8f67f8aefb Make the diff_options bitfields be an unsigned with explicit masks.
reverse_diff was a bit-value in disguise, it's merged in the flags now.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-11 16:54:15 -08:00
Pierre Habouzit 663af3422a Full rework of quote_c_style and write_name_quoted.
* quote_c_style works on a strbuf instead of a wild buffer.
* quote_c_style is now clever enough to not add double quotes if not needed.

* write_name_quoted inherits those advantages, but also take a different
  set of arguments. Now instead of asking for quotes or not, you pass a
  "terminator". If it's \0 then we assume you don't want to escape, else C
  escaping is performed. In any case, the terminator is also appended to the
  stream. It also no longer takes the prefix/prefix_len arguments, as it's
  seldomly used, and makes some optimizations harder.

* write_name_quotedpfx is created to work like write_name_quoted and take
  the prefix/prefix_len arguments.

Thanks to those API changes, diff.c has somehow lost weight, thanks to the
removal of functions that were wrappers around the old write_name_quoted
trying to give it a semantics like the new one, but performing a lot of
allocations for this goal. Now we always write directly to the stream, no
intermediate allocation is performed.

As a side effect of the refactor in builtin-apply.c, the length of the bar
graphs in diffstats are not affected anymore by the fact that the path was
clipped.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
2007-09-20 23:45:49 -07:00
Johannes Schindelin 30b250104d Future-proof source for changes in xdemitconf_t
The instances of xdemitconf_t were initialized member by member.
Instead, initialize them to all zero, so we do not have
to update those places each time we introduce a new member.

[jc: minimally fixed by getting rid of a new global]

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-06 00:22:12 -07:00
Johan Herland 8a912bcb25 Ensure return value from xread() is always stored into an ssize_t
This patch fixes all calls to xread() where the return value is not
stored into an ssize_t. The patch should not have any effect whatsoever,
other than putting better/more appropriate type names on variables.

Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-05-15 21:16:03 -07:00
Junio C Hamano f1af60bdba Support 'diff=pgm' attribute
This enhances the attributes mechanism so that external programs
meant for existing GIT_EXTERNAL_DIFF interface can be specifed
per path.

To configure such a custom diff driver, first define a custom
diff driver in the configuration:

	[diff "my-c-diff"]
		command = <<your command string comes here>>

Then mark the paths that you want to use this custom driver
using the attribute mechanism.

	*.c	diff=my-c-diff

The intent of this separation is that the attribute mechanism is
used for specifying the type of the contents, while the
configuration mechanism is used to define what needs to be done
to that type of the contents, which would be specific to both
platform and personal taste.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-22 22:16:14 -07:00
Shawn O. Pearce dc49cd769b Cast 64 bit off_t to 32 bit size_t
Some systems have sizeof(off_t) == 8 while sizeof(size_t) == 4.
This implies that we are able to access and work on files whose
maximum length is around 2^63-1 bytes, but we can only malloc or
mmap somewhat less than 2^32-1 bytes of memory.

On such a system an implicit conversion of off_t to size_t can cause
the size_t to wrap, resulting in unexpected and exciting behavior.
Right now we are working around all gcc warnings generated by the
-Wshorten-64-to-32 option by passing the off_t through xsize_t().

In the future we should make xsize_t on such problematic platforms
detect the wrapping and die if such a file is accessed.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-07 11:15:26 -08:00
Johannes Sixt a249a9b5a2 Tell multi-parent diff about core.symlinks.
When core.symlinks is false, and a merge of symbolic links had conflicts,
the merge result is left as a file in the working directory. A decision
must be made whether the file is treated as a regular file or as a
symbolic link. This patch treats the file as a symbolic link only if
all merge parents were also symbolic links.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-03 19:30:34 -08:00
Nicolas Pitre 21666f1aae convert object type handling from a string to a number
We currently have two parallel notation for dealing with object types
in the code: a string and a numerical value.  One of them is obviously
redundent, and the most used one requires more stack space and a bunch
of strcmp() all over the place.

This is an initial step for the removal of the version using a char array
found in object reading code paths.  The patch is unfortunately large but
there is no sane way to split it in smaller parts without breaking the
system.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-27 01:34:21 -08:00
Jim Meyering ee24ee55c2 diff --cc: integer overflow given a 2GB-or-larger file
Few of us use git to compare or even version-control 2GB files,
but when we do, we'll want it to work.

Reading a recent patch, I noticed two lines like this:

   int len = st.st_size;

Instead of "int", that should be "size_t".  Otherwise, in the
non-symlink case, with 64-bit size_t, if the file's size is 2GB,
the following xmalloc will fail:

   result = xmalloc(len + 1);

trying to allocate 2^64 - 2^31 + 1 bytes (assuming sign-extension
in the int-to-size_t promotion).  And even if it didn't fail, the
subsequent "result[len] = 0;" would be equivalent to an unpleasant
"result[-2147483648] = 0;"

The other nearby "int"-declared size variable, sz, should also be of
type size_t, for the same reason.  If sz ever wraps around and becomes
negative, xread will corrupt memory _before_ the "result" buffer.

Signed-off-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-27 01:03:37 -08:00
Junio C Hamano 4fc970c438 diff --cc: fix display of symlink conflicts during a merge.
"git-diff-files --cc" to show conflicts during merge did not pass
the correct mode information for the working tree down, and showed
bogus combined diff.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-25 22:25:30 -08:00
Junio C Hamano 3b0f5e88ee combine-diff: special case --unified=0
Even when --unified=0 is given, the main loop to show the
combined textual diff needs to handle a line that is unchanged
but has lines that were deleted relative to a parent before it
(because that is where the lost lines hang).  However, such a
line should not be emitted in the final output.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-03 16:31:11 -08:00
Junio C Hamano af70fa4f48 Merge branch 'jc/combined'
* jc/combined:
  combine-diff: honour --no-commit-id
  combine-diff: fix hunk_comment_line logic.
2006-10-26 02:07:18 -07:00
Junio C Hamano 44152787bc combine-diff: honour --no-commit-id
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-26 02:05:59 -07:00
Junio C Hamano 7a8ac59f2f combine-diff: fix hunk_comment_line logic.
We forgot that the last element of sline[] is a sentinel without
the actual line.  *BLUSH*

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-26 02:05:05 -07:00
Junio C Hamano e893f7ad73 Merge branch 'jc/combined'
* jc/combined:
  combine-diff: a few more finishing touches.
  Documentation: clarify refname disambiguation rules.
  diff-format.txt: Combined diff format documentation supplement
  Remove --syslog in git-daemon inetd documentation examples.
  Documentation: updates to "Everyday GIT"
2006-10-26 01:18:55 -07:00
Junio C Hamano d5f6a01af0 combine-diff: a few more finishing touches.
"new file" and "deleted file" were already reported in the
original code, but the logic was not as transparent as it could
have.  This uses a few variables and more comments to clarify
the flow.  The rule is: (1) if a path exists in the merge result
when no parent had it, we report "new" (otherwise it came from
the parents, as opposed to have added by the evil merge). (2) if
the path does not exist in the merge result, it is "deleted".

Since we can say "new" and "deleted", there is no reason not to
follow the /dev/null convention.  This fixes it.

Appending function name after @@@ ... @@@ is trivial, so
implement it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-26 01:18:49 -07:00
Junio C Hamano 74e2abe5b7 diff --numstat
[jc: with documentation from Jakub]

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-10-13 21:37:10 -07:00
Shawn Pearce e702496e43 Convert memcpy(a,b,20) to hashcpy(a,b).
This abstracts away the size of the hash values when copying them
from memory location to memory location, much as the introduction
of hashcmp abstracted away hash value comparsion.

A few call sites were using char* rather than unsigned char* so
I added the cast rather than open hashcpy to be void*.  This is a
reasonable tradeoff as most call sites already use unsigned char*
and the existing hashcmp is also declared to be unsigned char*.

[jc: Splitted the patch to "master" part, to be followed by a
 patch for merge-recursive.c which is not in "master" yet.

 Fixed the cast in the latter hunk to combine-diff.c which was
 wrong in the original.

 Also converted ones left-over in combine-diff.c, diff-lib.c and
 upload-pack.c ]

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-23 13:53:10 -07:00
David Rientjes a89fccd281 Do not use memcmp(sha1_1, sha1_2, 20) with hardcoded length.
Introduces global inline:

	hashcmp(const unsigned char *sha1, const unsigned char *sha2)

Uses memcmp for comparison and returns the result based on the length of
the hash name (a future runtime decision).

Acked-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-17 14:23:53 -07:00
David Rientjes 0bef57ee44 make inline is_null_sha1 global
Replace sha1 comparisons to null_sha1 with a global inline (which previously an
unused static inline in builtin-apply.c)

[jc: with a fix from Jonas Fonseca.]

Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-15 15:06:03 -07:00
Junio C Hamano a976b0a593 Remove combine-diff.c::uninteresting()
A patch from David Rientjes made me realize we do not have to have
this function -- just call diff_unmodified_pair() directly.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-14 18:41:12 -07:00
Junio C Hamano 89b0c4b5a3 Fix type of combine-diff.c::show_patch_diff()
The other function, show_raw_diff() is void and no callers use
return value from neither.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-13 19:19:34 -07:00
Junio C Hamano 567a03d14c combine-diff: use color
Using the same mechanism as the regular diffs, color combined diff
output.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-10 00:30:33 -07:00
Peter Eriksen 28f7581806 Substitute xmalloc()+memset(0) with xcalloc().
Signed-off-by: Peter Eriksen <s022018@student.dtu.dk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-25 14:08:09 -07:00
Pavel Roskin 82e5a82fd7 Fix more typos, primarily in the code
The only visible change is that git-blame doesn't understand
"--compability" anymore, but it does accept "--compatibility" instead,
which is already documented.

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-10 00:36:44 -07:00
Junio C Hamano 0c926a3d9c Merge branch 'th/diff'
* th/diff:
  builtin-diff: turn recursive on when defaulting to --patch format.
  t4013: note improvements brought by the new output code.
  t4013: add format-patch tests.
  format-patch: fix diff format option implementation
  combine-diff.c: type sanity.
  t4013 test updates for new output code.
  Fix some more diff options changes.
  Fix diff-tree -s
  log --raw: Don't descend into subdirectories by default
  diff-tree: Use ---\n as a message separator
  Print empty line between raw, stat, summary and patch
  t4013: add more tests around -c and --cc
  whatchanged: Default to DIFF_FORMAT_RAW
  Don't xcalloc() struct diffstat_t
  Add msg_sep to diff_options
  DIFF_FORMAT_RAW is not default anymore
  Set default diff output format after parsing command line
  Make --raw option available for all diff commands
  Merge with_raw, with_stat and summary variables to output_format
  t4013: add tests for diff/log family output options.
2006-07-05 16:31:24 -07:00
Junio C Hamano 2c0b4dfd5a combine-diff.c: type sanity.
In diff_tree_combined(), show_log_first boolean is initialized with
rev->loginfo (pointer to a string); the intention is that if we have
some string to be emitted we would want to remember that fact.  Picky
compilers are offended by this, so make the expression a bit type-safer.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-28 03:58:55 -07:00
Junio C Hamano 2386c2975d combine-diff.c: type sanity
- combine_diff() took cnt (count) which is unsigned in nature but the
  parameter type was declared as "int";
- find_next() took "uninteresting" parameter, which masked a static
  function of the same name;
- show_parent_lno() took an unused parameter "cnt";
- show_patch_diff() used a local variable in nested inner scope with
  the same name with different type, masking the one in the outer scope;
- the last loop in show_patch_diff iterated over lines so it should use
  the local variable "lno"

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-28 01:38:19 -07:00
Junio C Hamano 3969cf7db1 Fix some more diff options changes.
This fixes various problems in the new diff options code.

 - Fix --cc/-c --patch; it showed two-tree diff used internally.

 - Use "---\n" only where it matters -- that is, use it
   immediately after the commit log text when we show a
   commit log and something else before the patch text.

 - Do not output spurious extra "\n"; have an extra newline
   after the commit log text always when we have diff output and
   we are not doing oneline.

 - When running a pickaxe you need to go recursive.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-27 15:33:40 -07:00
Timo Hirvonen 39bc9a6c20 Add msg_sep to diff_options
Add msg_sep variable to struct diff_options.  msg_sep is printed after
commit message.  Default is "\n", format-patch sets it to "---\n".

This also removes the second argument from show_log() because all
callers derived it from the first argument:

    show_log(rev, rev->loginfo, ...

Signed-off-by: Timo Hirvonen <tihirvon@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-26 14:58:41 -07:00
Timo Hirvonen c6744349df Merge with_raw, with_stat and summary variables to output_format
DIFF_FORMAT_* are now bit-flags instead of enumerated values.

Signed-off-by: Timo Hirvonen <tihirvon@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-26 14:58:40 -07:00
Linus Torvalds ee1e5412a7 git diff: support "-U" and "--unified" options properly
We used to parse "-U" and "--unified" as part of the GIT_DIFF_OPTS
environment variable, but strangely enough we would _not_ parse them as
part of the normal diff command line (where we only accepted "-u").

This adds parsing of -U and --unified, both with an optional numeric
argument. So now you can just say

	git diff --unified=5

to get a unified diff with a five-line context, instead of having to do
something silly like

	GIT_DIFF_OPTS="--unified=5" git diff -u

(that silly format does continue to still work, of course).

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-05-14 16:26:27 -07:00
Junio C Hamano 0fe7c1de16 built-in diff: assorted updates.
"git diff(n)" without --base, --ours, etc. defaults to --cc,
which usually is the same as -p unless you are in the middle of
a conflicted merge, just like the shell script version.

"git diff(n) blobA blobB path" complains and dies.

"git diff(n) tree0 tree1 tree2...treeN" does combined diff that
shows a merge of tree1..treeN to result in tree0.

Giving "-c" option to any command that defaults to "--cc" turns
off dense-combined flag.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-29 01:32:53 -07:00
Junio C Hamano 34e98ea564 Merge branch 'lt/logopt'
* lt/logopt:
  Fix "git log --stat": make sure to set recursive with --stat.
  combine-diff: show diffstat with the first parent.
  git.c: LOGSIZE is unused after log printing cleanup.
  Log message printout cleanups (#3): fix --pretty=oneline
  Log message printout cleanups (#2)
  Log message printout cleanups
  rev-list --header: output format fix
  Fixes for option parsing
  log/whatchanged/show - log formatting cleanup.
  Simplify common default options setup for built-in log family.
  Tentative built-in "git show"
  Built-in git-whatchanged.
  rev-list option parser fix.
  Split init_revisions() out of setup_revisions()
  Fix up rev-list option parsing.
  Fix up default abbrev in setup_revisions() argument parser.
  Common option parsing for "git log --diff" and friends
2006-04-18 13:56:36 -07:00
Junio C Hamano 965f803c32 combine-diff: show diffstat with the first parent.
Asking for stat (either with --stat or --patch-with-stat) gives
you diffstat for the first parent, even under combine-diff.

While the combined patch is useful to highlight the complexity
and interaction of the parts touched by all branches when
reviewing a merge commit, diffstat is a tool to assess the
extent of damage the merge brings in, and showing stat with the
first parent is more sensible than clever per-parent diffstat.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-17 22:53:03 -07:00
Linus Torvalds eab144ac49 Log message printout cleanups (#2)
Here's a further patch on top of the previous one with cosmetic
improvements (no "real" code changes, just trivial updates):

 - it gets the "---" before a diffstat right, including for the combined
   merge case. Righ now the logic is that we always use "---" when we have
   a diffstat, and an empty line otherwise. That's how I visually prefer
   it, but hey, it can be tweaked later.

 - I made "diff --cc/combined" add the "---/+++" header lines too. The
   thing won't be mistaken for a valid diff, since the "@@" lines have too
   many "@" characters (three or more), but it just makes it visually
   match a real diff, which at least to me makes a big difference in
   readability. Without them, it just looks very "wrong".

   I guess I should have taken the filename from each individual entry
   (and had one "---" file per parent), but I didn't even bother to try to
   see how that works, so this was the simple thing.

With this, doing a

	git log --cc --patch-with-stat

looks quite readable, I think. The only nagging issue - as far as I'm
concerned - is that diffstats for merges are pretty questionable the way
they are done now. I suspect it would be better to just have the _first_
diffstat, and always make the merge diffstat be the one for "result
against first parent".

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-17 21:43:15 -07:00
Linus Torvalds 9153983310 Log message printout cleanups
On Sun, 16 Apr 2006, Junio C Hamano wrote:
>
> In the mid-term, I am hoping we can drop the generate_header()
> callchain _and_ the custom code that formats commit log in-core,
> found in cmd_log_wc().

Ok, this was nastier than expected, just because the dependencies between
the different log-printing stuff were absolutely _everywhere_, but here's
a patch that does exactly that.

The patch is not very easy to read, and the "--patch-with-stat" thing is
still broken (it does not call the "show_log()" thing properly for
merges). That's not a new bug. In the new world order it _should_ do
something like

	if (rev->logopt)
		show_log(rev, rev->logopt, "---\n");

but it doesn't. I haven't looked at the --with-stat logic, so I left it
alone.

That said, this patch removes more lines than it adds, and in particular,
the "cmd_log_wc()" loop is now a very clean:

	while ((commit = get_revision(rev)) != NULL) {
		log_tree_commit(rev, commit);
		free(commit->buffer);
		commit->buffer = NULL;
	}

so it doesn't get much prettier than this. All the complexity is entirely
hidden in log-tree.c, and any code that needs to flush the log literally
just needs to do the "if (rev->logopt) show_log(...)" incantation.

I had to make the combined_diff() logic take a "struct rev_info" instead
of just a "struct diff_options", but that part is pretty clean.

This does change "git whatchanged" from using "diff-tree" as the commit
descriptor to "commit", and I changed one of the tests to reflect that new
reality. Otherwise everything still passes, and my other tests look fine
too.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-17 15:18:25 -07:00
Serge E. Hallyn 310f8b5b6d cleanups: Remove unused vars from combine-diff.c
Mod_type in particular sure looks like it wants to be used, but isn't.

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-17 15:06:16 -07:00
Junio C Hamano 02376287ff Merge branch 'jc/combine' into next
* jc/combine:
  stripspace: make sure not to leave an incomplete line.
  git-commit: do not muck with commit message when no_edit is set.
  When showing a commit message, do not lose an incomplete line.
  Retire t5501-old-fetch-and-upload test.
  combine-diff: type fix.
2006-04-12 13:24:48 -07:00
Junio C Hamano 8bc7574b63 combine-diff: type fix.
The variable hunk_end points at a line number, which is
represented as unsigned long by all the other variables.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-12 13:23:50 -07:00
Junio C Hamano 72c159f642 Merge branch 'jc/combine' into next
* jc/combine:
  combine-diff: fix hunks at the end (take #2).
  combine-diff: do not lose hunks with only deletion at end.
2006-04-11 14:34:59 -07:00
Junio C Hamano 740659519e combine-diff: fix hunks at the end (take #2).
The previous round showed the delete-only hunks at the end, but
forgot to mark them interesting when they were.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-11 14:31:31 -07:00
Junio C Hamano 8a470ebfa1 combine-diff: do not lose hunks with only deletion at end.
We used to lose hunks that appear at the end and have only
deletion.  This makes sure that the record beyond the end of
file (which holds such deletions) is examined.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-11 12:06:27 -07:00
Petr Baudis 90c1b08c7d Separate the raw diff and patch with a newline
More friendly for human reading I believe, and possibly friendlier to some
parsers (although only by an epsilon).

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-11 11:17:50 -07:00
Junio C Hamano 86ff1d2012 diff-* --patch-with-raw
This new flag outputs the diff-raw output and diff-patch output
at the same time.  Requested by Cogito.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-10 19:44:18 -07:00
Junio C Hamano a0fd31463b Match ofs/cnt types in diff interface.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-06 22:29:55 -07:00
Junio C Hamano c1e335a43f combine-diff: move the code to parse hunk-header into common library.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-05 12:22:35 -07:00
Junio C Hamano d9ea73e056 combine-diff: refactor built-in xdiff interface.
This refactors the line-by-line callback mechanism used in
combine-diff so that other programs can reuse it more easily.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-05 02:09:58 -07:00
Junio C Hamano f23fc773a2 combine-diff: use built-in xdiff.
Now there is no GNU diff invocations, except the one from
blame.c

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-04 14:53:43 -07:00
Peter Eriksen 8e44025925 Use blob_, commit_, tag_, and tree_type throughout.
This replaces occurences of "blob", "commit", "tag", and "tree",
where they're really used as type specifiers, which we already
have defined global constants for.

Signed-off-by: Peter Eriksen <s022018@student.dtu.dk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-04 00:11:19 -07:00
Junio C Hamano 1b0c7174a1 tree/diff header cleanup.
Introduce tree-walk.[ch] and move "struct tree_desc" and
associated functions from various places.

Rename DIFF_FILE_CANON_MODE(mode) macro to canon_mode(mode) and
move it to cache.h.  This macro returns the canonicalized
st_mode value in the host byte order for files, symlinks and
directories -- to be compared with a tree_desc entry.
create_ce_mode(mode) in cache.h is similar but is intended to be
used for index entries (so it does not work for directories) and
returns the value in the network byte order.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-03-29 23:54:13 -08:00
Mark Wooding 6baf0484ef combine-diff: Honour -z option correctly.
Combined diffs don't null terminate things in the same way as standard
diffs.  This is presumably wrong.

Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-27 11:01:22 -08:00
Mark Wooding e70c6b3574 combine-diff: Honour --full-index.
For some reason, combined diffs don't honour the --full-index flag when
emitting patches.  Fix this.

Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-27 11:01:05 -08:00
Junio C Hamano 713a11fceb combine-diff: diff-files fix.
When showing a conflicted merge from index stages and working
tree file, we did not fetch the mode from the working tree,
and mistook that as a deleted file.  Also if the manual
resolution (or automated resolution by git rerere) ended up
taking either parent's version, we did not show _anything_ for
that path.  Either was quite bad and confusing.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-13 23:07:04 -08:00
Junio C Hamano d416df8869 combine-diff: Record diff status a bit more faithfully
This shows "new file mode XXXX" and "deleted file mode XXXX"
lines like two-way diff-patch output does, by checking the
status from each parent.

The diff-raw output for combined diff is made a bit uglier by
showing diff status letters with each parent.  While most of the
case you would see "MM" in the output, an Evil Merge that
touches a path that was added by inheriting from one parent is
possible and it would be shown like these:

    $ git-diff-tree --abbrev -c HEAD
    2d7ca89675eb8888b0b88a91102f096d4471f09f
    ::000000 000000 100644 0000000... 0000000... 31dd686... AA	b
    ::000000 100644 100644 0000000... 6c884ae... c6d4fa8... AM	d
    ::100644 100644 100644 4f7cbe7... f8c295c... 19d5d80... RR	e

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-10 02:50:53 -08:00
Junio C Hamano 297a1aadbe find_unique_abbrev() simplification.
Earlier it did not grok the 0{40} SHA1 very well, but what it
needed to do was to find the shortest 0{N} that is not used as a
valid object name to be consistent with the way names of valid
objects are abbreviated.  This makes some users simpler.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-10 01:51:12 -08:00
Junio C Hamano 0a798076b8 combine-diff: move formatting logic to show_combined_diff()
This way, diff-files can make use of it.  Also implement the
full suite of what diff_flush_raw() supports just for
consistency.  With this, 'diff-tree -c -r --name-status' would
show what is expected.

There is no way to get the historical output (useful for
debugging and low-level Plumbing work) anymore, so tentatively
it makes '-m' to mean "do not combine and show individual diffs
with parents".

diff-files matches diff-tree to produce raw output for -c.  For
textual combined diff, use -p -c.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-09 15:23:06 -08:00
Junio C Hamano 5b23683251 combined-diff: use diffcore before intersecting paths.
This is needed to make "diff-tree -c -M" to work semi-sensibly.
Otherwise rename detection, pickaxe and friends would never be
invoked.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-09 14:35:19 -08:00
Linus Torvalds ee63802422 diff-tree -c raw output
NOTE! This makes "-c" be the default, which effectively means that merges 
are never ignored any more, and "-m" is a no-op. So it changes semantics.

I would also like to make "--cc" the default if you do patches, but didn't 
actually do that.

The raw output format is not wonderfully pretty, but it's distinguishable 
from a "normal patch" in that a normal patch with just one parent has just 
one colon at the beginning, while a multi-parent raw diff has <n> colons 
for <n> parents.

So now, in the kernel, when you do

	git-diff-tree cce0cac125623f9b68f25dd1350f6d616220a8dd

(to see the manual ARM merge that had a conflict in arch/arm/Kconfig), you 
get

	cce0cac125623f9b68f25dd1350f6d616220a8dd
	::100644 100644 100644 4a63a8e2e45247a11c068c6ed66c6e7aba29ddd9 77eee38762d69d3de95ae45dd9278df9b8225e2c 2f61726d2f4b636f6e66696700dbf71a59dad287       arch/arm/Kconfig

ie you see two colons (two parents), then three modes (parent modes 
followed by result mode), then three sha1s (parent sha1s followed by
result sha1).

Which is pretty close to the normal raw diff output.

Cool/stupid exercise:

	$ git-whatchanged | grep '^::' | cut -f2- | sort |
	  uniq -c | sort -n | less -S

will show which files have needed the most file-level merge conflict
resolution. Useful? Probably not. But kind of interesting.

For the kernel, it's

     ....
     10 arch/ia64/Kconfig
     11 drivers/scsi/Kconfig
     12 drivers/net/Makefile
     17 include/linux/libata.h
     18 include/linux/pci_ids.h
     23 drivers/net/Kconfig
     24 drivers/scsi/libata-scsi.c
     28 drivers/scsi/libata-core.c
     43 MAINTAINERS

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-09 11:46:05 -08:00
Junio C Hamano 4462731e05 combine-diff: do not punt on removed or added files.
When we remove a file, the parents' contents are all removed so
it is not that interesting to show all of them, but the fact it
was removed when all parents had it *is* unusual.  When we add a
file, similarly the fact it was added when no parent wanted it
*is* unusual, and in addition the result matters, so show it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-06 18:54:08 -08:00
Junio C Hamano 2454c962fb combine-diff: show mode changes as well.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-06 13:06:49 -08:00
Junio C Hamano 9843a1f6fd combine-diff: do not send NULL to printf
When we run combined diff from working tree (diff-files --cc),
we sent NULL to printf that is returned by find_unique_abbrev().

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-06 12:30:00 -08:00
Junio C Hamano e3c3a550d4 combine-diff: remove misguided --show-empty hack.
Now --always flag is available in diff-tree, there is no reason
to have that hack in the diffcore side.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-05 22:25:00 -08:00
Junio C Hamano f7a3d33f0f combine-diff: finishing touches to git-diff-tree --cc
This updates the output format to make administrative lines more
consistent with the traditional diffs.

The "index" line shows blob object names from each parents
(separated by commas), double dots and the object name of the
resulting blob.

The hunk header line begins with N+1 '@' characters for N-way
diff, the line number L of the first line in the hunk and line
count C from the parent in "-L,C" format for each parents and
then the line number of the first line in the hunk and line
count from the resulting file in "+L,C" format, and finally
N+1 '@' characters (earlier versions had the line numbers from
the resulting file at the beginning).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 17:53:26 -08:00
Junio C Hamano 46dc941246 combine-diff: cleanup.
The flag on the surviving lines meant "this parent is not
different" while the parent_map flag on the lost lines meant
"this parent is different", which was confusing.  So swap the
meaning of on-bit in the flag.  Also more heavily comment the
code.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 17:53:26 -08:00
Junio C Hamano f16706cc59 combine-diff: show parent line numbers as well.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 17:53:26 -08:00
Junio C Hamano b469d8b6f7 combine-diff: add a bit more comments.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 17:53:25 -08:00
Junio C Hamano 823bcd6edc combine-diff: fix placement of deletion.
The code misplaced a raw hunk that consists of solely deleted
lines by one line.  This showed e.g. Len's 12-way octopus
(9fdb62af in the linux-2.6), kernel/power/disk.c, hunk starting
at line 95, incorrectly.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 05:21:14 -08:00
Junio C Hamano fd4b1d2193 combine-diff: add safety check to --cc.
The earlier change implemented "only two version" check but
without checking if the change rewrites from all the parents.
This implements a check to make sure that a change introduced
by the merge from all the parents is caught to be interesting.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 02:02:20 -08:00
Junio C Hamano bf1c32bdec combine-diff: update --cc "uninteresting hunks" logic.
Earlier logic was discarding hunks that has difference from only
one parent or the same difference from all but one parent.  This
changes it to check if the differences on all lines are from the
same sets of parents.  This discards more uninteresting hunks
and seems to match expectations more naturally.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 02:02:20 -08:00
Junio C Hamano 3c39e9bdeb combine-diff: reuse diff from the same blob.
When dealing with an insanely large Octopus, it is possible to
optimize by noticing that more than one parents have the same
blob and avoid running diff between a parent and the merge
result by reusing an earlier result.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-02 02:02:20 -08:00
Junio C Hamano ea726d02e9 diff-files: -c and --cc options.
This ports the "combined diff" to diff-files so that differences
to the working tree files since stage 2 and stage 3 are shown
the same way as combined diff output from diff-tree for the
merge commit would be shown if the current working tree files
are committed.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano 3ec1909fda combine-diff: better hunk splitting.
It considered an otherwise unchanged line that had line removals
in front of it an interesting line, which caused hunks to have
one extra the trailing context line.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano 8828cdcb44 diff-tree --cc: squelch header generation on empty patch.
Earlier round showed the commit log header and "diff --combined"
header even for paths that had no interesting hunk under --cc
flag.  Move the header display logic around to squelch them.
With this, a merge that does not have any interesting merges
will not be shown with --cc option, unless -m is used at the
same time.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano 263eee29e9 combine-diff: extend --cc logic to Octopus.
Santi Bejar points out that a hunk that changes from all the
same common parents except one is uninteresting.  The earlier
round marked changes from only one parent uninteresting, but
this also marks hunks that have the same change from all but one
parent uninteresting, which is a natural extension of the
original idea to Octopus merges.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano e228340961 combine-diff: minor output changes.
Remove extra whitespace between the change indicators and the
body text.  That is more in line with the uncombined unified
diff output (pointed out by Santi Bejar).

When showing --cc, say so instead of saying just --combined.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano 5290a0f812 combine-diff: fix appending at the tail of a list.
... and use the established pattern of tail initialized to point
at the head pointer for an empty list, and updated to point at
the next pointer field of the item at the tail when appending.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:29 -08:00
Junio C Hamano d8f4790e6f diff-tree --cc: denser combined diff output for a merge commit.
Building on the previous '-c' (combined) option, '--cc' option
squelches the output further by omitting hunks that consist of
difference with solely one parent.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:28 -08:00
Junio C Hamano af3feefa1d diff-tree -c: show a merge commit a bit more sensibly.
A new option '-c' to diff-tree changes the way a merge commit is
displayed when generating a patch output.  It shows a "combined
diff" (hence the option letter 'c'), which looks like this:

    $ git-diff-tree --pretty -c -p fec9ebf1 | head -n 18
    diff-tree fec9ebf... (from parents)
    Merge: 0620db3... 8a263ae...
    Author: Junio C Hamano <junkio@cox.net>
    Date:   Sun Jan 15 22:25:35 2006 -0800

	Merge fixes up to GIT 1.1.3

    diff --combined describe.c
    @@@ +98,7 @@@
	    return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
       }

    -  static void describe(char *arg)
     - static void describe(struct commit *cmit, int last_one)
    ++ static void describe(char *arg, int last_one)
       {
     +      unsigned char sha1[20];
     +      struct commit *cmit;

There are a few things to note about this feature:

 - The '-c' option implies '-p'.  It also implies '-m' halfway
   in the sense that "interesting" merges are shown, but not all
   merges.

 - When a blob matches one of the parents, we do not show a diff
   for that path at all.  For a merge commit, this option shows
   paths with real file-level merge (aka "interesting things").

 - As a concequence of the above, an "uninteresting" merge is
   not shown at all.  You can use '-m' in addition to '-c' to
   show the commit log for such a merge, but there will be no
   combined diff output.

 - Unlike "gitk", the output is monochrome.

A '-' character in the nth column means the line is from the nth
parent and does not appear in the merge result (i.e. removed
from that parent's version).

A '+' character in the nth column means the line appears in the
merge result, and the nth parent does not have that line
(i.e. added by the merge itself or inherited from another
parent).

The above example output shows that the function signature was
changed from either parents (hence two "-" lines and a "++"
line), and "unsigned char sha1[20]", prefixed by a " +", was
inherited from the first parent.

The code as sent to the list was buggy in few corner cases,
which I have fixed since then.

It does not bother to keep track of and show the line numbers
from parent commits, which it probably should.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-28 00:08:28 -08:00