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

Re: merge-recursive thinks symlink's child dirs are "real"

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Sep 16, 2019, 22:15 UTC
Message-ID
<20190916221501.GD6190@szeder.dev>
In-Reply-To
<20190916214707.190171-1-jonathantanmy@google.com>
On Mon, Sep 16, 2019 at 02:47:07PM -0700, Jonathan Tan wrote:
Show 35 quoted lines
> This was raised by a coworker at $DAYJOB. I run the following script:
> 
>   $GIT init test && cd test
>   ln -s . foo
>   mkdir bar && touch bar/file
>   $GIT add foo bar/file
>   $GIT commit -m "foo symlink"
>   
>   $GIT checkout -b branch1
>   $GIT commit --allow-empty -m "empty commit"
>   
>   $GIT checkout master
>   $GIT rm foo
>   mkdir foo
>   (cd foo; ln -s ../bar bar)
>   $GIT add foo/bar
>   $GIT commit -m "replace foo symlink with real foo dir and foo/bar symlink"
>   
>   $GIT checkout branch1
>   $GIT cherry-pick master
> 
> The cherry-pick must be manually resolved, when I would expect it to
> happen without needing user intervention.
> 
> You can see that at the point of the cherry-pick, in the working
> directory, ./foo is a symlink and ./foo/bar is a directory. I traced the
> code that ran during the cherry-pick to process_entry() in
> merge-recursive.c. When processing "foo/bar", control flow correctly
> reaches "Case B: Added in one", but the dir_in_way() invocation returns
> true, since lstat() indeed reveals that "foo/bar" is a directory. If I
> hardcode dir_in_way() to return false, then the cherry-pick happens
> without needing user intervention. I checked with "ls-tree -r" and the
> resulting tree is as I expect (foo is a real dir, foo/bar is a symlink).
> 
> Is this use case something that Git should be able to handle,

FWIW, Git used to handle this case, but it broke with edd2faf52e (merge-recursive: Consolidate process_entry() and process_df_entry(), 2011-08-11).

Cc-ing Elijah for insights...
Show 8 quoted lines
> and if
> yes, is the correct solution to teach dir_in_way() that dirs reachable
> from symlinks are not really in the way (presumably the implementation
> would climb directories until we reach the root or we reach a filesystem
> boundary, similar to what we do when we search for the .git directory)?
> Also, my proposed solution would work in the specific use case outlined
> in the script above, but can anyone think offhand of a case that it
> would make worse?
Previous: Jonathan TanNext: Elijah Newren
Message 2 of 13 in “merge-recursive thinks symlink's child dirs are "real"”
  1. Jonathan TanSep 16, 2019
  2. SZEDER GáborSep 16, 2019
  3. Elijah NewrenSep 17, 2019
  4. Jonathan NiederSep 17, 2019
  5. Elijah NewrenSep 17, 2019
  6. Elijah NewrenSep 17, 2019
  7. merge-recursive: symlink's descendants not in wayJonathan Tan, Sep 17, 2019
  8. Junio C HamanoSep 17, 2019
  9. Jonathan TanSep 17, 2019
  10. Junio C HamanoSep 17, 2019
  11. Jonathan TanSep 17, 2019
  12. SZEDER GáborSep 17, 2019
  13. Elijah NewrenSep 18, 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.