Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declare merge-ort ready for general usage #905

Closed
wants to merge 13 commits into from

Commits on Mar 16, 2021

  1. merge-ort: use STABLE_QSORT instead of QSORT where required

    rename/rename conflict handling depends on the fact that if both sides
    renamed the same path, that the one on the MERGE_SIDE1 will appear first
    in the combined diff_queue_struct passed to process_renames().  Since we
    add all pairs from MERGE_SIDE1 to combined first, and then all pairs
    from MERGE_SIDE2, and then sort based on filename, this will only be
    true if the sort used is stable.  This was found due to the fact that
    Mac, unlike Linux, apparently has a system-defined qsort that is not
    stable.
    
    While we are at it, review the other callers of QSORT and add comments
    about why they can remain as calls to QSORT instead of being modified
    to call STABLE_QSORT.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    e223f84 View commit details
    Browse the repository at this point in the history
  2. merge-ort: add a special minimal index just for renormalization

    renormalize_buffer() requires an index_state, which is something that
    merge-ort does not operate with.  However, all the renormalization code
    needs is an index with a .gitattributes file...plus a little bit of
    setup.  Create such an index, along with the deallocation and
    attr_direction handling.
    
    A subsequent commit will add a function to finish the initialization
    of this index.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    6d34cc4 View commit details
    Browse the repository at this point in the history
  3. merge-ort: have ll_merge() use a special attr_index for renormalization

    ll_merge() needs an index when renormalization is requested.  Create one
    specifically for just this purpose with just the one needed entry.  This
    fixes t6418.4 and t6418.5 under GIT_TEST_MERGE_ALGORITHM=ort.
    
    NOTE 1: Even if the user has a working copy or a real index (which is
    not a given as merge-ort can be used in bare repositories), we
    explicitly ignore any .gitattributes file from either of these
    locations.  merge-ort can be used to merge two branches that are
    unrelated to HEAD, so .gitattributes from the working copy and current
    index should not be considered relevant.
    
    NOTE 2: Since we are in the middle of merging, there is a risk that
    .gitattributes itself is conflicted...leaving us with an ill-defined
    situation about how to perform the rest of the merge.  It could be that
    the .gitattributes file does not even exist on one of the sides of the
    merge, or that it has been modified on both sides.  If it's been
    modified on both sides, it's possible that it could itself be merged
    cleanly, though it's also possible that it only merges cleanly if you
    use the right version of the .gitattributes file to drive the merge.  It
    gets kind of complicated.  The only test we ever had that attempted to
    test behavior in this area was seemingly unaware of the undefined
    behavior, but knew the test wouldn't work for lack of attribute handling
    support, marked it as test_expect_failure from the beginning, but
    managed to fail for several reasons unrelated to attribute handling.
    See commit 6f6e7cf ("t6038: remove problematic test", 2020-08-03) for
    details.  So there are probably various ways to improve what
    initialize_attr_index() picks in the case of a conflicted .gitattributes
    but for now I just implemented something simple -- look for whatever
    .gitattributes file we can find in any of the higher order stages and
    use it.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    4ff23d2 View commit details
    Browse the repository at this point in the history
  4. merge-ort: let renormalization change modify/delete into clean delete

    When we have a modify/delete conflict, but the only change to the
    modification is e.g. change of line endings, then if renormalization is
    requested then we should be able to recognize such a case as a
    not-modified/delete and resolve the conflict automatically.
    
    This fixes t6418.10 under GIT_TEST_MERGE_ALGORITHM=ort.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    c1c9605 View commit details
    Browse the repository at this point in the history
  5. merge-ort: support subtree shifting

    merge-recursive has some simple code to support subtree shifting; copy
    it over to merge-ort.  This fixes t6409.12 under
    GIT_TEST_MERGE_ALGORITHM=ort.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    41fffcd View commit details
    Browse the repository at this point in the history
  6. t6428: new test for SKIP_WORKTREE handling and conflicts

    If there is a conflict during a merge for a SKIP_WORKTREE entry, we
    expect that file to be written to the working copy and have the
    SKIP_WORKTREE bit cleared in the index.  If the user had manually
    created a file in the working tree despite SKIP_WORKTREE being set, we
    do not want to clobber their changes to that file, but want to move it
    out of the way.  Add tests that check for these behaviors.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    6aec1f4 View commit details
    Browse the repository at this point in the history
  7. merge-ort: implement CE_SKIP_WORKTREE handling with conflicted entries

    When merge conflicts occur in paths removed by a sparse-checkout, we
    need to unsparsify those paths (clear the SKIP_WORKTREE bit), and write
    out the conflicted file to the working copy.  In the very unlikely case
    that someone manually put a file into the working copy at the location
    of the SKIP_WORKTREE file, we need to avoid overwriting whatever edits
    they have made and move that file to a different location first.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    fe3baf6 View commit details
    Browse the repository at this point in the history
  8. t: mark several submodule merging tests as fixed under merge-ort

    merge-ort handles submodules (and directory/file conflicts in general)
    differently than merge-recursive does; it basically puts all the special
    handling for different filetypes into one place in the codebase instead
    of needing special handling for different filetypes in many different
    code paths.  This one code path in merge-ort could perhaps use some work
    still (there are still test_expect_failure cases in the testsuite), but
    it passes all the tests that merge-recursive does as well as 12
    additional ones that merge-recursive fails.  Mark those 12 tests as
    test_expect_success under merge-ort.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    f932564 View commit details
    Browse the repository at this point in the history
  9. merge-ort: write $GIT_DIR/AUTO_MERGE whenever we hit a conflict

    There are a variety of questions users might ask while resolving
    conflicts:
      * What changes have been made since the previous (first) parent?
      * What changes are staged?
      * What is still unstaged? (or what is still conflicted?)
      * What changes did I make to resolve conflicts so far?
    The first three of these have simple answers:
      * git diff HEAD
      * git diff --cached
      * git diff
    There was no way to answer the final question previously.  Adding one
    is trivial in merge-ort, since it works by creating a tree representing
    what should be written to the working copy complete with conflict
    markers.  Simply write that tree to .git/AUTO_MERGE, allowing users to
    answer the fourth question with
      * git diff AUTO_MERGE
    
    I avoided using a name like "MERGE_AUTO", because that would be
    merge-specific (much like MERGE_HEAD, REBASE_HEAD, REVERT_HEAD,
    CHERRY_PICK_HEAD) and I wanted a name that didn't change depending on
    which type of operation the merge was part of.
    
    Ensure that paths which clean out other temporary operation-specific
    files (e.g. CHERRY_PICK_HEAD, MERGE_MSG, rebase-merge/ state directory)
    also clean out this AUTO_MERGE file.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    4a79e61 View commit details
    Browse the repository at this point in the history
  10. merge-recursive: add a bunch of FIXME comments documenting known bugs

    The plan is to just delete merge-recursive, but not until everyone is
    comfortable with merge-ort as a replacement.  Given that I haven't
    switched all callers of merge-recursive over yet (e.g. git-am still uses
    merge-recursive), maybe there's some value documenting known bugs in the
    algorithm in case we end up keeping it or someone wants to dig it up in
    the future.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    a379794 View commit details
    Browse the repository at this point in the history
  11. Revert "merge-ort: ignore the directory rename split conflict for now"

    This reverts commit 5ced7c3, which was
    put in place as a temporary measure to avoid optimizations unstably
    erroring out on no destination having a majority of the necessary
    renames for directories that had no new files and thus no need for
    directory rename detection anyway.  Now that optimizations are in place
    to prevent us from trying to compute directory rename count computations
    for directories that do not need it, we can undo this temporary measure.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    6bda855 View commit details
    Browse the repository at this point in the history
  12. t6423: mark remaining expected failure under merge-ort as such

    When we started on merge-ort, thousands of tests failed when run with
    the GIT_TEST_MERGE_ALGORITHM=ort flag; with so many, it didn't make
    sense to flip all their test expectations.  The ones in t6409, t6418,
    and the submodule tests are being handled by an independent in-flight
    topic ("Complete merge-ort implemenation...almost").  The ones in
    t6423 were left out of the other series because other ongoing series
    that this commit depends upon were addressing those.  Now that we only
    have one remaining test failure in t6423, let's mark it as such.
    
    This remaining test will be fixed by a future optimization series, but
    since merge-recursive doesn't pass this test either, passing it is not
    necessary for declaring merge-ort ready for general use.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 16, 2021
    Configuration menu
    Copy the full SHA
    1c6361c View commit details
    Browse the repository at this point in the history

Commits on Mar 19, 2021

  1. Add testing with merge-ort merge strategy

    In preparation for switching from merge-recursive to merge-ort as the
    default strategy, have the testsuite default to running with merge-ort.
    Keep coverage of the recursive backend by having the linux-gcc job run
    with it.
    
    Signed-off-by: Elijah Newren <newren@gmail.com>
    newren committed Mar 19, 2021
    Configuration menu
    Copy the full SHA
    c2d2a1c View commit details
    Browse the repository at this point in the history