pack-objects: equal objects in size should delta against newer objects
[gitweb.git] / Documentation / git-read-tree.txt
index 4377362df2f8bd581ea351fb6cd4bc3f70a16e0e..019c8bef7af2868af150b4a13472b8ce26744ea3 100644 (file)
@@ -8,7 +8,7 @@ git-read-tree - Reads tree information into the index
 
 SYNOPSIS
 --------
-'git-read-tree' (<tree-ish> | [-m [-u|-i]] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
+'git-read-tree' (<tree-ish> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
 
 
 DESCRIPTION
@@ -50,6 +50,54 @@ OPTIONS
        trees that are not directly related to the current
        working tree status into a temporary index file.
 
+--aggressive::
+       Usually a three-way merge by `git-read-tree` resolves
+       the merge for really trivial cases and leaves other
+       cases unresolved in the index, so that Porcelains can
+       implement different merge policies.  This flag makes the
+       command to resolve a few more cases internally:
++
+* when one side removes a path and the other side leaves the path
+  unmodified.  The resolution is to remove that path.
+* when both sides remove a path.  The resolution is to remove that path.
+* when both sides adds a path identically.  The resolution
+  is to add that path.
+
+--prefix=<prefix>/::
+       Keep the current index contents, and read the contents
+       of named tree-ish under directory at `<prefix>`.  The
+       original index file cannot have anything at the path
+       `<prefix>` itself, and have nothing in `<prefix>/`
+       directory.  Note that the `<prefix>/` value must end
+       with a slash.
+
+--exclude-per-directory=<gitignore>::
+       When running the command with `-u` and `-m` options, the
+       merge result may need to overwrite paths that are not
+       tracked in the current branch.  The command usually
+       refuses to proceed with the merge to avoid losing such a
+       path.  However this safety valve sometimes gets in the
+       way.  For example, it often happens that the other
+       branch added a file that used to be a generated file in
+       your branch, and the safety valve triggers when you try
+       to switch to that branch after you ran `make` but before
+       running `make clean` to remove the generated file.  This
+       option tells the command to read per-directory exclude
+       file (usually '.gitignore') and allows such an untracked
+       but explicitly ignored file to be overwritten.
+
+--index-output=<file>::
+       Instead of writing the results out to `$GIT_INDEX_FILE`,
+       write the resulting index in the named file.  While the
+       command is operating, the original index file is locked
+       with the same mechanism as usual.  The file must allow
+       to be rename(2)ed into from a temporary file that is
+       created next to the usual index file; typically this
+       means it needs to be on the same filesystem as the index
+       file itself, and you need write permission to the
+       directories the index file and index output file are
+       located in.
+
 <tree-ish#>::
        The id of the tree object(s) to be read/merged.
 
@@ -167,26 +215,32 @@ $ git-read-tree -m <tree1> <tree2> <tree3>
 
 and you will end up with an index with all of the <tree1> entries in
 "stage1", all of the <tree2> entries in "stage2" and all of the
-<tree3> entries in "stage3".
+<tree3> entries in "stage3".  When performing a merge of another
+branch into the current branch, we use the common ancestor tree
+as <tree1>, the current branch head as <tree2>, and the other
+branch head as <tree3>.
 
 Furthermore, `git-read-tree` has special-case logic that says: if you see
 a file that matches in all respects in the following states, it
 "collapses" back to "stage0":
 
    - stage 2 and 3 are the same; take one or the other (it makes no
-     difference - the same work has been done on stage 2 and 3)
+     difference - the same work has been done on our branch in
+     stage 2 and their branch in stage 3)
 
    - stage 1 and stage 2 are the same and stage 3 is different; take
-     stage 3 (some work has been done on stage 3)
+     stage 3 (our branch in stage 2 did not do anything since the
+     ancestor in stage 1 while their branch in stage 3 worked on
+     it)
 
    - stage 1 and stage 3 are the same and stage 2 is different take
-     stage 2 (some work has been done on stage 2)
+     stage 2 (we did something while they did nothing)
 
 The `git-write-tree` command refuses to write a nonsensical tree, and it
 will complain about unmerged entries if it sees a single entry that is not
 stage 0.
 
-Ok, this all sounds like a collection of totally nonsensical rules,
+OK, this all sounds like a collection of totally nonsensical rules,
 but it's actually exactly what you want in order to do a fast
 merge. The different stages represent the "result tree" (stage 0, aka
 "merged"), the original tree (stage 1, aka "orig"), and the two trees
@@ -207,7 +261,7 @@ populated.  Here is an outline of how the algorithm works:
 
 - the index file saves and restores with all this information, so you
   can merge things incrementally, but as long as it has entries in
-  stages 1/2/3 (ie "unmerged entries") you can't write the result. So
+  stages 1/2/3 (i.e., "unmerged entries") you can't write the result. So
   now the merge algorithm ends up being really simple:
 
   * you walk the index in order, and ignore all entries of stage 0,
@@ -223,11 +277,9 @@ populated.  Here is an outline of how the algorithm works:
     trivial rules ..
 
 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.
+`git-merge-one-file` to do this last step.  The script updates
+the files in the working tree as it merges each path and at the
+end of a successful merge.
 
 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
@@ -238,8 +290,9 @@ 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:
+changes, and mixing your random changes in an unrelated merge
+commit.  To illustrate, suppose you start from what has been
+committed last to your repository:
 
 ----------------
 $ JC=`git-rev-parse --verify "HEAD^0"`
@@ -251,8 +304,8 @@ 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`
+$ git-fetch git://.... linus
+$ LT=`cat .git/FETCH_HEAD`
 ----------------
 
 Your work tree is still based on your HEAD ($JC), but you have
@@ -271,6 +324,20 @@ 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.
 
+However, if you have local changes in the working tree that
+would be overwritten by this merge,`git-read-tree` will refuse
+to run to prevent your changes from being lost.
+
+In other words, there is no need to worry about what exists only
+in the working tree.  When you have local changes in a part of
+the project that is not involved in the merge, your changes do
+not interfere with the merge, and are kept intact.  When they
+*do* interfere, the merge does not even start (`git-read-tree`
+complains loudly and fails without modifying anything).  In such
+a case, you can simply continue doing what you were in the
+middle of doing, and when your working tree is ready (i.e. you
+have finished your work-in-progress), attempt the merge again.
+
 
 See Also
 --------