Skip to content
  • Elijah Newren's avatar
    am: avoid directory rename detection when calling recursive merge machinery · 6aba117d
    Elijah Newren authored and Junio C Hamano's avatar Junio C Hamano committed
    
    
    Let's say you have the following three trees, where Base is from one commit
    behind either master or branch:
    
       Base  : bar_v1, foo/{file1, file2, file3}
       branch: bar_v2, foo/{file1, file2},       goo/file3
       master: bar_v3, foo/{file1, file2, file3}
    
    Using git-am (or am-based rebase) to apply the changes from branch onto
    master results in the following tree:
    
       Result: bar_merged, goo/{file1, file2, file3}
    
    This is not what users want; they did not rename foo/ -> goo/, they only
    renamed one file within that directory.  The reason this happens is am
    constructs fake trees (via build_fake_ancestor()) of the following form:
    
       Base_bfa  : bar_v1, foo/file3
       branch_bfa: bar_v2, goo/file3
    
    Combining these two trees with master's tree:
    
       master: bar_v3, foo/{file1, file2, file3},
    
    You can see that merge_recursive_generic() would see branch_bfa as renaming
    foo/ -> goo/, and master as just adding both foo/file1 and foo/file2.  As
    such, it ends up with goo/{file1, file2, file3}
    
    The core problem is that am does not have access to the original trees; it
    can only construct trees using the blobs involved in the patch.  As such,
    it is not safe to perform directory rename detection within am -3.
    
    Signed-off-by: default avatarElijah Newren <newren@gmail.com>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    6aba117d