2017-04-27 7 views
8

하나의 저장소에서 다른 저장소로 두 파일을 옮기고 싶습니다.여러 개의 이름을 가진 두 파일에 대한 Git 패치를 만듭니다.

  1. /src/init/PriceValue.cs
  2. /tests/init/PriceValueTests.cs
: /tests/init/PriceTests.cs

두 파일

  1. /src/init/Price.cs
  2. 나중에로 이름이 변경되었습니다 : 같은 파일은 원래 추가되었습니다

    1. /src/moved/PriceValue.cs
    2. /tests/moved/PriceValueTests.cs

    내가 이러한 파일의 패치 세트를 만들 this description로 이동하려고했습니다,하지만 난 방법을 확실 해요 : 6,

    그리고 한 다음에 이동 파일이 존재하는 여섯 가지 경로를 전달하십시오.

    나는 (이름 변경 및 이동에 걸쳐) PriceValue.cs에 영향을 미치는 모든 커밋 ID를 찾아 나섰고 힘내에 그 ID를 통과하면 다음과 같은 오류 메시지와 함께 실패했습니다

    $ git format-patch -o /tmp/pricevaluepatches $(git log --all dfeeb 6966b 9f882 …) 
    -bash: /usr/local/bin/git: Argument list too long 
    

    그래서, 어떻게 내가 어떻게 만듭니 까 언급 된 파일에 대한 변경 사항 만 포함되어 있지만 하나의 이름 바꾸기와 각 파일 이동에 대해 변경 사항이 포함 된 패치 세트

+0

모든 커밋 ID를'ids.txt' (한 줄에 하나씩) 파일에 넣고'cat ids.txt | xargs git format-patch -o/tmp/pricevaluepatches'? –

+2

또한 명령에서'git log --all ...'을 실행할 필요가 없습니다. 간단한'git format-patch -o/tmp/pricevaluepatches dfeeb 6966b 9f882 ...'이면 충분합니다. –

+0

@ NilsWerner, 제안에 감사드립니다. 하지만 문제의 절반 만 해결합니다. 내가 가지고있는 ID로 인식되는 커밋에서 이름 바꾸기와 이동에 걸쳐 'PriceValue.cs' 및'PriceValueTests.cs'에 영향을주는 변경 만 적용하려면 어떻게해야합니까? –

답변

1

음 ..... 패치 파일을 원래 상태대로 유지하려는 경우 패치 파일을 분기에 적용하여 올바른 분기에서 체리를 선택할 수 있도록해야합니다.

그래서 master 브랜치에 /tests/moved/PriceValueTests.cs라는 파일이 있고이를 대신 /tests/init/PriceTests.cs라는 이름의 패치를 적용하고 싶습니다. 내가하지 패치 파일을 해킹 싶어 가정, 내가 무엇을 할 것입니다 것은 :

  • 가 동일한 경로에 파일 이름을 변경 내 주인
  • 체크 아웃 임시 지점
  • 에서 임시 지점을 만드는 것이 패치 파일은
  • 임시 분기에 패치 파일을 적용
  • 임시 지점
  • CHEC에 커밋 (파일 경로가 일치하는 파일을 가지고 지금 작동합니다) (물론, 커밋)이있다 카우이 너무입니다 일시적 지점

에서 최종 개정

  • 체리 픽 마스터 이름 변경을 추적하고 성공적으로 적용 할 수 있습니다 그 자식. 나는 그것을 여러 번 해냈고 git의 파일 이름 바꾸기 알고리즘은 올바르게 작동하는 경향이있다.

  • +0

    이 질문은 대답이 아닌 다른 대답입니다. 이 질문에는 패치가 필요한 파일이 없으며 한 저장소에서 다른 저장소로 이동 한 파일 만 있습니다. –

    6

    당신은 오래된 파일 (이전 이름 ​​변경에) 또는 기존 파일을 할 수있다

    git format-patch sha1 -- file1 file2 ... 
    

    파일 중 하나를 사용하여 sha1 커밋보다 먼저 몇 가지 특정 파일 하지만의 패치를 얻을 수 있습니다. 당신이 모든 커밋 될 때까지 sha1 당신이 그래서 귀하의 경우

    git format-patch --root sha1 -- file1 file2 ... 
    

    을 사용할 수 있습니다 커밋합니다

    모든 당신의 여섯 개 파일의 지금 (HEAD를) 할 때까지 커밋 :

    git format-patch --root HEAD -- /src/init/Price.cs /src/init/PriceValue.cs /src/moved/PriceValue.cs /src/init/PriceTests.cs /src/init/PriceValueTests.cs /src/moved/PriceValueTests.cs 
    
    +0

    그래서 모든 위치의 모든 파일에 영향을 미치는 모든 커밋 ID를 먼저 알아야합니까? –

    +0

    아니요, 원하는 첫 번째 것입니다. 이 파일들에 대해 * 모든 커밋 *을 원한다면 sha1에'origin'을 입력하면됩니다. –

    +0

    @ AsbjørnUlsberg :'format-patch'는 하나의 선형 히스토리를 재현 할 수 있도록 패치 시퀀스를 생성합니다. 병합을 통해 지사의 이력을 "이식"하는 것을 허용하지 않습니다. 하나의 개별 패치에는 부모에 대한 정보가 포함되어 있지 않습니다. – LeGEC

    1

    것은 달성하기 위해 병합을 통한 질문 (format-patch를 통해 개별 패치를 이동하는 대신 질문으로 질문 함)에서 새 커밋의 다른 모든 파일을 제거한 다음 리포지토리 전체에서 해당 커밋을 병합 할 수 있습니다 (https://stackoverflow.com/a/10548919/7496656에서 적응) 대상 저장소로들 :

    cd path/to/project-a 
    git checkout -b for-b master # or whichever branch you want to merge from 
    git rm -r . 
    git checkout HEAD -- src/moved/PriceValue.cs tests/moved/PriceValueTests.cs 
    git commit 
    cd path/to/project-b 
    git remote add project-a path/to/project-a 
    git fetch project-a 
    git merge --allow-unrelated-histories project-a/for-b 
    git remote remove project-a 
    cd path/to/project-a 
    git branch -D for-b 
    

    이 모든 역사는이 장점을 가지고, 커밋 ID는 동일하게 유지하고 개인의 커밋을 저글링도 찾을 필요가 없습니다. 그래프보기 (예 : gitk)와는 대조적으로 선형화 된보기 (예 : git log)가 관련이없는 커밋 수가 커질수록 더 혼란스럽게된다는 단점이있을 수 있습니다.

    병합하기 전에 project-a 리포지토리를 필터링하여 관련없는 파일이나 커밋을 숨길 수 있습니다. 그러나 단점은 다음과 같습니다. 저장소 리포지토리에서이 작업을 여러 번 병합하면 다른 방향으로 병합 될 수도 있습니다. 이렇게하면 공용 히스토리가 여러 번 (각 병합마다 한 번) 발생하기 때문에 히스토리가 정리되지 않습니다. 이것은 또한이 솔루션을 처음 시도한 것보다 어렵게 만듭니다. 또한 커밋 ID가 동일하게 유지되지 않으므로 리포지토리에서 동일한 커밋을 쉽게 찾을 수 없다는 단점이 있습니다.