Re: [PATCH v2] fast-export: Add a --tag-of-filtered-object option for newly dangling tags

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

 



newren@xxxxxxxxx writes:

> From: Elijah Newren <newren@xxxxxxxxx>
>
> When providing a list of paths to limit what is exported, the object that
> a tag points to can be filtered out entirely.  This new switch allows
> the user to specify what should happen to the tag in such a case.  The
> default action, 'abort' will exit with an error message.  With 'drop', the
> tag will simply be omitted from the output.  With 'rewrite', if the object
> tagged was a commit, the tag will be modified to tag an ancestor of the
> removed commit.

I had to wonder what "an ancestor" means in the above sentence.

 - It cannot be the "direct ancestor", as such a commit could also have
   been filtered out.  it will probably find an ancestor of the tagged
   commit that is not TREESAME, i.e. changes one of the specified paths.
   is that what the code tries to do?

 - Assuming that the answer is true, finding an ancestor means go back in
   the ancestry graph.  How should a merged history be handled?

   - If two branches merged, only one among which touched the paths, then
     the simplication would have linearized the history already, so it is
     a non issue;

   - If a merge really had changes from both branches, that merge would
     remain in the output, and the tag will be moved there.

   - Did I miss any other case?

If I have to wonder, many other people who read the "git log" output later
will get puzzled, too.  Please clarify.

> @@ -333,10 +349,42 @@ static void handle_tag(const char *name, struct tag *tag)
>  			}
>  	}
>  
> +	/* handle tag->tagged having been filtered out due to paths specified */
> +	struct object * tagged = tag->tagged;
> +	int tagged_mark = get_object_mark(tagged);
> +	if (!tagged_mark) {
> +		switch(tag_of_filtered_mode) {
> +		case ABORT:
> +			die ("Tag %s tags unexported commit; use "
> +			     "--tag-of-filtered-object=<mode> to handle it.",
> +			     sha1_to_hex(tag->object.sha1));
> +		case DROP:
> +			/* Ignore this tag altogether */
> +			return;
> +				/* fallthru */

Doesn't fall through...

> +		case REWRITE:
> +			if (tagged->type != OBJ_COMMIT) {
> +				die ("Tag %s tags unexported commit; use "
> +				     "--tag-of-filtered-object=<mode> to handle it.",
> +				     sha1_to_hex(tag->object.sha1));
> +			}
> +			commit = (struct commit *)tagged;
> +			switch (rewrite_one_commit(revs, &commit)) {
> +			case rewrite_one_ok:
> +				tagged_mark = get_object_mark(&commit->object);
> +				break;
> +			case rewrite_one_noparents:
> +			case rewrite_one_error:
> +				die ("Can't find replacement commit for tag %s\n",
> +				     sha1_to_hex(tag->object.sha1));
> +			}
> +		}
> +	}
> +

This makes me a bit worried.  The rewrite_one() function is never designed
to be called from outside while the main traversal has still work to do,
nor called more than once on the same commit object.  I do not know what
would happen if somebody did so.

Granted, all of this processing happens after the revision traversing
machinery is done with all the commits, and rewriting commits further here
will not have a chance of breaking the subtleties in get_revision() and
everything called from it that already has happened in the main traversal,
but still I would prefer not exposing this function out of revision.c to
avoid mistakes if possible.

Also, are you absolutely sure that your revs is always limited at this
point?  Otherwise, the parents of this commit are queued in rev->list,
expecting somebody else to later pick them up and further process, but
there is nobody who does that in your codepath as far as I can see.  What
will happen to these parent commits?
--
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]