Merge branch 'tr/rev-list-docs' into tr/filter-branch

This prepares the necessary parts to merge filter-branch
fix based on simplify-merges to master.
This commit is contained in:
Junio C Hamano 2008-08-31 10:41:01 -07:00
commit e910ce30e4
4 changed files with 192 additions and 26 deletions

View file

@ -307,9 +307,18 @@ backslash, and zero or more occurrences of `sub` followed by
There are a few built-in patterns to make this easier, and `tex`
is one of them, so you do not have to write the above in your
configuration file (you still need to enable this with the
attribute mechanism, via `.gitattributes`). Another built-in
pattern is defined for `java` that defines a pattern suitable
for program text in Java language.
attribute mechanism, via `.gitattributes`). The following built in
patterns are available:
- `bibtex` suitable for files with BibTeX coded references.
- `java` suitable for source code in the Java lanugage.
- `pascal` suitable for source code in the Pascal/Delphi language.
- `ruby` suitable for source code in the Ruby language.
- `tex` suitable for source code for LaTeX documents.
Performing a three-way merge

View file

@ -43,11 +43,13 @@ endif::git-rev-list[]
--parents::
Print the parents of the commit.
Print the parents of the commit. Also enables parent
rewriting, see 'History Simplification' below.
--children::
Print the children of the commit.
Print the children of the commit. Also enables parent
rewriting, see 'History Simplification' below.
ifdef::git-rev-list[]
--timestamp::
@ -191,20 +193,6 @@ endif::git-rev-list[]
Stop when a given path disappears from the tree.
--full-history::
Show also parts of history irrelevant to current state of given
paths. This turns off history simplification, which removed merges
which didn't change anything at all at some child. It will still actually
simplify away merges that didn't change anything at all into either
child.
--simplify-merges::
Simplify away commits that did not change the given paths, similar
to `--full-history`, and further remove merges none of whose
parent history changes the given paths.
--no-merges::
Do not print commits with more than one parent.
@ -286,18 +274,186 @@ See also linkgit:git-reflog[1].
Output uninteresting commits at the boundary, which are usually
not shown.
--
History Simplification
~~~~~~~~~~~~~~~~~~~~~~
When optional paths are given, 'git-rev-list' simplifies commits with
various strategies, according to the options you have selected.
Suppose you specified `foo` as the <paths>. We shall call commits
that modify `foo` !TREESAME, and the rest TREESAME. (In a diff
filtered for `foo`, they look different and equal, respectively.)
In the following, we will always refer to the same example history to
illustrate the differences between simplification settings. We assume
that you are filtering for a file `foo` in this commit graph:
-----------------------------------------------------------------------
.-A---M---N---O---P
/ / / / /
I B C D E
\ / / / /
`-------------'
-----------------------------------------------------------------------
The horizontal line of history A--P is taken to be the first parent of
each merge. The commits are:
* `I` is the initial commit, in which `foo` exists with contents
"asdf", and a file `quux` exists with contents "quux". Initial
commits are compared to an empty tree, so `I` is !TREESAME.
* In `A`, `foo` contains just "foo".
* `B` contains the same change as `A`. Its merge `M` is trivial and
hence TREESAME to all parents.
* `C` does not change `foo`, but its merge `N` changes it to "foobar",
so it is not TREESAME to any parent.
* `D` sets `foo` to "baz". Its merge `O` combines the strings from
`N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent.
* `E` changes `quux` to "xyzzy", and its merge `P` combines the
strings to "quux xyzzy". Despite appearing interesting, `P` is
TREESAME to all parents.
'rev-list' walks backwards through history, including or excluding
commits based on whether '\--full-history' and/or parent rewriting
(via '\--parents' or '\--children') are used. The following settings
are available.
Default mode::
Commits are included if they are not TREESAME to any parent
(though this can be changed, see '\--sparse' below). If the
commit was a merge, and it was TREESAME to one parent, follow
only that parent. (Even if there are several TREESAME
parents, follow only one of them.) Otherwise, follow all
parents.
+
This results in:
+
-----------------------------------------------------------------------
.-A---N---O
/ /
I---------D
-----------------------------------------------------------------------
+
Note how the rule to only follow the TREESAME parent, if one is
available, removed `B` from consideration entirely. `C` was
considered via `N`, but is TREESAME. Root commits are compared to an
empty tree, so `I` is !TREESAME.
+
Parent/child relations are only visible with --parents, but that does
not affect the commits selected in default mode, so we have shown the
parent lines.
--full-history without parent rewriting::
This mode differs from the default in one point: always follow
all parents of a merge, even if it is TREESAME to one of them.
Even if more than one side of the merge has commits that are
included, this does not imply that the merge itself is! In
the example, we get
+
-----------------------------------------------------------------------
I A B N D O
-----------------------------------------------------------------------
+
`P` and `M` were excluded because they are TREESAME to a parent. `E`,
`C` and `B` were all walked, but only `B` was !TREESAME, so the others
do not appear.
+
Note that without parent rewriting, it is not really possible to talk
about the parent/child relationships between the commits, so we show
them disconnected.
--full-history with parent rewriting::
Ordinary commits are only included if they are !TREESAME
(though this can be changed, see '\--sparse' below).
+
Merges are always included. However, their parent list is rewritten:
Along each parent, prune away commits that are not included
themselves. This results in
+
-----------------------------------------------------------------------
.-A---M---N---O---P
/ / / / /
I B / D /
\ / / / /
`-------------'
-----------------------------------------------------------------------
+
Compare to '\--full-history' without rewriting above. Note that `E`
was pruned away because it is TREESAME, but the parent list of P was
rewritten to contain `E`'s parent `I`. The same happened for `C` and
`N`. Note also that `P` was included despite being TREESAME.
In addition to the above settings, you can change whether TREESAME
affects inclusion:
--dense::
Commits that are walked are included if they are not TREESAME
to any parent.
--sparse::
When optional paths are given, the default behaviour ('--dense') is to
only output commits that changes at least one of them, and also ignore
merges that do not touch the given paths.
All commits that are walked are included.
+
Note that without '\--full-history', this still simplifies merges: if
one of the parents is TREESAME, we follow only that one, so the other
sides of the merge are never walked.
Use the '--sparse' flag to makes the command output all eligible commits
(still subject to count and age limitation), but apply merge
simplification nevertheless.
Finally, there is a fourth simplification mode available:
--simplify-merges::
First, build a history graph in the same way that
'\--full-history' with parent rewriting does (see above).
+
Then simplify each commit `C` to its replacement `C'` in the final
history according to the following rules:
+
--
* Set `C'` to `C`.
+
* Replace each parent `P` of `C'` with its simplification `P'`. In
the process, drop parents that are ancestors of other parents, and
remove duplicates.
+
* If after this parent rewriting, `C'` is a root or merge commit (has
zero or >1 parents), a boundary commit, or !TREESAME, it remains.
Otherwise, it is replaced with its only parent.
--
+
The effect of this is best shown by way of comparing to
'\--full-history' with parent rewriting. The example turns into:
+
-----------------------------------------------------------------------
.-A---M---N---O
/ / /
I B D
\ / /
`---------'
-----------------------------------------------------------------------
+
Note the major differences in `N` and `P` over '\--full-history':
+
--
* `N`'s parent list had `I` removed, because it is an ancestor of the
other parent `M`. Still, `N` remained because it is !TREESAME.
+
* `P`'s parent list similarly had `I` removed. `P` was then
removed completely, because it had one parent and is TREESAME.
--
ifdef::git-rev-list[]
Bisection Helpers
~~~~~~~~~~~~~~~~~
--bisect::
Limit output to the one commit object which is roughly halfway between
@ -347,7 +503,6 @@ after all the sorted commit objects, there will be the same text as if
`--bisect-vars` had been used alone.
endif::git-rev-list[]
--
Commit Ordering
~~~~~~~~~~~~~~~

View file

@ -794,6 +794,7 @@ static void child_handler(int signo)
}
break;
}
signal(SIGCHLD, child_handler);
}
static int set_reuse_addr(int sockfd)

1
diff.c
View file

@ -1387,6 +1387,7 @@ static struct builtin_funcname_pattern {
"\\|"
"^\\(.*=[ \t]*\\(class\\|record\\).*\\)$"
},
{ "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" },
{ "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" },
{ "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" },
};