git merge : 다른 파일로 이동 한 코드에 변경 사항을 적용 변경했지만 동료가 해당 코드를 지점의 새

나는 지금 꽤 강력한 git merge 기동을 시도하고 있습니다. 내가 겪고있는 한 가지 문제는 지점의 일부 코드를 약간 변경했지만 동료가 해당 코드를 지점의 새 파일로 옮겼다는 것입니다. 그래서 내가 할 때 git merge my_branch his_branchgit은 새 파일의 코드가 이전 코드와 동일하다는 것을 알지 못했기 때문에 변경 사항이 없습니다.

변경 사항을 새 파일의 코드에 다시 적용하는 가장 쉬운 방법은 무엇입니까? 어떤 커밋을 다시 적용 해야하는지 찾는 데 너무 많은 문제가 없습니다 (그냥 사용할 수 있습니다 git log --stat). 그러나 내가 알 수있는 한, git이 변경 사항을 새 파일에 다시 적용 할 수있는 방법은 없습니다. 지금보고있는 가장 쉬운 방법은 변경 내용을 수동으로 다시 적용하는 것인데, 이는 좋은 생각처럼 보이지 않습니다.

나는 git이 파일이 아닌 blob을 인식한다는 것을 알고 있으므로 “이 커밋 에서이 정확한 코드 변경 사항을 적용하십시오.



답변

비슷한 문제가 있었고 대상 파일 구성과 일치하도록 작업을 조정하여 문제를 해결했습니다.

수정 한 것을 말한다 original.txt지사 (온 local지점),하지만 마스터 분기에, original.txt또 다른 하나에 복사 된 말 copy.txt. 이 사본은 commit이라는 커밋에서 수행되었습니다 CP.

에 수행 된 모든 로컬 변경 사항, 커밋 AB아래 original.txt를 새 파일 에 적용하려고 합니다 copy.txt.

 ---- X -----CP------ (master)
       \
        \--A---B--- (local)

move을 사용하여 변경 시작 지점에 버리기 지점 을 만듭니다 git branch move X. 즉, 병합하려는 커밋 이전의 move분기를 commit에 두십시오 X. 아마도 이것은 변경 사항을 구현하기 위해 분기 한 커밋입니다. @digory doo 사용자 가 아래에 쓴 것처럼 git merge-base master local을 찾을 수 X있습니다.

 ---- X (move)-----CP----- (master)
       \
        \--A---B--- (local)

이 분기에서 다음 이름 변경 명령을 실행하십시오.

git mv original.txt copy.txt

파일 이름이 바뀝니다. 참고 copy.txt아직이 시점에서 트리에 존재하지 않았다.
변경 사항을 커밋하십시오 (이 커밋 이름을 지정합니다 MV).

        /--MV (move)
       /
 ---- X -----CP----- (master)
       \
        \--A---B--- (local)

이제 다음 작업을 기반으로 작업을 리베이스 할 수 있습니다 move.

git rebase move local

문제없이 작동하며 변경 사항이 copy.txt로컬 지점에 적용됩니다 .

        /--MV (move)---A'---B'--- (local)
       /
 ---- X -----CP----- (master)

MV이동 조작 CP으로 인해 메인 브랜치 에서 커밋 할 때 복사 조작과 충돌이 발생할 수 있으므로 이제는 메인 브랜치 히스토리에서 커밋을 원하지 않거나 가질 필요가 없습니다 .

다음과 같이 이동 작업을 삭제하고 작업을 다시베이스로 변경하면됩니다.

git rebase move local --onto CP

… 다른 지점에서 도입 된 CP커밋은 어디에 있습니까 copy.txt? 이것은 커밋 copy.txt상단의 모든 변경 사항을 리베이스합니다 CP. 이제 local브랜치는 항상 수정 copy.txt하고 아닌 것처럼 정확하게 original.txt유지되며 다른 사람과 계속 병합 할 수 있습니다.

                /--A''---B''-- (local)
               /
 -----X-------CP----- (master)

변경 사항이 적용 CP되거나 copy.txt존재하지 않고 변경 사항이 다시 적용되는 것이 중요합니다 original.txt.

이것이 분명하기를 바랍니다. 이 답변은 늦었지만 다른 사람에게는 유용 할 수 있습니다.


답변

항상 git diff(또는 git format-patch)를 사용하여 패치를 생성 한 다음 패치에서 파일 이름을 수동으로 편집하고 git apply(또는 git am)로 적용 할 수 있습니다 .

이것의 부족으로, 자동으로 작동하는 유일한 방법은 git의 이름 변경 감지가 이전 파일과 새 파일이 같은 것을 알아낼 수 있는지입니다. git은 파일이 아닌 blob을 사용하지만 blob은 파일 이름과 메타 데이터가 첨부되지 않은 전체 파일의 내용 일뿐입니다. 따라서 두 파일 사이에서 코드 덩어리가 이동하면 실제로 동일한 얼룩이 아닙니다. 나머지 얼룩의 내용은 다릅니다.


답변

다음은 이름 바꾸기 및 편집시 병합 충돌이 발생하고 올바른 3 개의 병합 소스 파일을 인식하는 mergetool로이를 해결 하는 병합 솔루션입니다.

  • ‘삭제 된 파일’로 인해 병합이 실패하면 이름이 바뀌고 편집 된 것입니다.

    1. 병합을 중단합니다.
    2. 지점에서 이름이 바뀐 파일을 커밋합니다.
    3. 그리고 다시 합치십시오.

연습 :

file.txt를 작성하십시오.

$ git init
Initialized empty Git repository in /tmp/git-rename-and-modify-test/.git/

$ echo "A file." > file.txt
$ git add file.txt
$ git commit -am "file.txt added."
[master (root-commit) 401b10d] file.txt added.
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt

나중에 편집 할 지점을 만듭니다.

$ git branch branch-with-edits
Branch branch-with-edits set up to track local branch master.

마스터에서 이름 바꾸기 및 편집을 작성하십시오.

$ git mv file.txt renamed-and-edited.txt
$ echo "edits on master" >> renamed-and-edited.txt
$ git commit -am "file.txt + edits -> renamed-and-edited.txt."
[master def790f] file.txt + edits -> renamed-and-edited.txt.
 2 files changed, 2 insertions(+), 1 deletion(-)
 delete mode 100644 file.txt
 create mode 100644 renamed-and-edited.txt

지점으로 스왑하고 편집하십시오.

$ git checkout branch-with-edits
Switched to branch 'branch-with-edits'
Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
$
$ echo "edits on branch" >> file.txt
$ git commit -am "file.txt edited on branch."
[branch-with-edits 2c4760e] file.txt edited on branch.
 1 file changed, 1 insertion(+)

마스터 병합을 시도하십시오 :

$ git merge master
CONFLICT (modify/delete): file.txt deleted in master and modified in HEAD. Version HEAD of file.txt left in tree.
Automatic merge failed; fix conflicts and then commit the result.

충돌을 해결하기 어렵고 파일 이름이 바뀌 었습니다. 중단하고 이름 바꾸기를 모방합니다.

$ git merge --abort
$ git mv file.txt renamed-and-edited.txt
$ git commit -am "Preparing for merge; Human noticed renames files were edited."
[branch-with-edits ca506da] Preparing for merge; Human noticed renames files were edited.
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename file.txt => renamed-and-edited.txt (100%)

다시 병합하십시오 :

$ git merge master
Auto-merging renamed-and-edited.txt
CONFLICT (add/add): Merge conflict in renamed-and-edited.txt
Recorded preimage for 'renamed-and-edited.txt'
Automatic merge failed; fix conflicts and then commit the result.

큰! 병합하면 mergetool로 해결할 수있는 ‘정상적인’충돌이 발생합니다.

$ git mergetool
Merging:
renamed-and-edited.txt

Normal merge conflict for 'renamed-and-edited.txt':
  {local}: created file
  {remote}: created file
$ git commit
Recorded resolution for 'renamed-and-edited.txt'.
[branch-with-edits 2264483] Merge branch 'master' into branch-with-edits


답변