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

fast-import: avoid making replace refs point to themselves #1824

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Commits on Nov 18, 2024

  1. fast-import: avoid making replace refs point to themselves

    If someone replaces a commit with a modified version, then builds on
    that commit, and then later decides to rewrite history in a format like
    
        git fast-export --all | CMD_TO_TWEAK_THE_STREAM | git fast-import
    
    and CMD_TO_TWEAK_THE_STREAM undoes the modifications that the
    replacement did, then at the end you'd get a replace ref that points to
    itself.  For example:
    
        $ git show-ref | grep replace
        fb92ebc654641b310e7d0360d0a5a49316fd7264 refs/replace/fb92ebc654641b310e7d0360d0a5a49316fd7264
    
    Git commands which pay attention to replace refs will die with an error
    when a self-referencing replace ref is present:
    
        $ git log
        fatal: replace depth too high for object fb92ebc654641b310e7d0360d0a5a49316fd7264
    
    Avoid such problems by deleting replace refs that will simply end up
    pointing to themselves at the end of our writing.  Unless users specify
    --quiet, warn them when we delete such a replace ref.
    
    Two notes about this patch:
      * We are not ignoring the problematic update of the replace ref
        (turning it into a no-op), we are replacing the update with a delete.
        The logic here is that if the repository had a value for the replace
        ref before fast-import was run, and the replace ref was explicitly
        named in the fast-import stream, we don't want the replace ref to be
        left with a pre-fast-import value.
      * While loops with more than one element (e.g. refs/replace/A points
        to B, and refs/replace/B points to A) are possible, they seem much
        less plausible.  It is pretty easy to create a sequence of
        git-filter-repo commands that will trigger a self-referencing replace
        ref, but I do not know how to trigger a scenario with a cycle length
        greater than 1.
    
    Signed-off-by: Elijah Newren <[email protected]>
    newren committed Nov 18, 2024
    Configuration menu
    Copy the full SHA
    cc77a00 View commit details
    Browse the repository at this point in the history