summaryrefslogtreecommitdiff
path: root/diff-lib.c
AgeCommit message (Collapse)AuthorFilesLines
2012-07-29diff: do not use null sha1 as a sentinel valueLibravatar Jeff King1-8/+12
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-01-16diff-index: enable recursive pathspec matching in unpack_treesLibravatar Nguyen Thai Ngoc Duy1-0/+2
The pathspec structure has a few bits of data to drive various operation modes after we unified the pathspec matching logic in various codepaths. For example, max_depth field is there so that "git grep" can limit the output for files found in limited depth of tree traversal. Also in order to show just the surface level differences in "git diff-tree", recursive field stops us from descending into deeper level of the tree structure when it is set to false, and this also affects pathspec matching when we have wildcards in the pathspec. The diff-index has always wanted the recursive behaviour, and wanted to match pathspecs without any depth limit. But we forgot to do so when we updated tree_entry_interesting() logic to unify the pathspec matching logic. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-10-05Merge branch 'cn/eradicate-working-copy'Libravatar Junio C Hamano1-1/+1
* cn/eradicate-working-copy: Remove 'working copy' from the documentation and C code
2011-10-05Merge branch 'jc/diff-index-unpack'Libravatar Junio C Hamano1-0/+1
* jc/diff-index-unpack: diff-index: pass pathspec down to unpack-trees machinery unpack-trees: allow pruning with pathspec traverse_trees(): allow pruning with pathspec
2011-09-21Remove 'working copy' from the documentation and C codeLibravatar Carlos Martín Nieto1-1/+1
The git term is 'working tree', so replace the most public references to 'working copy'. Signed-off-by: Carlos Martín Nieto <cmn@elego.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-29diff-index: pass pathspec down to unpack-trees machineryLibravatar Junio C Hamano1-0/+1
And finally, pass the pathspec down through unpack_trees() to traverse_trees() callchain. Before and after applying this series, looking for changes in the kernel repository with a fairly narrow pathspec becomes somewhat faster. (without patch) $ /usr/bin/time git diff --raw v2.6.27 -- net/ipv6 >/dev/null 0.48user 0.05system 0:00.53elapsed 100%CPU (0avgtext+0avgdata 163296maxresident)k 0inputs+952outputs (0major+11163minor)pagefaults 0swaps (with patch) $ /usr/bin/time git diff --raw v2.6.27 -- net/ipv6 >/dev/null 0.01user 0.00system 0:00.02elapsed 104%CPU (0avgtext+0avgdata 43856maxresident)k 0inputs+24outputs (0major+3688minor)pagefaults 0swaps Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-08Merge branch 'jc/diff-index-refactor'Libravatar Junio C Hamano1-52/+19
* jc/diff-index-refactor: diff-lib: refactor run_diff_index() and do_diff_cache() diff-lib: simplify do_diff_cache()
2011-08-01Merge branch 'jc/maint-reset-unmerged-path'Libravatar Junio C Hamano1-1/+2
* jc/maint-reset-unmerged-path: reset [<commit>] paths...: do not mishandle unmerged paths
2011-07-13diff-lib: refactor run_diff_index() and do_diff_cache()Libravatar Junio C Hamano1-28/+19
The latter is meant to be an API for internal callers that want to inspect the resulting diff-queue, while the former is an implementation of "git diff-index" command. Extract the common logic into a single helper function and make them thin wrappers around it. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-13diff-lib: simplify do_diff_cache()Libravatar Junio C Hamano1-25/+1
Since 34110cd (Make 'unpack_trees()' have a separate source and destination index, 2008-03-06), we can run unpack_trees() without munging the index at all, but do_diff_cache() tried ever so carefully to work around the old behaviour of the function. We can just tell unpack_trees() not to touch the original index and there is no need to clean-up whatever the previous round has done. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-13reset [<commit>] paths...: do not mishandle unmerged pathsLibravatar Junio C Hamano1-1/+2
Because "diff --cached HEAD" showed an incorrect blob object name on the LHS of the diff, we ended up updating the index entry with bogus value, not what we read from the tree. Noticed by John Nowak. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-06-06Merge branch 'jk/diff-not-so-quick'Libravatar Junio C Hamano1-3/+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
2011-05-31diff-index --quiet: learn the "stop feeding the backend early" logicLibravatar Junio C Hamano1-1/+6
A negative return from the unpack callback function usually means unpack failed for the entry and signals the unpack_trees() machinery to fail the entire merge operation, immediately and there is no other way for the callback to tell the machinery to exit early without reporting an error. This is what we usually want to make a merge all-or-nothing operation, but the machinery is also used for diff-index codepath by using a custom unpack callback function. And we do sometimes want to exit early without failing, namely when we are under --quiet and can short-cut the diff upon finding the first difference. Add "exiting_early" field to unpack_trees_options structure, to signal the unpack_trees() machinery that the negative return value is not signaling an error but an early return from the unpack_trees() machinery. As this by definition hasn't unpacked everything, discard the resulting index just like the failure codepath. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-31Merge remote-tracking branch 'ko/maint' into jc/diff-index-quick-exit-earlyLibravatar Junio C Hamano1-63/+78
* ko/maint: (4352 commits) git-submodule.sh: separate parens by a space to avoid confusing some shells Documentation/technical/api-diff.txt: correct name of diff_unmerge() read_gitfile_gently: use ssize_t to hold read result remove tests of always-false condition rerere.c: diagnose a corrupt MERGE_RR when hitting EOF between TAB and '\0' Git 1.7.5.3 init/clone: remove short option -L and document --separate-git-dir do not read beyond end of malloc'd buffer git-svn: Fix git svn log --show-commit Git 1.7.5.2 provide a copy of the LGPLv2.1 test core.gitproxy configuration copy_gecos: fix not adding nlen to len when processing "&" Update draft release notes to 1.7.5.2 Documentation/git-fsck.txt: fix typo: unreadable -> unreachable send-pack: avoid deadlock on git:// push with failed pack-objects connect: let callers know if connection is a socket connect: treat generic proxy processes like ssh processes sideband_demux(): fix decl-after-stmt t3503: test cherry picking and reverting root commits ... Conflicts: diff.c
2011-05-31diff: futureproof "stop feeding the backend early" logicLibravatar Junio C Hamano1-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>
2011-05-13Merge branch 'jc/fix-diff-files-unmerged' into maintLibravatar Junio C Hamano1-4/+11
* jc/fix-diff-files-unmerged: diff-files: show unmerged entries correctly diff: remove often unused parameters from diff_unmerge() diff.c: return filepair from diff_unmerge() test: use $_z40 from test-lib
2011-05-06Merge branch 'jc/fix-diff-files-unmerged'Libravatar Junio C Hamano1-4/+11
* jc/fix-diff-files-unmerged: diff-files: show unmerged entries correctly diff: remove often unused parameters from diff_unmerge() diff.c: return filepair from diff_unmerge() test: use $_z40 from test-lib
2011-04-23diff-files: show unmerged entries correctlyLibravatar Junio C Hamano1-2/+8
Earlier, e9c8409 (diff-index --cached --raw: show tree entry on the LHS for unmerged entries., 2007-01-05) taught the command to show the object name and the mode from the entry coming from the tree side when comparing a tree with an unmerged index. This is a belated companion patch that teaches diff-files to show the mode from the entry coming from the working tree side, when comparing an unmerged index and the working tree. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-04-23diff: remove often unused parameters from diff_unmerge()Libravatar Junio C Hamano1-3/+4
e9c8409 (diff-index --cached --raw: show tree entry on the LHS for unmerged entries., 2007-01-05) added a <mode, object name> pair as parameters to this function, to store them in the pre-image side of an unmerged file pair. Now the function is fixed to return the filepair it queued, we can make the caller on the special case codepath to do so. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-23Merge branch 'jc/maint-diff-q-filter'Libravatar Junio C Hamano1-1/+2
* jc/maint-diff-q-filter: diff --quiet: disable optimization when --diff-filter=X is used
2011-03-16diff --quiet: disable optimization when --diff-filter=X is usedLibravatar Junio C Hamano1-1/+2
The code notices that the caller does not want any detail of the changes and only wants to know if there is a change or not by specifying --quiet. And it breaks out of the loop when it knows it already found any change. When you have a post-process filter (e.g. --diff-filter), however, the path we found to be different in the previous round and set HAS_CHANGES bit may end up being uninteresting, and there may be no output at the end. The optimization needs to be disabled for such case. Note that the f245194 (diff: change semantics of "ignore whitespace" options, 2009-05-22) already disables this optimization by refraining from setting HAS_CHANGES when post-process filters that need to inspect the contents of the files (e.g. -S, -w) in diff_change() function. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-02-03Convert ce_path_match() to use struct pathspecLibravatar Nguyễn Thái Ngọc Duy1-2/+2
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-02-03struct rev_info: convert prune_data to struct pathspecLibravatar Nguyễn Thái Ngọc Duy1-3/+3
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-02-03Convert struct diff_options to use struct pathspecLibravatar Nguyễn Thái Ngọc Duy1-1/+1
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-08-09Submodules: Add the new "ignore" config option for diff and statusLibravatar Jens Lehmann1-5/+10
The new "ignore" config option controls the default behavior for "git status" and the diff family. It specifies under what circumstances they consider submodules as modified and can be set separately for each submodule. The command line option "--ignore-submodules=" has been extended to accept the new parameter "none" for both status and diff. Users that chose submodules to get rid of long work tree scanning times might want to set the "dirty" option for those submodules. This brings back the pre 1.7.0 behavior, where submodule work trees were never scanned for modifications. By using "--ignore-submodules=none" on the command line the status and diff commands can be told to do a full scan. This option can be set to the following values (which have the same name and meaning as for the "--ignore-submodules" option of status and diff): "all": All changes to the submodule will be ignored. "dirty": Only differences of the commit recorded in the superproject and the submodules HEAD will be considered modifications, all changes to the work tree of the submodule will be ignored. When using this value, the submodule will not be scanned for work tree changes at all, leading to a performance benefit on large submodules. "untracked": Only untracked files in the submodules work tree are ignored, a changed HEAD and/or modified files in the submodule will mark it as modified. "none" (which is the default): Either untracked or modified files in a submodules work tree or a difference between the subdmodules HEAD and the commit recorded in the superproject will make it show up as changed. This value is added as a new parameter for the "--ignore-submodules" option of the diff family and "git status" so the user can override the settings in the configuration. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-11Add optional parameters to the diff option "--ignore-submodules"Libravatar Jens Lehmann1-0/+1
In some use cases it is not desirable that the diff family considers submodules that only contain untracked content as dirty. This may happen e.g. when the submodule is not under the developers control and not all build generated files have been added to .gitignore by the upstream developers. Using the "untracked" parameter for the "--ignore-submodules" option disables checking for untracked content and lets git diff report them as changed only when they have new commits or modified content. Sometimes it is not wanted to have submodules show up as changed when they just contain changes to their work tree. An example for that are scripts which just want to check for submodule commits while ignoring any changes to the work tree. Also users having large submodules known not to change might want to use this option, as the - sometimes substantial - time it takes to scan the submodule work tree(s) is saved. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-24Merge branch 'jl/submodule-diff-dirtiness'Libravatar Junio C Hamano1-18/+27
* jl/submodule-diff-dirtiness: git status: ignoring untracked files must apply to submodules too git status: Fix false positive "new commits" output for dirty submodules Refactor dirty submodule detection in diff-lib.c git status: Show detailed dirty status of submodules in long format git diff --submodule: Show detailed dirty status of submodules
2010-03-13git status: ignoring untracked files must apply to submodules tooLibravatar Jens Lehmann1-1/+1
Since 1.7.0 submodules are considered dirty when they contain untracked files. But when git status is called with the "-uno" option, the user asked to ignore untracked files, so they must be ignored in submodules too. To achieve this, the new flag DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES is introduced. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-12git status: Fix false positive "new commits" output for dirty submodulesLibravatar Jens Lehmann1-4/+2
Testing if the output "new commits" should appear in the long format of "git status" is done by comparing the hashes of the diffpair. This always resulted in printing "new commits" for submodules that contained untracked or modified content, even if they did not contain new commits. The reason was that match_stat_with_submodule() did set the "changed" flag for dirty submodules, resulting in two->sha1 being set to the null_sha1 at the call sites, which indicates that new commits are present. This is changed so that when no new commits are present, the same object names are in the sha1 field for both sides of the filepair, and the working tree side will have the "dirty_submodule" flag set when appropriate. For a submodule to be seen as modified even when it just has a dirty work tree, some conditions had to be extended to also check for the "dirty_submodule" flag. Unfortunately the test case that should have found this bug had been changed incorrectly too. It is fixed and extended to test for other combinations too. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-12Refactor dirty submodule detection in diff-lib.cLibravatar Jens Lehmann1-18/+27
Moving duplicated code into the new function match_stat_with_submodule(). Replacing the implicit activation of detailed checks for the dirtiness of submodules when DIFF_FORMAT_PATCH was selected with explicitly setting the recently added DIFF_OPT_DIRTY_SUBMODULES option in diff_setup_done(). Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-09revision: introduce setup_revision_optLibravatar Junio C Hamano1-1/+4
So far the last parameter to setup_revisions() was to specify the default ref when the command line did not give any (typically "HEAD"). This changes it to take a pointer to a structure so that we can add other information without touching too many codepaths in later patches. There is no functionality change. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-08git status: Show detailed dirty status of submodules in long formatLibravatar Jens Lehmann1-2/+4
Since 1.7.0 there are three reasons a submodule is considered modified against the work tree: It contains new commits, modified content or untracked content. Lets show all reasons in the long format of git status, so the user can better asses the nature of the modification. This change does not affect the short and porcelain formats. Two new members are added to "struct wt_status_change_data" to store the information gathered by run_diff_files(). wt-status.c uses the new flag DIFF_OPT_DIRTY_SUBMODULES to tell diff-lib.c it wants to get detailed dirty information about submodules. A hint line for submodules is printed in the dirty header when dirty submodules are present. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-04git diff --submodule: Show detailed dirty status of submodulesLibravatar Jens Lehmann1-8/+8
When encountering a dirty submodule while doing "git diff --submodule" print an extra line for new untracked content and another for modified but already tracked content. And if the HEAD of the submodule is equal to the ref diffed against in the superproject, drop the output which would just show the same SHA1s and no commit message headlines. To achieve that, the dirty_submodule bitfield is expanded to two bits. The output of "git status" inside the submodule is parsed to set the according bits. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-26Merge branch 'jl/diff-submodule-ignore'Libravatar Junio C Hamano1-5/+7
* jl/diff-submodule-ignore: Teach diff --submodule that modified submodule directory is dirty git diff: Don't test submodule dirtiness with --ignore-submodules Make ce_uptodate() trustworthy again
2010-01-24git diff: Don't test submodule dirtiness with --ignore-submodulesLibravatar Jens Lehmann1-4/+6
The diff family suppresses the output of submodule changes when requested but checks them nonetheless. But since recently submodules get examined for their dirtiness, which is rather expensive. There is no need to do that when the --ignore-submodules option is used, as the gathered information is never used anyway. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-24Merge branch 'jc/fix-tree-walk'Libravatar Junio C Hamano1-18/+1
* jc/fix-tree-walk: read-tree --debug-unpack unpack-trees.c: look ahead in the index unpack-trees.c: prepare for looking ahead in the index Aggressive three-way merge: fix D/F case traverse_trees(): handle D/F conflict case sanely more D/F conflict tests tests: move convenience regexp to match object names to test-lib.sh Conflicts: builtin-read-tree.c unpack-trees.c unpack-trees.h
2010-01-24Make ce_uptodate() trustworthy againLibravatar Junio C Hamano1-1/+1
The rule has always been that a cache entry that is ce_uptodate(ce) means that we already have checked the work tree entity and we know there is no change in the work tree compared to the index, and nobody should have to double check. Note that false ce_uptodate(ce) does not mean it is known to be dirty---it only means we don't know if it is clean. There are a few codepaths (refresh-index and preload-index are among them) that mark a cache entry as up-to-date based solely on the return value from ie_match_stat(); this function uses lstat() to see if the work tree entity has been touched, and for a submodule entry, if its HEAD points at the same commit as the commit recorded in the index of the superproject (a submodule that is not even cloned is considered clean). A submodule is no longer considered unmodified merely because its HEAD matches the index of the superproject these days, in order to prevent people from forgetting to commit in the submodule and updating the superproject index with the new submodule commit, before commiting the state in the superproject. However, the patch to do so didn't update the codepath that marks cache entries up-to-date based on the updated definition and instead worked it around by saying "we don't trust the return value of ce_uptodate() for submodules." This makes ce_uptodate() trustworthy again by not marking submodule entries up-to-date. The next step _could_ be to introduce a few "in-core" flag bits to cache_entry structure to record "this entry is _known_ to be dirty", call is_submodule_modified() from ie_match_stat(), and use these new bits to avoid running this rather expensive check more than once, but that can be a separate patch. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-18Performance optimization for detection of modified submodulesLibravatar Jens Lehmann1-15/+31
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>
2010-01-16Show submodules as modified when they contain a dirty work treeLibravatar Jens Lehmann1-2/+6
Until now a submodule only then showed up as modified in the supermodule when the last commit in the submodule differed from the one in the index or the diffed against commit of the superproject. A dirty work tree containing new untracked or modified files in a submodule was undetectable when looking at it from the superproject. Now git status and git diff (against the work tree) in the superproject will also display submodules as modified when they contain untracked or modified files, even if the compared ref matches the HEAD of the submodule. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-13Merge branch 'nd/sparse'Libravatar Junio C Hamano1-2/+3
* nd/sparse: (25 commits) t7002: test for not using external grep on skip-worktree paths t7002: set test prerequisite "external-grep" if supported grep: do not do external grep on skip-worktree entries commit: correctly respect skip-worktree bit ie_match_stat(): do not ignore skip-worktree bit with CE_MATCH_IGNORE_VALID tests: rename duplicate t1009 sparse checkout: inhibit empty worktree Add tests for sparse checkout read-tree: add --no-sparse-checkout to disable sparse checkout support unpack-trees(): ignore worktree check outside checkout area unpack_trees(): apply $GIT_DIR/info/sparse-checkout to the final index unpack-trees(): "enable" sparse checkout and load $GIT_DIR/info/sparse-checkout unpack-trees.c: generalize verify_* functions unpack-trees(): add CE_WT_REMOVE to remove on worktree alone Introduce "sparse checkout" dir.c: export excluded_1() and add_excludes_from_file_1() excluded_1(): support exclude files in index unpack-trees(): carry skip-worktree bit over in merged_entry() Read .gitignore from index if it is skip-worktree Avoid writing to buffer in add_excludes_from_file_1() ... Conflicts: .gitignore Documentation/config.txt Documentation/git-update-index.txt Makefile entry.c t/t7002-grep.sh
2010-01-07unpack-trees.c: look ahead in the indexLibravatar Junio C Hamano1-0/+1
This makes the traversal of index be in sync with the tree traversal. When unpack_callback() is fed a set of tree entries from trees, it inspects the name of the entry and checks if the an index entry with the same name could be hiding behind the current index entry, and (1) if the name appears in the index as a leaf node, it is also fed to the n_way_merge() callback function; (2) if the name is a directory in the index, i.e. there are entries in that are underneath it, then nothing is fed to the n_way_merge() callback function; (3) otherwise, if the name comes before the first eligible entry in the index, the index entry is first unpacked alone. When traverse_trees_recursive() descends into a subdirectory, the cache_bottom pointer is moved to walk index entries within that directory. All of these are omitted for diff-index, which does not even want to be fed an index entry and a tree entry with D/F conflicts. This fixes 3-way read-tree and exposes a bug in other parts of the system in t6035, test #5. The test prepares these three trees: O = HEAD^ 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/b-2/c/d 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/b/c/d 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/x A = HEAD 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/b-2/c/d 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/b/c/d 100644 blob 587be6b4c3f93f93c489c0111bba5596147a26cb a/x B = master 120000 blob a36b77384451ea1de7bd340ffca868249626bc52 a/b 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/b-2/c/d 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a/x With a clean index that matches HEAD, running git read-tree -m -u --aggressive $O $A $B now yields 120000 a36b77384451ea1de7bd340ffca868249626bc52 3 a/b 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 a/b-2/c/d 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 1 a/b/c/d 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 2 a/b/c/d 100644 587be6b4c3f93f93c489c0111bba5596147a26cb 0 a/x which is correct. "master" created "a/b" symlink that did not exist, and removed "a/b/c/d" while HEAD did not do touch either path. Before this series, read-tree did not notice the situation and resolved addition of "a/b" and removal of "a/b/c/d" independently. If A = HEAD had another path "a/b/c/e" added, this merge should conflict but instead it silently resolved "a/b" and then immediately overwrote it to add "a/b/c/e", which was quite bogus. Tests in t1012 start to work with this. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-07unpack-trees.c: prepare for looking ahead in the indexLibravatar Junio C Hamano1-18/+0
This prepares but does not yet implement a look-ahead in the index entries when traverse-trees.c decides to give us tree entries in an order that does not match what is in the index. A case where a look-ahead in the index is necessary happens when merging branch B into branch A while the index matches the current branch A, using a tree O as their common ancestor, and these three trees looks like this: O A B t t t-i t-i t-i t-j t-j t/1 t/2 The traverse_trees() function gets "t", "t-i" and "t" from trees O, A and B first, and notices that A may have a matching "t" behind "t-i" and "t-j" (indeed it does), and tells A to give that entry instead. After unpacking blob "t" from tree B (as it hasn't changed since O in B and A removed it, it will result in its removal), it descends into directory "t/". The side that walked index in parallel to the tree traversal used to be implemented with one pointer, o->pos, that points at the next index entry to be processed. When this happens, the pointer o->pos still points at "t-i" that is the first entry. We should be able to skip "t-i" and "t-j" and locate "t/1" from the index while the recursive invocation of traverse_trees() walks and match entries found there, and later come back to process "t-i". While that look-ahead is not implemented yet, this adds a flag bit, CE_UNPACKED, to mark the entries in the index that has already been processed. o->pos pointer has been renamed to o->cache_bottom and it points at the first entry that may still need to be processed. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-12-26Merge branch 'jc/1.7.0-diff-whitespace-only-status'Libravatar Junio C Hamano1-2/+2
* jc/1.7.0-diff-whitespace-only-status: diff.c: fix typoes in comments Make test case number unique diff: Rename QUIET internal option to QUICK diff: change semantics of "ignore whitespace" options Conflicts: diff.h
2009-10-11diff-lib.c: fix misleading comments on oneway_diff()Libravatar Junio C Hamano1-1/+1
20a16eb (unpack_trees(): fix diff-index regression., 2008-03-10) adjusted diff-index to the new world order since 34110cd (Make 'unpack_trees()' have a separate source and destination index, 2008-03-06). Callbacks are expected to return anything non-negative as "success", and instead of reporting how many index entries they have processed, they are expected to advance o->pos themselves. The code did so, but a stale comment was left behind. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-28Merge branch 'jc/shortstatus'Libravatar Junio C Hamano1-20/+2
* jc/shortstatus: git commit --dry-run -v: show diff in color when asked Documentation/git-commit.txt: describe --dry-run wt-status: collect untracked files in a separate "collect" phase Make git_status_config() file scope static to builtin-commit.c wt-status: move wt_status_colors[] into wt_status structure wt-status: move many global settings to wt_status structure commit: --dry-run status: show worktree status of conflicted paths separately wt-status.c: rework the way changes to the index and work tree are summarized diff-index: keep the original index intact diff-index: report unmerged new entries
2009-08-23Teach Git to respect skip-worktree bit (reading part)Libravatar Nguyễn Thái Ngọc Duy1-2/+3
grep: turn on --cached for files that is marked skip-worktree ls-files: do not check for deleted file that is marked skip-worktree update-index: ignore update request if it's skip-worktree, while still allows removing diff*: skip worktree version Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-11Prevent diff machinery from examining assume-unchanged entries on worktreeLibravatar Nguyễn Thái Ngọc Duy1-2/+4
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-05diff-index: keep the original index intactLibravatar Junio C Hamano1-18/+0
When comparing the index and a tree, we used to read the contents of the tree into stage #1 of the index and compared them with stage #0. In order not to lose sight of entries originally unmerged in the index, we hoisted them to stage #3 before reading the tree. Commit d1f2d7e (Make run_diff_index() use unpack_trees(), not read_tree(), 2008-01-19) changed all this. These days, we instead use unpack_trees() API to traverse the tree and compare the contents with the index, without modifying the index at all. There is no reason to hoist the unmerged entries to stage #3 anymore. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-05diff-index: report unmerged new entriesLibravatar Junio C Hamano1-2/+2
Since an earlier change to diff-index by d1f2d7e (Make run_diff_index() use unpack_trees(), not read_tree(), 2008-01-19), we stopped reporting an unmerged path that does not exist in the tree, but we should. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-29diff: Rename QUIET internal option to QUICKLibravatar Junio C Hamano1-2/+2
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>