[git] 한 저장소에서 다른 저장소로 git 패치를 적용하는 방법은 무엇입니까?

두 개의 저장소가 있는데 하나는 라이브러리의 기본 저장소이고 다른 하나는 해당 라이브러리를 사용하는 프로젝트입니다.

하위 프로젝트를 수정하면 해당 패치를 업스트림에 쉽게 적용 할 수있는 방법이 필요합니다.

파일의 위치는 저장소마다 다릅니다.

  • 기본 저장소 : www.playdar.org/static/playdar.js
  • 계획: playlick.com/lib/playdar.js

나는 사용하여 시도 git format-patch -- lib/playdar.jsplaylick 프로젝트, 다음 git am주 playdar의 환매 특약에 있지만, 패치 파일에서 다른 파일 위치에 오류가 발생합니다.

주어진 파일에 대한 주어진 커밋의 패치를 다른 임의의 파일에 적용하는 쉬운 방법이 있습니까?

보너스 포인트의 경우 패치를 적용하려는 파일이 git 저장소에 없으면 어떻게됩니까?



답변

수동 패치 파일을 편집하는 질문 또는 불가능 벗어나면,이 표준 옵션 (로모 수행 할 수 있습니다 git apply, git format-patch그리고 GNU patch).

  1. -p<n>n패치의 경로에서 선행 디렉토리를 제거 합니다.

  2. 처리 후 -p, --directory=<root>앞에 추가 root적용하기 전에 패치의 각 경로에 관한 것이다.

따라서 예를 들어 원래 있던 패치를에 static/playdar.js적용하려면 lib/playdar.js다음을 실행합니다.

$ cat patch_file | git am     \
          -p1                 \ # remove 1 leading directory ('static/')
         --directory='lib/'     # prepend 'lib/'


답변

에서 생성 된 패치 git format-patch는 단순히 텍스트 파일입니다. diff 헤더를 편집하여 다른 경로를 수정할 수 있습니다.

예를 들어 다음과 같이 생성되었을 것입니다.

diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js

당신이해야 할 모든 변화 lib/playdar.jsstatic/playdar.js다음 패치를 통해 실행git am"

패치는없는 사람들을위한 표준 GNU 패치 유틸리티 읽을 수 있어야 git—하지만 실행하지 않는 format-patch으로 -M,-C 그들에 대한 지원은 보편적하지 않기 때문에, 그 경우 생산 이름 바꾸기 패치 등의 옵션을 제공합니다.


답변

두 프로젝트가 모두 git 프로젝트라고 가정하면 하위 모듈 이 당신에게 완벽하게 맞는 것 같습니다. 이를 통해 git 프로젝트가 다른 git 프로젝트에 동적으로 연결되어 본질적으로 다른 git repo 내에서 바로 git repo를 베이킹 할 수 있습니다.

즉, “프로젝트”의 하위 모듈로 “main repo”를 추가합니다. “메인 저장소”에서 새 항목을 커밋 / 푸시 할 때마다 git pull“프로젝트”로 돌아갑니다.


답변

Henrik의 답변 을 완료 하고 보너스 포인트 를 얻으려면

패치를 적용하려는 파일이 git 저장소에 없으면 어떻게합니까?

git 저장소에서 오는 패치에 대한 파일 후보의 디렉토리에 액세스 할 수 있다면 먼저 해당 디렉토리 / 파일 트리를 git 저장소 자체로 변환 할 수 있습니다! ( ‘ git init‘: git 저장소는 결국 루트 디렉토리 내의 .git 일뿐입니다).
그런 다음 해당 저장소를 기본 프로젝트의 하위 모듈로 설정합니다.


답변

--relative옵션을 사용하여 format-patch추상화를 개선 할 수 있습니다 (패치가 생성 된 저장소에 대한 관련없는 세부 정보 숨기기).

[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'

오류 --3way방지를 위해 패치를 적용 할 때 필요한 옵션을 찾았습니다 does not exist in index. 마일리지가 다를 수 있습니다. 사용 --directory=(...)은 대상 경로가 저장소의 루트가 아닌 경우에만 필요합니다.

[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)

  • format-patch ‘base’이후 현재 브랜치에 대한 커밋 당 하나의 패치 파일을 생성합니다.

  • --relative옵션에 대한 문서 가 일부 경우 누락 된 것처럼 보이지만 어쨌든 작동하는 것 같습니다 (버전 2.7.4 기준).


답변

새 리모컨을 추가하고 가져올 수 있습니다. 세부 사항이있는 기사.

$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA


답변

일시적으로 기본 저장소를 제거 (이름 변경) 할 수 있습니다.

cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git