Re: [PATCH] Documentation/git-filter-branch.txt: Fix description of --commit-filter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On May 30, 2008, at 4:41 PM, Junio C Hamano wrote:

Kevin Ballard <kevin@xxxxxx> 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.

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---D

Also 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@xxxxxx
http://www.tildesoft.com


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux