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

Re: [WIP PATCH] fast-export: emit deletions first

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 6, 2026, 17:15 UTC
Message-ID
<xmqqo6jwau34.fsf@gitster.g>
In-Reply-To
<20260406063607.15353-1-ray@ameretat.dev>
"Raymond E. Pasco" <ray@ameretat.dev> writes:
Show 18 quoted lines
> fast-export chooses its output order by pathname, sorting longer
> paths earlier. However, this causes faulty output when the deleted
> path is a prefix of the added one. For example, deleting a file 'a' and
> creating a file 'a/b' emits:
>
> from :prev_label
> M 100644 :blob_label a/b
> D a
>
> Fix this by sorting deletions to come before other types of change.
>
> Signed-off-by: Raymond E. Pasco <ray@ameretat.dev>
> ---
>
> This is a quick and dirty fix for the bug. However, I do want to spend a
> little more time on it - it may be that we only want to reverse the sort
> when the deletion is specifically the prefix of some addition, and I
> want to fence this off with new tests.

I recall doing something like this in "git checkout" and also "git am" to ensure that a thing deep in the hierarchy will not be affected by a D/F conflict at a shallower level, so I do not have objection to this kind of change in principle. I do not know if depth_first() is the right place to make this decision or if the function should keep its name if it turns out to be the right place.

In any case, it is a bit surprising that fast-export survived this long without having encountering the problem you are solving. I wonder if fast-import handles such an output with some smart to avoid the issue?

Thanks.
Show 19 quoted lines
>  builtin/fast-export.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index b90da5e616..82d73b2f43 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -354,6 +354,12 @@ static int depth_first(const void *a_, const void *b_)
>  	int len_a, len_b, len;
>  	int cmp;
>  
> +	/* emit deletions first */
> +	int a_deletes = (a->status == DIFF_STATUS_DELETED);
> +	int b_deletes = (b->status == DIFF_STATUS_DELETED);
> +	if (a_deletes != b_deletes)
> +		return b_deletes - a_deletes;
> +
>  	name_a = a->one ? a->one->path : a->two->path;
>  	name_b = b->one ? b->one->path : b->two->path;
Previous: Raymond E. PascoNext: Jeff King
Message 2 of 8 in “fast-export: emit deletions first”
  1. fast-export: emit deletions firstRaymond E. Pasco, Apr 6, 2026
  2. Junio C HamanoApr 6, 2026
  3. Jeff KingApr 6, 2026
  4. Elijah NewrenApr 6, 2026
  5. Jeff KingApr 7, 2026
  6. Raymond E. PascoApr 7, 2026
  7. Raymond E. PascoApr 7, 2026
  8. Jeff KingApr 7, 2026

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.