X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;ds=sidebyside;f=Documentation%2Fgit-read-tree.txt;h=5653baccaffe888bc5a238e0fef8212045ab187d;hb=8b73edf498adf2895af7ff9c750283cf9325a632;hp=6440c4b41942e3af2270f46c7d0186feb689da13;hpb=c859600954df4c292ec7c81d7f2f9d0a62b5975b;p=git.git diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 6440c4b4..5653bacc 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -9,16 +9,19 @@ git-read-tree - Reads tree information into the directory cache SYNOPSIS -------- -'git-read-tree' ( | -m [ ])" +'git-read-tree' ( | [-m [-u|-i]] [ []]) + DESCRIPTION ----------- -Reads the tree information given by into the directory cache, +Reads the tree information given by into the directory cache, but does not actually *update* any of the files it "caches". (see: -git-checkout-cache) +git-checkout-index) -Optionally, it can merge a tree into the cache or perform a 3-way -merge. +Optionally, it can merge a tree into the cache, perform a +fast-forward (i.e. 2-way) merge, or a 3-way merge, with the -m +flag. When used with -m, the -u flag causes it to also update +the files in the work tree with the result of the merge. Trivial merges are done by "git-read-tree" itself. Only conflicting paths will be in unmerged state when "git-read-tree" returns. @@ -26,7 +29,21 @@ will be in unmerged state when "git-read-tree" returns. OPTIONS ------- -m:: - Perform a merge, not just a read + Perform a merge, not just a read. + +-u:: + After a successful merge, update the files in the work + tree with the result of the merge. + +-i:: + Usually a merge requires the index file as well as the + files in the working tree are up to date with the + current head commit, in order not to lose local + changes. This flag disables the check with the working + tree and is meant to be used when creating a merge of + trees that are not directly related to the current + working tree status into a temporary index file. + :: The id of the tree object(s) to be read/merged. @@ -34,20 +51,22 @@ OPTIONS Merging ------- -If '-m' is specified, "git-read-tree" performs 2 kinds of merge, a single tree -merge if only 1 tree is given or a 3-way merge if 3 trees are +If '-m' is specified, "git-read-tree" can perform 3 kinds of +merge, a single tree merge if only 1 tree is given, a +fast-forward merge with 2 trees, or a 3-way merge if 3 trees are provided. + Single Tree Merge ~~~~~~~~~~~~~~~~~ If only 1 tree is specified, git-read-tree operates as if the user did not specify '-m', except that if the original cache has an entry for a -given pathname; and the contents of the path matches with the tree +given pathname, and the contents of the path matches with the tree being read, the stat info from the cache is used. (In other words, the -cache's stat()s take precedence over the merged tree's) +cache's stat()s take precedence over the merged tree's). That means that if you do a "git-read-tree -m " followed by a -"git-checkout-cache -f -a", the "git-checkout-cache" only checks out +"git-checkout-index -f -u -a", the "git-checkout-index" only checks out the stuff that really changed. This is used to avoid unnecessary false hits when "git-diff-files" is @@ -65,10 +84,10 @@ fast forward situation). When two trees are specified, the user is telling git-read-tree the following: - (1) The current index and work tree is derived from $H, but + 1. The current index and work tree is derived from $H, but the user may have local changes in them since $H; - (2) The user wants to fast-forward to $M. + 2. The user wants to fast-forward to $M. In this case, the "git-read-tree -m $H $M" command makes sure that no local change is lost as the result of this "merge". @@ -117,13 +136,13 @@ operating under the -u flag. When this form of git-read-tree returns successfully, you can see what "local changes" you made are carried forward by running -"git-diff-cache --cached $M". Note that this does not -necessarily match "git-diff-cache --cached $H" would have +"git-diff-index --cached $M". Note that this does not +necessarily match "git-diff-index --cached $H" would have produced before such a two tree merge. This is because of cases 18 and 19 --- if you already had the changes in $M (e.g. maybe -you picked it up via e-mail in a patch form), "git-diff-cache +you picked it up via e-mail in a patch form), "git-diff-index --cached $H" would have told you about the change before this -merge, but it would not show in "git-diff-cache --cached $M" +merge, but it would not show in "git-diff-index --cached $M" output after two-tree merge. @@ -166,23 +185,18 @@ merge. The different stages represent the "result tree" (stage 0, aka "merged"), the original tree (stage 1, aka "orig"), and the two trees you are trying to merge (stage 2 and 3 respectively). -In fact, the way "git-read-tree" works, it's entirely agnostic about how -you assign the stages, and you could really assign them any which way, -and the above is just a suggested way to do it (except since -"git-write-tree" refuses to write anything but stage0 entries, it makes -sense to always consider stage 0 to be the "full merge" state). - -So what happens? Try it out. Select the original tree, and two trees -to merge, and look how it works: +The order of stages 1, 2 and 3 (hence the order of three + command line arguments) are significant when you +start a 3-way merge with an index file that is already +populated. Here is an outline of how the algorithm works: - if a file exists in identical format in all three trees, it will - automatically collapse to "merged" state by the new git-read-tree. + automatically collapse to "merged" state by git-read-tree. - a file that has _any_ difference what-so-ever in the three trees - will stay as separate entries in the index. It's up to "script + will stay as separate entries in the index. It's up to "porcelain policy" to determine how to remove the non-0 stages, and insert a - merged version. But since the index is always sorted, they're easy - to find: they'll be clustered together. + merged version. - the index file saves and restores with all this information, so you can merge things incrementally, but as long as it has entries in @@ -201,15 +215,53 @@ to merge, and look how it works: matching "stage1" entry if it exists too. .. all the normal trivial rules .. -Incidentally - it also means that you don't even have to have a -separate subdirectory for this. All the information literally is in -the index file, which is a temporary thing anyway. There is no need to -worry about what is in the working directory, since it is never shown -and never used. +You would normally use "git-merge-index" with supplied +"git-merge-one-file" to do this last step. The script +does not touch the files in the work tree, and the entire merge +happens in the index file. In other words, there is no need to +worry about what is in the working directory, since it is never +shown and never used. + +When you start a 3-way merge with an index file that is already +populated, it is assumed that it represents the state of the +files in your work tree, and you can even have files with +changes unrecorded in the index file. It is further assumed +that this state is "derived" from the stage 2 tree. The 3-way +merge refuses to run if it finds an entry in the original index +file that does not match stage 2. + +This is done to prevent you from losing your work-in-progress +changes. To illustrate, suppose you start from what has been +commited last to your repository: + + $ JC=`cat .git/HEAD` + $ git-checkout-index -f -u -a $JC + +You do random edits, without running git-update-index. And then +you notice that the tip of your "upstream" tree has advanced +since you pulled from him: + + $ git-fetch rsync://.... linus + $ LT=`cat .git/MERGE_HEAD` + +Your work tree is still based on your HEAD ($JC), but you have +some edits since. Three-way merge makes sure that you have not +added or modified cache entries since $JC, and if you haven't, +then does the right thing. So with the following sequence: + + $ git-read-tree -m -u `git-merge-base $JC $LT` $JC $LT + $ git-merge-index git-merge-one-file -a + $ echo "Merge with Linus" | \ + git-commit-tree `git-write-tree` -p $JC -p $LT + +what you would commit is a pure merge between $JC and LT without +your work-in-progress changes, and your work tree would be +updated to the result of the merge. + See Also -------- -link:git-write-tree.html[git-write-tree]; link:git-ls-files.html[git-ls-files] +gitlink:git-write-tree[1]; gitlink:git-ls-files[1] Author @@ -222,5 +274,5 @@ Documentation by David Greaves, Junio C Hamano and the git-list