summaryrefslogtreecommitdiff
path: root/tree-diff.c
Commit message (Collapse)AuthorAgeFilesLines
...
* tree-diff: rename compare_tree_entry -> tree_entry_pathcmpKirill Smelkov2014-03-201-6/+9
| | | | | | | | | | | | Since previous commit, this function does not compare entry hashes, and mode are compared fully outside of it. So what it does is compare entry names and DIR bit in modes. Reflect this in its name. Add documentation stating the semantics, and move the note about files/dirs comparison to it. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: move all action-taking code out of compare_tree_entry()Kirill Smelkov2014-03-201-16/+12
| | | | | | | | | | | | | | - let it do only comparison. This way the code is cleaner and more structured - cmp function only compares, and the driver takes action based on comparison result. There should be no change in performance, as effectively, we just move if series from on place into another, and merge it to was-already-there same switch/if, so the result is maybe a little bit faster. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: don't assume compare_tree_entry() returns -1,0,1Kirill Smelkov2014-03-201-8/+14
| | | | | | | | | | | | | | | | | | | | | | It does, but we'll be reworking it in the next patch after it won't, and besides it is better to stick to standard strcmp/memcmp/base_name_compare/etc... convention, where comparison function returns <0, =0, >0 Regarding performance, comparing for <0, =0, >0 should be a little bit faster, than switch, because it is just 1 test-without-immediate instruction and then up to 3 conditional branches, and in switch you have up to 3 tests with immediate and up to 3 conditional branches. No worry, that update_tree_entry(t2) is duplicated for =0 and >0 - it will be good after we'll be adding support for multiparent walker and will stay that way. =0 case goes first, because it happens more often in real diffs - i.e. paths are the same. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: consolidate code for emitting diffs and recursion in one placeKirill Smelkov2014-03-201-30/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | Currently both compare_tree_entry() and show_entry() invoke opt diff callbacks (opt->add_remove() and opt->change()), and also they both have code which decides whether to recurse into sub-tree, and whether to emit a tree as separate entry if DIFF_OPT_TREE_IN_RECURSIVE is set. I.e. we have code duplication and logic scattered on two places. Let's consolidate it - all diff emiting code and recurion logic moves to show_entry, which is now named as show_path, because it shows diff for a path, based on up to two tree entries, with actual diff emitting code being kept in new helper emit_diff() for clarity. What we have as the result, is that compare_tree_entry is now free from code with logic for diff generation, and also performance is not affected as timings for `git log --raw --no-abbrev --no-renames` for navy.git and `linux.git v3.10..v3.11`, just like in previous patch, stay the same. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: show_tree() is not neededKirill Smelkov2014-03-041-32/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We don't need special code for showing added/removed subtree, because we can do the same via diff_tree_sha1, just passing NULL for absent tree. And compared to show_tree(), which was calling show_entry() for every tree entry, that would lead to the same show_entry() callings: show_tree(t): for e in t.entries: show_entry(e) diff_tree_sha1(NULL, new): /* the same applies to (old, NULL) */ diff_tree(t1=NULL, t2) ... if (!t1->size) show_entry(t2) ... and possible overhead is negligible, since after the patch, timing for `git log --raw --no-abbrev --no-renames` for navy.git and `linux.git v3.10..v3.11` is practically the same. So let's say goodbye to show_tree() - it removes some code, but also, and what is important, consolidates more code for showing/recursing into trees into one place. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: no need to pass match to skip_uninteresting()Kirill Smelkov2014-02-241-9/+8
| | | | | | | | It is neither used there as input, nor the output written through it, is used outside. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: no need to manually verify that there is no mode change for a pathKirill Smelkov2014-02-241-10/+5
| | | | | | | | | | | | | | Because if there is, such two tree entries would never be compared as equal - the code in base_name_compare() explicitly compares modes, if there is a change for dir bit, even for equal paths, entries would compare as different. The code I'm removing here is from 2005 April 262e82b4 (Fix diff-tree recursion), which pre-dates base_name_compare() introduction in 958ba6c9 (Introduce "base_name_compare()" helper function) by a month. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: convert diff_root_tree_sha1() to just call diff_tree_sha1 with ↵Kirill Smelkov2014-02-051-14/+1
| | | | | | | | | | | old=NULL Now since diff_tree_sha1 understands NULL for both old and new, we could indicate an empty tree for root commit by providing just NULL for old sha1. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: allow diff_tree_sha1 to accept NULL sha1Kirill Smelkov2014-02-051-8/+4
| | | | | | | | | | | | | | which would mean that corresponding tree - old or new - is empty. As followup patches will show, that functionality was already needed in several places of Git codebase, but there, we were preparing empty tree_desc objects by hand, with some code duplication. For handling sha1 = NULL case, let's reuse fill_tree_descriptor() which returns just empty tree_desc in that case. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* pathspec: stop --*-pathspecs impact on internal parse_pathspec() usesnd/literal-pathspecsnd/liteal-pathspecsNguyễn Thái Ngọc Duy2013-10-281-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Normally parse_pathspec() is used on command line arguments where it can do fancy thing like parsing magic on each argument or adding magic for all pathspecs based on --*-pathspecs options. There's another use of parse_pathspec(), where pathspec is needed, but the input is known to be pure paths. In this case we usually don't want --*-pathspecs to interfere. And we definitely do not want to parse magic in these paths, regardless of --literal-pathspecs. Add new flag PATHSPEC_LITERAL_PATH for this purpose. When it's set, --*-pathspecs are ignored, no magic is parsed. And if the caller allows PATHSPEC_LITERAL (i.e. the next calls can take literal magic), then PATHSPEC_LITERAL will be set. This fixes cases where git chokes when GIT_*_PATHSPECS are set because parse_pathspec() indicates it won't take any magic. But GIT_*_PATHSPECS add them anyway. These are export GIT_LITERAL_PATHSPECS=1 git blame -- something git log --follow something git log --merge "git ls-files --with-tree=path" (aka parse_pathspec() in overlay_tree_on_cache()) is safe because the input is empty, and producing one pathspec due to PATHSPEC_PREFER_CWD does not take any magic into account. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* pathspec: support :(literal) syntax for noglob pathspecNguyễn Thái Ngọc Duy2013-07-151-1/+1
| | | | | Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-diff: remove the use of pathspec's raw[] in follow-rename codepathNguyễn Thái Ngọc Duy2013-07-151-2/+2
| | | | | | | Put a checkpoint to guard unsupported pathspec features in future. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* remove init_pathspec() in favor of parse_pathspec()Nguyễn Thái Ngọc Duy2013-07-151-5/+5
| | | | | | | While at there, move free_pathspec() to pathspec.c Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* remove diff_tree_{setup,release}_pathsNguyễn Thái Ngọc Duy2013-07-151-14/+4
| | | | | Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* guard against new pathspec magic in pathspec matching codeNguyễn Thái Ngọc Duy2013-07-151-0/+19
| | | | | | | | | | GUARD_PATHSPEC() marks pathspec-sensitive code, basically all those that touch anything in 'struct pathspec' except fields "nr" and "original". GUARD_PATHSPEC() is not supposed to fail. It's mainly to help the designers catch unsupported codepaths. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* parse_pathspec: add special flag for max_depth featureNguyễn Thái Ngọc Duy2013-07-151-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | match_pathspec_depth() and tree_entry_interesting() check max_depth field in order to support "git grep --max-depth". The feature activation is tied to "recursive" field, which led to some unwanted activation, e.g. 5c8eeb8 (diff-index: enable recursive pathspec matching in unpack_trees - 2012-01-15). This patch decouples the activation from "recursive" field, puts it in "magic" field instead. This makes sure that only "git grep" can activate this feature. And because parse_pathspec knows when the feature is not used, it does not need to sort pathspec (required for max_depth to work correctly). A small win for non-grep cases. Even though a new magic flag is introduced, no magic syntax is. The magic can be only enabled by parse_pathspec() caller. We might someday want to support ":(maxdepth:10)src." It all depends on actual use cases. max_depth feature cannot be enabled via init_pathspec() anymore. But that's ok because init_pathspec() is on its way to /dev/null. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'jk/maint-null-in-trees'Junio C Hamano2012-08-271-4/+4
|\ | | | | | | | | | | | | | | | | 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
| * diff: do not use null sha1 as a sentinel valueJeff King2012-07-291-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* | diff_setup_done(): return voidThomas Rast2012-08-031-2/+1
|/ | | | | | | | | | | | | | | | | diff_setup_done() has historically returned an error code, but lost the last nonzero return in 943d5b7 (allow diff.renamelimit to be set regardless of -M/-C, 2006-08-09). The callers were in a pretty confused state: some actually checked for the return code, and some did not. Let it return void, and patch all callers to take this into account. This conveniently also gets rid of a handful of different(!) error messages that could never be triggered anyway. Note that the function can still die(). Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* use custom rename score during --followjk/follow-rename-scoreJeff King2011-12-161-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If you provide a custom rename score on the command line, like: git log -M50 --follow foo.c it is completely ignored, and there is no way to --follow with a looser rename score. Instead, let's use the same rename score that will be used for generating diffs. This is convenient, and mirrors what we do with the break-score. You can see an example of it being useful in git.git: $ git log --oneline --summary --follow \ Documentation/technical/api-string-list.txt 86d4b52 string-list: Add API to remove an item from an unsorted list 1d2f80f string_list: Fix argument order for string_list_append e242148 string-list: add unsorted_string_list_lookup() 0dda1d1 Fix two leftovers from path_list->string_list c455c87 Rename path_list to string_list create mode 100644 Documentation/technical/api-string-list.txt $ git log --oneline --summary -M40 --follow \ Documentation/technical/api-string-list.txt 86d4b52 string-list: Add API to remove an item from an unsorted list 1d2f80f string_list: Fix argument order for string_list_append e242148 string-list: add unsorted_string_list_lookup() 0dda1d1 Fix two leftovers from path_list->string_list c455c87 Rename path_list to string_list rename Documentation/technical/{api-path-list.txt => api-string-list.txt} (47%) 328a475 path-list documentation: document all functions and data structures 530e741 Start preparing the API documents. create mode 100644 Documentation/technical/api-path-list.txt You could have two separate rename scores, one for following and one for diff. But almost nobody is going to want that, and it would just be unnecessarily confusing. Besides which, we re-use the diff results from try_to_follow_renames for the actual diff output, which means having them as separate scores is actively wrong. E.g., with the current code, you get: $ git log --oneline --diff-filter=R --name-status \ -M90 --follow git.spec.in 27dedf0 GIT 0.99.9j aka 1.0rc3 R084 git-core.spec.in git.spec.in f85639c Rename the RPM from "git" to "git-core" R098 git.spec.in git-core.spec.in The first one should not be considered a rename by the -M score we gave, but we print it anyway, since we blindly re-use the diff information from the follow (which uses the default score). So this could also be considered simply a bug-fix, as with the current code "-M" is completely ignored when using "--follow". Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree_entry_interesting(): give meaningful names to return valuesNguyễn Thái Ngọc Duy2011-10-271-7/+9
| | | | | | | | | It is a basic code hygiene to avoid magic constants that are unnamed. Besides, this helps extending the value later on for "interesting, but cannot decide if the entry truely matches yet" (ie. prefix matches) Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tree-walk.c: do not leak internal structure in tree_entry_len()Nguyễn Thái Ngọc Duy2011-10-271-3/+3
| | | | | | | | | | | | | tree_entry_len() does not simply take two random arguments and return a tree length. The two pointers must point to a tree item structure, or struct name_entry. Passing random pointers will return incorrect value. Force callers to pass struct name_entry instead of two pointers (with hope that they don't manually construct struct name_entry themselves) Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'jk/diff-not-so-quick'Junio C Hamano2011-06-061-2/+1
|\ | | | | | | | | | | | | | | | | * jk/diff-not-so-quick: diff: futureproof "stop feeding the backend early" logic diff_tree: disable QUICK optimization with diff filter Conflicts: diff.c
| * diff: futureproof "stop feeding the backend early" logicJunio C Hamano2011-05-311-3/+1
| | | | | | | | | | | | | | | | | | | | | | Refactor the "do not stop feeding the backend early" logic into a small helper function and use it in both run_diff_files() and diff_tree() that has the stop-early optimization. We may later add other types of diffcore transformation that require to look at the whole result like diff-filter does, and having the logic in a single place is essential for longer term maintainability. Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * diff_tree: disable QUICK optimization with diff filterJeff King2011-05-311-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We stop looking for changes early with QUICK, so our diff queue contains only a subset of the changes. However, we don't apply diff filters until later; it will appear at that point as though there are no changes matching our filter, when in reality we simply didn't keep looking for changes long enough. Commit 2cfe8a6 (diff --quiet: disable optimization when --diff-filter=X is used, 2011-03-16) fixes this in some cases by disabling the optimization when a filter is present. However, it only tweaked run_diff_files, missing the similar case in diff_tree. Thus the fix worked only for diffing the working tree and index, but not between trees. Noticed by Yasushi SHOJI. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'nd/struct-pathspec'Junio C Hamano2011-05-061-33/+20
|\ \ | | | | | | | | | | | | | | | | | | | | | * nd/struct-pathspec: pathspec: rename per-item field has_wildcard to use_wildcard Improve tree_entry_interesting() handling code Convert read_tree{,_recursive} to support struct pathspec Reimplement read_tree_recursive() using tree_entry_interesting()
| * | Improve tree_entry_interesting() handling codeNguyễn Thái Ngọc Duy2011-03-251-33/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | t_e_i() can return -1 or 2 to early shortcut a search. Current code may use up to two variables to handle it. One for saving return value from t_e_i temporarily, one for saving return code 2. The second variable is not needed. If we make sure the first variable does not change until the next t_e_i() call, then we can do something like this: int ret = 0; while (...) { if (ret != 2) { ret = t_e_i(); if (ret < 0) /* no longer interesting */ break; if (ret == 0) /* skip this round */ continue; } /* ret > 0, interesting */ } Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Remove unused variablesJohannes Schindelin2011-03-221-2/+1
|/ / | | | | | | | | | | | | Noticed by gcc 4.6.0. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | grep: drop pathspec_matches() in favor of tree_entry_interesting()Nguyễn Thái Ngọc Duy2011-02-031-2/+2
| | | | | | | | | | Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | tree_entry_interesting(): support depth limitNguyễn Thái Ngọc Duy2011-02-031-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | This is needed to replace pathspec_matches() in builtin/grep.c. max_depth == -1 means infinite depth. Depth limit is only effective when pathspec.recursive == 1. When pathspec.recursive == 0, the behavior depends on match functions: non-recursive for tree_entry_interesting() and recursive for match_pathspec{,_depth} Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | diff-tree: convert base+baselen to writable strbufNguyễn Thái Ngọc Duy2011-02-031-68/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In traversing trees, a full path is splitted into two parts: base directory and entry. They are however quite often concatenated whenever a full path is needed. Current code allocates a new buffer, do two memcpy(), use it, then release. Instead this patch turns "base" to a writable, extendable buffer. When a concatenation is needed, the callee only needs to append "entry" to base, use it, then truncate the entry out again. "base" must remain unchanged before and after entering a function. This avoids quite a bit of malloc() and memcpy(). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Move tree_entry_interesting() to tree-walk.c and export itNguyễn Thái Ngọc Duy2011-02-031-112/+0
| | | | | | | | | | Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | tree_entry_interesting(): remove dependency on struct diff_optionsNguyễn Thái Ngọc Duy2011-02-031-16/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This function can be potentially used in more places than just tree-diff.c. "struct diff_options" does not make much sense outside diff_tree_sha1(). While removing the use of diff_options, it also removes tree_entry_extract() call, which means S_ISDIR() uses the entry->mode directly, without being filtered by canon_mode() (called internally inside tree_entry_extract). The only use of the mode information in this function is to check the type of the entry by giving it to S_ISDIR() macro, and the result does not change with or without canon_mode(), so it is ok to bypass tree_entry_extract(). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Convert struct diff_options to use struct pathspecNguyễn Thái Ngọc Duy2011-02-031-35/+13
| | | | | | | | | | Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'en/tree-walk-optim'Junio C Hamano2010-10-261-14/+15
|\ \ | | | | | | | | | | | | | | | | | | | | | * en/tree-walk-optim: diff_tree(): Skip skip_uninteresting() when all remaining paths interesting tree_entry_interesting(): Make return value more specific tree-walk: Correct bitrotted comment about tree_entry() Document pre-condition for tree_entry_interesting
| * | diff_tree(): Skip skip_uninteresting() when all remaining paths interestingElijah Newren2010-08-261-13/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 1d848f6 (tree_entry_interesting(): allow it to say "everything is interesting" 2007-03-21), both show_tree() and skip_uninteresting() were modified to determine if all remaining tree entries were interesting. However, the latter returns as soon as it finds the first interesting path, without any way to signal to its caller (namely, diff_tree()) that all remaining paths are interesting, making these extra checks useless. Pass whether all remaining entries are interesting back to diff_tree(), and whenever they are, have diff_tree() skip subsequent calls to skip_uninteresting(). With this change, I measure speedups of 3-4% for the commands $ git rev-list --quiet HEAD -- Documentation/ $ git rev-list --quiet HEAD -- t/ in git.git. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | tree_entry_interesting(): Make return value more specificElijah Newren2010-08-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | tree_entry_interesting() can signal to its callers not only if the given entry matches one of the specified paths, but whether all remaining paths will (or will not) match. When no paths are specified, all paths are considered interesting, so intead of returning 1 (this path is interesting) return 2 (all paths are interesting). This will allow the caller to avoid calling tree_entry_interesting() again, which theoretically should speed up tree walking. I am not able to measure any actual gains in practice, but it certainly can not hurt and seems to make the code more readable to me. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | Document pre-condition for tree_entry_interestingElijah Newren2010-08-261-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | tree_entry_interesting will fail to find appropriate matches if the base directory path is not terminated with a slash. Knowing this earlier would have saved me some debugging time. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | diff --follow: do call diffcore_std() as necessaryJunio C Hamano2010-08-131-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Usually, diff frontends populate the output queue with filepairs without any rename information and call diffcore_std() to sort the renames out. When --follow is in effect, however, diff-tree family of frontend has a hack that looks like this: diff-tree frontend -> diff_tree_sha1() . populate diff_queued_diff . if --follow is in effect and there is only one change that creates the target path, then -> try_to_follow_renames() -> diff_tree_sha1() with no pathspec but with -C -> diffcore_std() to find renames . if rename is found, tweak diff_queued_diff and put a single filepair that records the found rename there -> diffcore_std() . tweak elements on diff_queued_diff by - rename detection - path ordering - pickaxe filtering We need to skip parts of the second call to diffcore_std() that is related to rename detection, and do so only when try_to_follow_renames() did find a rename. Earlier 1da6175 (Make diffcore_std only can run once before a diff_flush, 2010-05-06) tried to deal with this issue incorrectly; it unconditionally disabled any second call to diffcore_std(). This hopefully fixes the breakage. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | diff --follow: do not waste cycles while recursingJunio C Hamano2010-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The "--follow" logic is called from diff_tree_sha1() function, but the input trees to diff_tree_sha1() are not necessarily the top-level trees (compare_tree_entry() calls it while it recursively descends into subtrees). When a newly created path lives in somewhere deep in the source hierarchy, e.g. "platform/", but the rename source is in a totally different place in the destination hierarchy, e.g. "lang-api/src/com/...", running "try_to_find_renames()" while base is set to "platform/" is a wasted call. We only need to run the rename following at the very top level. Signed-off-by: Junio C Hamano <gitster@pobox.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
* | | Make git log --follow find copies among unmodified files.Bo Yang2010-05-071-1/+1
|/ / | | | | | | | | | | | | | | 'git log --follow <path>' don't track copies from unmodified files, and this patch fix it. Signed-off-by: Bo Yang <struggleyb.nku@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Performance optimization for detection of modified submodulesJens Lehmann2010-01-181-4/+4
|/ | | | | | | | | | | | | | | | | | | In the worst case is_submodule_modified() got called three times for each submodule. The information we got from scanning the whole submodule tree the first time can be reused instead. New parameters have been added to diff_change() and diff_addremove(), the information is stored in a new member of struct diff_filespec. Its value is then reused instead of calling is_submodule_modified() again. When no explicit "-dirty" is needed in the output the call to is_submodule_modified() is not necessary when the submodules HEAD already disagrees with the ref of the superproject, as this alone marks it as modified. To achieve that, get_stat_data() got an extra argument. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* diff: Rename QUIET internal option to QUICKJunio C Hamano2009-07-291-1/+1
| | | | | | | | | | | | | | | The option "QUIET" primarily meant "find if we have _any_ difference as quick as possible and report", which means we often do not even have to look at blobs if we know the trees are different by looking at the higher level (e.g. "diff-tree A B"). As a side effect, because there is no point showing one change that we happened to have found first, it also enables NO_OUTPUT and EXIT_WITH_STATUS options, making the end result look quiet. Rename the internal option to QUICK to reflect this better; it also makes grepping the source tree much easier, as there are other kinds of QUIET option everywhere. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* diff: change semantics of "ignore whitespace" optionsJunio C Hamano2009-07-291-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Traditionally, the --ignore-whitespace* options have merely meant to tell the diff output routine that some class of differences are not worth showing in the textual diff output, so that the end user has easier time to review the remaining (presumably more meaningful) changes. These options never affected the outcome of the command, given as the exit status when the --exit-code option was in effect (either directly or indirectly). When you have only whitespace changes, however, you might expect git diff -b --exit-code to report that there is _no_ change with zero exit status. Change the semantics of --ignore-whitespace* options to mean more than "omit showing the difference in text". The exit status, when --exit-code is in effect, is computed by checking if we found any differences at the path level, while diff frontends feed filepairs to the diffcore engine. When "ignore whitespace" options are in effect, we defer this determination until the very end of diffcore transformation. We simply do not know until the textual diff is generated, which comes very late in the pipeline. When --quiet is in effect, various diff frontends optimize by breaking out early from the loop that enumerates the filepairs, when we find the first path level difference; when --ignore-whitespace* is used the above change automatically disables this optimization. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'ne/maint-1.6.0-diff-tree-t-r-show-directory'Junio C Hamano2009-07-011-0/+6
|\ | | | | | | | | * ne/maint-1.6.0-diff-tree-t-r-show-directory: diff-tree -r -t: include added/removed directories in the output
| * diff-tree -r -t: include added/removed directories in the outputNick Edelen2009-06-131-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | 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 <sirnot@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Fix typos / spelling in commentsMike Ralphson2009-04-221-1/+1
| | | | | | | | | | Signed-off-by: Mike Ralphson <mike@abacus.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | tree_entry_interesting: a pathspec only matches at directory boundaryBjörn Steinbrink2009-04-011-3/+9
|/ | | | | | | | 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 <B.Steinbrink@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* 'git foo' program identifies itself without dash in die() messagesJunio C Hamano2008-08-311-1/+1
| | | | | | | | | | 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 <gitster@pobox.com>
* Fix buffer overflow in git diffDmitry Potapov2008-07-161-5/+22
| | | | | | | | | 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 <dpotapov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>