Skip to content
  • Junio C Hamano's avatar
    apply: do not touch a file beyond a symbolic link · e0d201b6
    Junio C Hamano authored
    
    
    Because Git tracks symbolic links as symbolic links, a path that
    has a symbolic link in its leading part (e.g. path/to/dir/file,
    where path/to/dir is a symbolic link to somewhere else, be it
    inside or outside the working tree) can never appear in a patch
    that validly applies, unless the same patch first removes the
    symbolic link to allow a directory to be created there.
    
    Detect and reject such a patch.
    
    Things to note:
    
     - Unfortunately, we cannot reuse the has_symlink_leading_path()
       from dir.c, as that is only about the working tree, but "git
       apply" can be told to apply the patch only to the index or to
       both the index and to the working tree.
    
     - We cannot directly use has_symlink_leading_path() even when we
       are applying only to the working tree, as an early patch of a
       valid input may remove a symbolic link path/to/dir and then a
       later patch of the input may create a path path/to/dir/file, but
       "git apply" first checks the input without touching either the
       index or the working tree.  The leading symbolic link check must
       be done on the interim result we compute in-core (i.e. after the
       first patch, there is no path/to/dir symbolic link and it is
       perfectly valid to create path/to/dir/file).
    
       Similarly, when an input creates a symbolic link path/to/dir and
       then creates a file path/to/dir/file, we need to flag it as an
       error without actually creating path/to/dir symbolic link in the
       filesystem.
    
    Instead, for any patch in the input that leaves a path (i.e. a non
    deletion) in the result, we check all leading paths against the
    resulting tree that the patch would create by inspecting all the
    patches in the input and then the target of patch application
    (either the index or the working tree).
    
    This way, we catch a mischief or a mistake to add a symbolic link
    path/to/dir and a file path/to/dir/file at the same time, while
    allowing a valid patch that removes a symbolic link path/to/dir and
    then adds a file path/to/dir/file.
    
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    e0d201b6