git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Junio C Hamano <gitster@pobox.com>
Date
Jun 22, 2009, 18:34 UTC
Message-ID
<7vd48wazhu.fsf@alter.siamese.dyndns.org>
In-Reply-To
<1245676001-14734-5-git-send-email-newren@gmail.com>
newren@gmail.com writes:
Show 9 quoted lines
> From: Elijah Newren <newren@gmail.com>
>
> 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.

Show 17 quoted lines
> @@ -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...
Show 19 quoted lines
> +		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?

Previous: newren@gmail.comNext: Elijah Newren
Message 8 of 11 in “A few fast export fixups -- round 2”
  1. newren@gmail.comJun 22, 2009
  2. fast-export: Omit tags that tag treesnewren@gmail.com, Jun 22, 2009
  3. Junio C HamanoJun 22, 2009
  4. fast-export: Make sure we show actual ref names instead of "(null)"newren@gmail.com, Jun 22, 2009
  5. Junio C HamanoJun 22, 2009
  6. fast-export: Do parent rewriting to avoid dropping relevant commitsnewren@gmail.com, Jun 22, 2009
  7. fast-export: Add a --tag-of-filtered-object option for newly dangling tagsnewren@gmail.com, Jun 22, 2009
  8. Junio C HamanoJun 22, 2009
  9. Elijah NewrenJun 26, 2009
  10. Add new fast-export testcasesnewren@gmail.com, Jun 22, 2009
  11. fast-export: Document the fact that git-rev-list arguments are acceptednewren@gmail.com, Jun 22, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.