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

Re: [PATCH v2] merge-recursive: symlink's descendants not in way

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 20, 2019, 17:15 UTC
Message-ID
<xmqqzhiyvqhe.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20190918202738.57273-1-jonathantanmy@google.com>
Jonathan Tan <jonathantanmy@google.com> writes:
Show 15 quoted lines
> When the working tree has:
>  - bar (directory)
>  - bar/file (file)
>  - foo (symlink to .)
>
> (note that lstat() for "foo/bar" would tell us that it is a directory)
>
> and the user merges a commit that deletes the foo symlink and instead
> contains:
>  - bar (directory, as above)
>  - bar/file (file, as above)
>  - foo (directory)
>  - foo/bar (file)
>
> the merge should happen without requiring user intervention.

Thanks. That clears my previous confusion. It is clear that the desired outcome is that bar/file will be merged with itself, foo itself will resolve to "deleted", and foo/bar will be created.

> However, this does not happen.

OK. We notice that we need to newly create foo/bar but we incorrectly find that there is "foo/bar" already because of the careless use of bare lstat(2) makes "bar" visible as if it were also "foo/bar". I wonder if the current code would be confused the same way if the side branch added "foo/bar/file", or the confusion would be even worse---it is not dir_in_way() and a different codepath would be affected, no?

Show 11 quoted lines
> diff --git a/merge-recursive.c b/merge-recursive.c
> index 6b812d67e3..22a12cfeba 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c
> @@ -764,7 +764,8 @@ static int dir_in_way(struct index_state *istate, const char *path,
>  
>  	strbuf_release(&dirpath);
>  	return check_working_copy && !lstat(path, &st) && S_ISDIR(st.st_mode) &&
> -		!(empty_ok && is_empty_dir(path));
> +		!(empty_ok && is_empty_dir(path)) &&
> +		!has_symlink_leading_path(path, strlen(path));

As the new call is fairly heavyweight compared to everything else we are doing, I think it is very sensible to have this at the end, like this patch does.

Nicely done.  Thanks, will queue.
Previous: Elijah NewrenNext: Jonathan Tan
Message 3 of 6 in “merge-recursive: symlink's descendants not in way”
  1. merge-recursive: symlink's descendants not in wayJonathan Tan, Sep 18, 2019
  2. Elijah NewrenSep 18, 2019
  3. Junio C HamanoSep 20, 2019
  4. Jonathan TanSep 20, 2019
  5. Junio C HamanoSep 20, 2019
  6. Jonathan TanSep 20, 2019

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.