Re: [PATCH] Documentation/git-filter-branch.txt: Fix description of --commit-filter
On May 30, 2008, at 4:41 PM, Junio C Hamano wrote:
Show 62 quoted lines
> Kevin Ballard <kevin@sb.org> writes:
>
>>> But I am also confused by the new description:
>>>
>>> In that history, we will make sure that rewritten D (original
>>> commit being C) have A as parent. IOW, we will have
>>>
>>> --A'--C' D'
>>> /
>>> A
>>>
>>> which is not what happens. What it does is that the commits in the
>>> output
>>> from the filter (i.e. A) are first mapped to the corresponding
>>> commits in
>>> the rewritten history (i.e. A'), and they will be used as the
>>> parents of
>>> the rewritten commit, to form this history:
>>>
>>> --A'--C'
>>>
>>> isn't it?
>>
>> So basically, you think it's missing the fact that the emitted id is
>> mapped to rewritten commits? From reading the git-filter-branch code,
>> I don't think that's correct. When each commit is created, its
>> original parents get mapped to new values, but the results of the
>> commit-filter are dumped straight into the map.
>
> Ah, I misread this part of the code:
>
> parentstr=
> for parent in $parents; do
> for reparent in $(map "$parent"); do
> parentstr="$parentstr -p $reparent"
> done
> done
> if [ "$filter_parent" ]; then
> parentstr="$(echo "$parentstr" | eval "$filter_parent")" ||
> die "parent filter failed: $filter_parent"
> fi
>
> You get the commit object names from the new history, and you are
> supposed
> to give back names from the new history from the filter.
>
> So "the rewritten commit will have the output from parent-filter as
> its
> parents" is what happens, right?
>
> IOW, in the history in the previous message, when rewriting C (to
> create
> C'), the filter will get A' and B' (i.e. from the new history), and
> can
> choose to return A', and that is recorded when creating C'. "the
> rewritten children of the commit" in your:
>
> +commit ids; in that case, the rewritten children of the original
> +commit will have all of them as parents.
>
> sounded as if you are talking about D' not C', and that was what I was
> confused about.
I was talking about D'. You've switched from talking about the commit- filter to talking about the parent-filter.
If a parent-filter is specified, it will be run on the parents that are handed to the commit-filter (before the commit-filter is invoked), but that's not relevant right now.
When using the commit-filter to rewrite C (to create C'), when A is returned, that's dumped into the map so in the future, $(map C) will return A. This means that when D is processed, it's handed A as the parent.
Show 24 quoted lines
>> To give an example, let's examine your tree. A will be processed
>> first, and A' gets put into the map for A. B gets processed next (or
>> maybe before A, but that's irrelevant) and B' gets put into the map
>> for B. C gets processed, and it emits A, so A goes into the map for
>> C.
>
> Hmm? I meant C is rewritten to become C' but when it does so filter
> can
> remove B from its parent set (iow, the filter is told that unless it
> intervenes C' will have A' and B' as its parents, but the filter can
> choose to return only A'). So I do not quite get "it emits A"
> part. Do
> you mean "the filter outputs A'"? Also do you mean by "map" the
> mapping
> from <A, B, C> to <A', B', C'> commit namespace? If so, even when the
> filter "emits A'", I do not think it "goes into the map for C".
> When the
> filter "emits A'", it is used as _the_ single parent to create C',
> and it
> is C' that "goes into the map for C". Am I still confused?
>
> Now, I admit that I did not look at the implementation of the "map"
> in the
> code quoted above. Perhaps that thing is busted, I dunno.
You're still talking about the parent-filter here. I think you're quite confused.
Given this history to start:
B
\
A---C---DAlso given that we're specifying a commit-filter but *not* a parent- filter.
When that commit-filter is given A and B, it returns A' and B' without doing any changes (A' and B' in this case come from git-commit-tree). When given C, the commit-filter returns A. When given D, it returns D' again with no changes.
The resulting history will look like this:
B'
A' A---D'
As you can see, there is no C' commit (as the commit-filter simply returned A), and the A' and B' commits are left dangling.
Here is a shell script which will generate this exact repo:
http://pastie.textmate.org/206265
If you inspect the result, you'll see HEAD points to D' with a parent of A, and that there are two dangling commits A' and B'.
What I was talking about with the map can be demonstrated here. If you edit the commit-filter to print out some debug info while writing D', you can see that $(map $(git rev-parse C)) will output $(git rev-parse A).
-Kevin
--
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com