병합에서 잃어버린 두 번째 아버지 복구

12386 단어 Git
두 번째 부모가 기록하지 않고 제출하지 않은 합병을 합병으로 어떻게 통합할 것인가를 고려한다.

전제 조건

  • 재결합 안 함
  • 모회사 제출 외에 제출 시 창고 내용을 변경하지 않음
  • 커밋된 타임스탬프를 변경하지 않음(Commoniter Date 포함)

  • 그림의 제출 A5는 B4를 제출 A4에 통합한 제출이다.
    어떤 이유로 합병을 제출하지 않아 B4-A5의 선이 사라졌다1.
    이거 제자리에 놓을게요.

    방법1


    나는 rebase로 방법을 강구해서 해결하고 싶다. 곧 생각해 낼 수 있다.
    git checkout A
    git rebase -i A3
    
    pick A4
    exec git merge -s ours B4
    fixup A5
    pick A6
    pick A7
    
  • merge에서 빈 합병 제출을 지정-s ours합니다.
  • A5를 융합시켜 목적의 수정판 도표를 얻을 수 있다.
  • 그러나 이런 방법은 A5가 제출한 정보와 시간 스탬프를 잃어버릴 수 있다.

    방법2

    replace 상위 커밋만 수정합니다.
  • Git의 다양한 도구 교체 - Git 객체
  • usage: git replace [-f] <object> <replacement>
       or: git replace [-f] --edit <object>
       or: git replace [-f] --graft <commit> [<parent>...]
       or: git replace -d <object>...
       or: git replace [--format=<format>] [-l [<pattern>]]
    
        -l, --list            list replace refs
        -d, --delete          delete replace refs
        -e, --edit            edit existing object
        -g, --graft           change a commit's parents
        -f, --force           replace the ref if it exists
        --raw                 do not pretty-print contents for --edit
        --format <format>     use this format
    
    다음 명령줄을 사용하면 부모 제출을 수정할 수 있습니다.
    git replace --graft <commit> [<parent>...]
    
    따라서 다음 명령을 실행하면 목표의 수정 버전 도표를 얻을 수 있다.
    git checkout A
    git replace --graft A5 A4 B4
    git replace --graft A6 replace/A5
    git replace --graft A7 replace/A6
    git reset --hard replace/A7
    git replace -d A5
    git replace -d A6
    git replace -d A7
    
  • A5의 부모를 A4, B4로 변경한다.이것이 바로 합병 제출이다.
  • A6의 부모를 새로운 A5로 변경한다.A5를 대체한 제출 프로그램replace/A5은 참조할 수 있습니다.
  • 순서대로 부모를 바꾸어 도표를 연결한다.
  • 최신 커밋으로 교체하면 새 커밋으로 재설정됩니다.
  • 마지막으로 제출한 인용을 삭제합니다.
  • 부모님께 제출하는 것 이외에 아무것도 바뀌지 않으면 목표의 수정판 도표를 얻을 수 있다.
  • 이 방법은 rebase와 달리 작업 폴더에 차분을 적용하는 것이 아니기 때문에 매우 빠르다.

    각본화


    만약 대량의 제출이 있다면 수동으로 명령을 집행하는 것은 매우 어렵다.
    자세히 살펴보면 다음 순서대로 집행해도 문제없다는 것을 알 수 있다.
    git checkout A
    git replace --graft A5 A4 B4
    
    git replace --graft A6 replace/A5
    git replace -d A5
    
    git replace --graft A7 replace/A6
    git replace -d A6
    
    git reset --hard replace/A7
    git replace -d A7
    
    중간 부분은 중복되기 때문에 스크립트화됩니다. (샘플은 PowerShell입니다.)
    rebase-by-replace.ps1
    function rebase-by-replace($Commits, $InitialCommit)
    {
        git replace --graft $Commits[0] $InitialCommit $Commits[0]
        for($i = 1; $i -lt $Commits.length; $i++)
        {
            git replace --graft $Commits[$i] "replace/$($Commits[$i-1])" $Commits[$i]
            git replace -d $Commits[$i-1]
        }
    
        git reset --hard "replace/$($Commits[$Commits.length-1][0])"
        git replace -d $Commits[$Commits.length-1][0]
    }
    
    그러면 병합해서 제출할 수 없으니 일단 CSV 형식으로 두 번째 부모님께 드리죠.
    rebase-by-replace.ps1
    function rebase-by-replace($Commits, $InitialCommit)
    {
        for($i = 0; $i -lt $Commits.length; $i++)
        {
            $Commits[$i] = $Commits[$i] -split ','
        }
    
        git replace --graft $Commits[0][0] $InitialCommit $Commits[0][1]
        for($i = 1; $i -lt $Commits.length; $i++)
        {
            git replace --graft $Commits[$i][0] "replace/$($Commits[$i-1][0])" $Commits[$i][1]
            git replace -d $Commits[$i-1][0]
        }
    
        git reset --hard "replace/$($Commits[$Commits.length-1][0])"
        git replace -d $Commits[$Commits.length-1][0]
    }
    
    이 스크립트를 사용하여 다음을 수행할 수 있습니다.
    git checkout -b new_A A4
    rebase-by-replace @("A5,B4","A6","A7") A4
    
    예를 들어 잘못된 merge --squashgit-svn에서 Subversion에서 이동하고mergeinfo 속성을 성공적으로 포획하지 못할 때. 

    좋은 웹페이지 즐겨찾기