summaryrefslogtreecommitdiff
path: root/unpack-trees.h
AgeCommit message (Collapse)AuthorFilesLines
2008-09-09checkout: do not lose staged removalLibravatar Junio C Hamano1-0/+1
The logic to checkout a different commit implements the safety to never lose user's local changes. For example, switching from a commit to another commit, when you have changed a path that is different between them, need to merge your changes to the version from the switched-to commit, which you may not necessarily be able to resolve easily. By default, "git checkout" refused to switch branches, to give you a chance to stash your local changes (or use "-m" to merge, accepting the risks of getting conflicts). This safety, however, had one deliberate hole since early June 2005. When your local change was to remove a path (and optionally to stage that removal), the command checked out the path from the switched-to commit nevertheless. This was to allow an initial checkout to happen smoothly (e.g. an initial checkout is done by starting with an empty index and switching from the commit at the HEAD to the same commit). We can tighten the rule slightly to allow this special case to pass, without losing sight of removal explicitly done by the user, by noticing if the index is truly empty when the operation begins. For historical background, see: http://thread.gmane.org/gmane.comp.version-control.git/4641/focus=4646 This case is marked as *0* in the message, which both Linus and I said "it feels somewhat wrong but otherwise we cannot start from an empty index". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-05-19unpack-trees: allow Porcelain to give different error messagesLibravatar Junio C Hamano1-0/+9
The plumbing output is sacred as it is an API. We _could_ change it if it is broken in such a way that it cannot convey necessary information fully, but we just do not _reword_ for the sake of rewording. If somebody does not like it, s/he is complaining too late. S/he should have been here in early May 2005 and make the language used by the API closer to what humans read. S/he wasn't here. Too bad, and it is too late. And people who complain should look at a bigger picture. Look at what was suggested by one of them and think for five seconds: $ git checkout mytopic -fatal: Entry 'frotz' not uptodate. Cannot merge. +fatal: Entry 'frotz' has local changes. Cannot merge. If you do not see something wrong with this output, your brain has already been rotten with use of git for too long a time. Nobody asked us to "merge" but why are we talking about "Cannot merge"? This patch introduces a mechanism to allow Porcelains to specify messages that are different from the ones that is given by the underlying plumbing implementation of read-tree, so that we can reword the message Porcelains give without disrupting the output from the plumbing. $ git-checkout pu error: You have local changes to 'Makefile'; cannot switch branches. There are other places that ask unpack_trees() to n-way merge, detect issues and let it issue error message on its own, but I did this as a demonstration and replaced only one message. Yes I know about C99 structure initializers. I'd love to use them but we try to be nice to compilers without it. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-09Make branch merging aware of underlying case-insensitive filsystemsLibravatar Linus Torvalds1-1/+1
If we find an unexpected file, see if that filename perhaps exists in a case-insensitive way in the index, and whether the file matches that. If so, ignore it as a known pre-existing file of a different name. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-09Make unpack_trees_options bit flags actual bitfieldsLibravatar Linus Torvalds1-10/+10
Instead of wasting space with whole integers for a single bit. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-03-13read-tree() and unpack_trees(): use consistent limitLibravatar Junio C Hamano1-0/+2
read-tree -m can read up to MAX_TREES, which was arbitrarily set to 8 since August 2007 (4 is needed to deal with 2 merge-base case). However, the updated unpack_trees() code had an advertised limit of 4 (which it enforced). In reality the code was prepared to take only 3 trees and giving 4 caused it to stomp on its stack. Rename the MAX_TREES constant to MAX_UNPACK_TREES, move it to the unpack-trees.h common header file, and use it from both places to avoid future confusion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-03-09Make 'unpack_trees()' have a separate source and destination indexLibravatar Linus Torvalds1-7/+9
We will always unpack into our own internal index, but we will take the source from wherever specified, and we will optionally write the result to a specified index (optionally, because not everybody even _wants_ any result: the index diffing really wants to just walk the tree and index in parallel). This ends up removing a fair number more lines than it adds, for the simple reason that we can now skip all the crud that tried to be oh-so-careful about maintaining our position in the index as we were traversing and modifying it. Since we don't actually modify the source index any more, we can just update the 'o->pos' pointer without worrying about whether an index entry got removed or replaced or added to. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-03-09Make 'unpack_trees()' take the index to work on as an argumentLibravatar Linus Torvalds1-0/+1
This is just a very mechanical conversion, and makes everybody set it to '&the_index' before calling, but at least it makes it more explicit where we work with the index. The next stage would be to split that index usage up into a 'source' and a 'destination' index, so that we can unpack into a different index than we started out from. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-09Add "skip_unmerged" option to unpack_trees.Libravatar Daniel Barkalow1-0/+1
This option allows the caller to reset everything that isn't unmerged, leaving the unmerged things to be resolved. If, after a merge of "working" and "HEAD", this is used with "HEAD" (reset, !update), the result will be that all of the changes from "local" are in the working tree but not added to the index (either with the index clean but unchanged, or with the index unmerged, depending on whether there are conflicts). This will be used in checkout -m. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
2008-02-09Add flag to make unpack_trees() not print errors.Libravatar Daniel Barkalow1-0/+1
(This applies only to errors where a plausible operation is impossible due to the particular data, not to errors resulting from misuse of the merge functions.) This will allow builtin-checkout to suppress merge errors if it's going to try more merging methods. Additionally, if unpack_trees() returns with an error, but without printing anything, it will roll back any changes to the index (by rereading the index, currently). This obviously could be done by the caller, but chances are that the caller would forget and debugging this is difficult. Also, future implementations may give unpack_trees() a more efficient way of undoing its changes than the caller could. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
2008-01-21Make run_diff_index() use unpack_trees(), not read_tree()Libravatar Linus Torvalds1-0/+1
A plain "git commit" would still run lstat() a lot more than necessary, because wt_status_print() would cause the index to be repeatedly flushed and re-read by wt_read_cache(), and that would cause the CE_UPTODATE bit to be lost, resulting in the files in the index being lstat'ed three times each. The reason why wt-status.c ended up invalidating and re-reading the cache multiple times was that it uses "run_diff_index()", which in turn uses "read_tree()" to populate the index with *both* the old index and the tree we want to compare against. So this patch re-writes run_diff_index() to not use read_tree(), but instead use "unpack_trees()" to diff the index to a tree. That, in turn, means that we don't need to modify the index itself, which then means that we don't need to invalidate it and re-read it! This, together with the lstat() optimizations, means that "git commit" on the kernel tree really only needs to lstat() the index entries once. That noticeably cuts down on the cached timings. Best time before: [torvalds@woody linux]$ time git commit > /dev/null real 0m0.399s user 0m0.232s sys 0m0.164s Best time after: [torvalds@woody linux]$ time git commit > /dev/null real 0m0.254s user 0m0.140s sys 0m0.112s so it's a noticeable improvement in addition to being a nice conceptual cleanup (it's really not that pretty that "run_diff_index()" dirties the index!) Doing an "strace -c" on it also shows that as it cuts the number of lstat() calls by two thirds, it goes from being lstat()-limited to being limited by getdents() (which is the readdir system call): Before: % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 60.69 0.000704 0 69230 31 lstat 23.62 0.000274 0 5522 getdents 8.36 0.000097 0 5508 2638 open 2.59 0.000030 0 2869 close 2.50 0.000029 0 274 write 1.47 0.000017 0 2844 fstat After: % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 45.17 0.000276 0 5522 getdents 26.51 0.000162 0 23112 31 lstat 19.80 0.000121 0 5503 2638 open 4.91 0.000030 0 2864 close 1.48 0.000020 0 274 write 1.34 0.000018 0 2844 fstat ... It passes the test-suite for me, but this is another of one of those really core functions, and certainly pretty subtle, so.. NOTE! The Linux lstat() system call is really quite cheap when everything is cached, so the fact that this is quite noticeable on Linux is likely to mean that it is *much* more noticeable on other operating systems. I bet you'll see a much bigger performance improvement from this on Windows in particular. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-08-10Move old index entry removal from "unpack_trees()" into the individual functionsLibravatar Linus Torvalds1-5/+6
This makes no changes to current code, but it allows the individual merge functions to decide what to do about the old entry. They might decide to update it in place, rather than force them to always delete and re-add it. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-10Start moving unpack-trees to "struct tree_desc"Libravatar Linus Torvalds1-1/+1
This doesn't actually change any real code, but it changes the interface to unpack_trees() to take an array of "struct tree_desc" entries, the same way the tree-walk.c functions do. The reason for this is that we would be much better off if we can do the tree-unpacking using the generic "traverse_trees()" functionality instead of having to the special "unpack" infrastructure. This really is a pretty minimal diff, just to change the calling convention. It passes all the tests, and looks sane. There were only two users of "unpack_trees()": builtin-read-tree and merge-recursive, and I tried to keep the changes minimal. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-04-04unpack-trees: get rid of *indpos parameter.Libravatar Junio C Hamano1-0/+1
This variable keeps track of which entry in the original index the traversal is looking at, and belongs to the unpack_trees_options structure along with other traversal status information. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-05read-tree: further loosen "working file will be lost" check.Libravatar Junio C Hamano1-0/+1
This follows up commit ed93b449 where we removed overcautious "working file will be lost" check. A new option "--exclude-per-directory=.gitignore" can be used to tell the "git-read-tree" command that the user does not mind losing contents in untracked files in the working tree, if they need to be overwritten by a merge (either a two-way "switch branches" merge, or a three-way merge). Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-30read-tree: move merge functions to the libraryLibravatar Johannes Schindelin1-0/+5
This will allow merge-recursive to use the read-tree functionality without exec()ing git-read-tree. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-07-30read-trees: refactor the unpack_trees() partLibravatar Johannes Schindelin1-0/+30
Basically, the options are passed by a struct unpack_trees_options now. That's all. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>