1git-read-tree(1) 2================ 3v0.1, May 2005 4 5NAME 6---- 7git-read-tree - Reads tree information into the directory cache 8 9 10SYNOPSIS 11-------- 12'git-read-tree' (<tree-ish> | -m <tree-ish1> [<tree-ish2> <tree-ish3>])" 13 14DESCRIPTION 15----------- 16Reads the tree information given by <tree> into the directory cache, 17but does not actually *update* any of the files it "caches". (see: 18git-checkout-cache) 19 20Optionally, it can merge a tree into the cache or perform a 3-way 21merge. 22 23Trivial merges are done by "git-read-tree" itself. Only conflicting paths 24will be in unmerged state when "git-read-tree" returns. 25 26OPTIONS 27------- 28-m:: 29 Perform a merge, not just a read 30 31<tree-ish#>:: 32 The id of the tree object(s) to be read/merged. 33 34 35Merging 36------- 37If '-m' is specified, "git-read-tree" performs 2 kinds of merge, a single tree 38merge if only 1 tree is given or a 3-way merge if 3 trees are 39provided. 40 41Single Tree Merge 42~~~~~~~~~~~~~~~~~ 43If only 1 tree is specified, git-read-tree operates as if the user did not 44specify '-m', except that if the original cache has an entry for a 45given pathname; and the contents of the path matches with the tree 46being read, the stat info from the cache is used. (In other words, the 47cache's stat()s take precedence over the merged tree's) 48 49That means that if you do a "git-read-tree -m <newtree>" followed by a 50"git-checkout-cache -f -a", the "git-checkout-cache" only checks out 51the stuff that really changed. 52 53This is used to avoid unnecessary false hits when "git-diff-files" is 54run after git-read-tree. 55 56 57Two Tree Merge 58~~~~~~~~~~~~~~ 59 60Typically, this is invoked as "git-read-tree -m $H $M", where $H 61is the head commit of the current repository, and $M is the head 62of a foreign tree, which is simply ahead of $H (i.e. we are in a 63fast forward situation). 64 65When two trees are specified, the user is telling git-read-tree 66the following: 67 68 (1) The current index and work tree is derived from $H, but 69 the user may have local changes in them since $H; 70 71 (2) The user wants to fast-forward to $M. 72 73In this case, the "git-read-tree -m $H $M" command makes sure 74that no local change is lost as the result of this "merge". 75Here are the "carry forward" rules: 76 77 I (index) H M Result 78 ------------------------------------------------------- 79 0 nothing nothing nothing (does not happen) 80 1 nothing nothing exists use M 81 2 nothing exists nothing remove path from cache 82 3 nothing exists exists use M 83 84 clean I==H I==M 85 ------------------ 86 4 yes N/A N/A nothing nothing keep index 87 5 no N/A N/A nothing nothing keep index 88 89 6 yes N/A yes nothing exists keep index 90 7 no N/A yes nothing exists keep index 91 8 yes N/A no nothing exists fail 92 9 no N/A no nothing exists fail 93 94 10 yes yes N/A exists nothing remove path from cache 95 11 no yes N/A exists nothing fail 96 12 yes no N/A exists nothing fail 97 13 no no N/A exists nothing fail 98 99 clean (H=M) 100 ------ 101 14 yes exists exists keep index 102 15 no exists exists keep index 103 104 clean I==H I==M (H!=M) 105 ------------------ 106 16 yes no no exists exists fail 107 17 no no no exists exists fail 108 18 yes no yes exists exists keep index 109 19 no no yes exists exists keep index 110 20 yes yes no exists exists use M 111 21 no yes no exists exists fail 112 113In all "keep index" cases, the cache entry stays as in the 114original index file. If the entry were not up to date, 115git-read-tree keeps the copy in the work tree intact when 116operating under the -u flag. 117 118When this form of git-read-tree returns successfully, you can 119see what "local changes" you made are carried forward by running 120"git-diff-cache --cached $M". Note that this does not 121necessarily match "git-diff-cache --cached $H" would have 122produced before such a two tree merge. This is because of cases 12318 and 19 --- if you already had the changes in $M (e.g. maybe 124you picked it up via e-mail in a patch form), "git-diff-cache 125--cached $H" would have told you about the change before this 126merge, but it would not show in "git-diff-cache --cached $M" 127output after two-tree merge. 128 129 1303-Way Merge 131~~~~~~~~~~~ 132Each "index" entry has two bits worth of "stage" state. stage 0 is the 133normal one, and is the only one you'd see in any kind of normal use. 134 135However, when you do "git-read-tree" with three trees, the "stage" 136starts out at 1. 137 138This means that you can do 139 140 git-read-tree -m <tree1> <tree2> <tree3> 141 142and you will end up with an index with all of the <tree1> entries in 143"stage1", all of the <tree2> entries in "stage2" and all of the 144<tree3> entries in "stage3". 145 146Furthermore, "git-read-tree" has special-case logic that says: if you see 147a file that matches in all respects in the following states, it 148"collapses" back to "stage0": 149 150 - stage 2 and 3 are the same; take one or the other (it makes no 151 difference - the same work has been done on stage 2 and 3) 152 153 - stage 1 and stage 2 are the same and stage 3 is different; take 154 stage 3 (some work has been done on stage 3) 155 156 - stage 1 and stage 3 are the same and stage 2 is different take 157 stage 2 (some work has been done on stage 2) 158 159The "git-write-tree" command refuses to write a nonsensical tree, and it 160will complain about unmerged entries if it sees a single entry that is not 161stage 0. 162 163Ok, this all sounds like a collection of totally nonsensical rules, 164but it's actually exactly what you want in order to do a fast 165merge. The different stages represent the "result tree" (stage 0, aka 166"merged"), the original tree (stage 1, aka "orig"), and the two trees 167you are trying to merge (stage 2 and 3 respectively). 168 169In fact, the way "git-read-tree" works, it's entirely agnostic about how 170you assign the stages, and you could really assign them any which way, 171and the above is just a suggested way to do it (except since 172"git-write-tree" refuses to write anything but stage0 entries, it makes 173sense to always consider stage 0 to be the "full merge" state). 174 175So what happens? Try it out. Select the original tree, and two trees 176to merge, and look how it works: 177 178- if a file exists in identical format in all three trees, it will 179 automatically collapse to "merged" state by the new git-read-tree. 180 181- a file that has _any_ difference what-so-ever in the three trees 182 will stay as separate entries in the index. It's up to "script 183 policy" to determine how to remove the non-0 stages, and insert a 184 merged version. But since the index is always sorted, they're easy 185 to find: they'll be clustered together. 186 187- the index file saves and restores with all this information, so you 188 can merge things incrementally, but as long as it has entries in 189 stages 1/2/3 (ie "unmerged entries") you can't write the result. So 190 now the merge algorithm ends up being really simple: 191 192 * you walk the index in order, and ignore all entries of stage 0, 193 since they've already been done. 194 195 * if you find a "stage1", but no matching "stage2" or "stage3", you 196 know it's been removed from both trees (it only existed in the 197 original tree), and you remove that entry. 198 199 * if you find a matching "stage2" and "stage3" tree, you remove one 200 of them, and turn the other into a "stage0" entry. Remove any 201 matching "stage1" entry if it exists too. .. all the normal 202 trivial rules .. 203 204Incidentally - it also means that you don't even have to have a 205separate subdirectory for this. All the information literally is in 206the index file, which is a temporary thing anyway. There is no need to 207worry about what is in the working directory, since it is never shown 208and never used. 209 210See Also 211-------- 212link:git-write-tree.html[git-write-tree]; link:git-ls-files.html[git-ls-files] 213 214 215Author 216------ 217Written by Linus Torvalds <torvalds@osdl.org> 218 219Documentation 220-------------- 221Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>. 222 223GIT 224--- 225Part of the link:git.html[git] suite 226