git : 한 리포지토리의 커밋에 의해 도입 된 변경 사항을 다른 리포지토리에 적용


115

나는 repo1repo2로컬 컴퓨터에 있습니다. 그들은 매우 유사하지만 후자는 일종의 다른 분기입니다 ( repo1더 이상 유지되지 않음).

/path/to/repo1 $ git log HEAD~5..HEAD~4
<some_sha> Add: Introduce feature X

어떻게 커밋에 의해 변경 적용 <some_sha>repo1에를 repo2?

패치를 준비해야 cherry-pick합니까? 아니면 리포지토리간에 패치를 수행 할 수 있습니까?

동일하지만 커밋 범위에 대해 어떻게합니까?


2
repo1에서 repo2로 가져올 수 없습니까?
zwol

당신이 저장소 중 하나에 이동 된 파일이나 파일에 대한 변경 사항을 적용하기 위해 찾고있는 좀 더 구체적인 경우에, 이쪽을 봐 : stackoverflow.com/questions/3491270/...
브라만 스나이더

답변:


31

해킹 으로 GitTips 페이지에서 두 개의 다른 저장소에있는 커밋을 비교하기위한 레시피를 수정할 수 있습니다 .

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects \
git cherry-pick $(git --git-dir=../repo/.git rev-parse --verify <commit>)

어디 ../repo다른 저장소에 대한 경로입니다.

최신 Git을 사용하면 cherry-pick으로 여러 개정 및 개정 범위를 사용할 수 있습니다. .

$(git --git-dir=../repo/.git rev-parse --verify <commit>) 번역 여기 <commit>(예 HEAD, 또는 v0.2또는 master~2커밋의 SHA-1 식별자로는 복사해서 제 리포지토리 값인하는). 선택하려는 변경의 SHA-1을 알고 있으면 필요하지 않습니다.

참고 가 다른 객체 저장소가 하나 개의 작업을 위해, 일시적 것을 알고하지 않습니다하지만 힘내, 소스 저장소에서 개체를 복사 건너 뛸 수있다. 다음을 사용하여 두 번째 저장소에서 개체를 복사해야 할 수 있습니다.

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects git repack -a -d -f

이렇게하면 두 번째 저장소에서 빌린 객체가 원래 저장소 저장소에 저장됩니다.

검증되지 않은.


그렇게 해키하지 않은 해결책은 knittl 대답 을 따르는 것입니다 .

  • 커밋을 복사하려는 두 번째 저장소로 이동하고 원하는 커밋에서 패치를 생성합니다. git format-patch
  • 선택적으로 패치 (0001- * 등)를 저장소에 복사합니다.
  • git am --3way패치 적용에 사용

1
잘 작동합니다. 커밋에 문제가 있으면 'git reset HEAD; git add. '.
gumik

5
이것은 굉장합니다. 다양한 커밋을 어떻게 수행 하시겠습니까? 그냥 sha1 ... sha2?
hvgotcodes 2013 년

나도 얻지 fatal: unable to read tree ...git reset HEAD^모든 것이 잘 작동 한 후에
jmarceli 2014

@hvgotcodes 그것은 단순히 범위를 전달함으로써 나를 위해 일 <commit>했지만 rev-parse --verify명령은 단일 커밋 값 만 허용하기 때문에 그것을 좋아하지 않습니다. 그러나 cherry-pick단일 및 범위 커밋 값을 모두 허용하므로 질문합니다. 왜 rev-parse필요한가요?
Chuim

1
@Chuim : git rev-parse다른 저장소 예에서의 심판 기반의 이름으로 커밋을 참조 할 경우 필요 master, HEAD^^또는 그런 일; rev-parse는이를 범용 SHA-1 식별자로 바꿉니다.
Jakub Narębski

207

아마도 해당 패치를 사용한 다음 저장소에 적용 git format-patch하고 싶을 것입니다 git am.

/path/to/1 $ git format-patch sha1^..sha1
/path/to/1 $ cd /path/to/2
/path/to/2 $ git am -3 /path/to/1/0001-…-….patch

또는 한 줄로 :

/path/to/2 $ git --git-dir=/path/to/1/.git format-patch --stdout sha1^..sha1 | git am -3

9
이 솔루션은 직접 체리 피킹 GIT_ALTERNATE_OBJECT_DIRECTORIES(내 저장소를 손상시킬 수 있음)을 사용하는 허용 된 답변보다 더 간단하고 안전 합니다.
Chuim

2
충돌이 있으면 다른 브랜치에서 커밋을 찾지 못해 작동하지 않습니다.
Roger Far

2
추가 --ignore-whitespace받는 git am명령은 충돌을 해결하고 3 방향 병합을 수행 할 필요가 피할 수
Hugheth

97

cherry-pick두 번째 저장소를 첫 번째 저장소에 원격으로 추가하면 할 수 있습니다 fetch.


11
그것은 실제로 그것을하는 적절한 방법입니다.
Wilbert 2013 년

5
이것은 나에게도 올바른 방법 인 것 같습니다. 그리고 나는 그것을 사용했고 그것은 나를 위해 잘 작동했습니다.
리키 넬슨

11
차라리 말하고 싶습니다 : git fetch [remote-name]두 번째 repo에서 수행 한 다음 git cherry-pick [sha1].

5
이 접근 방식은 저에게 효과적이었습니다. 감사합니다. 두 번째 저장소도 로컬이므로 원격으로 추가 할 때 파일 URI를 사용해야했습니다.
palimpsestor

2
제 경우에는 (병렬 작업을 허용하기 위해) 거대한 원격 git 저장소의 두 복제본이 있습니다. 즉, 모든 기록이 이미 다운로드되어 HD에 두 번 저장됩니다. 또한 각각을 다른 리모컨으로 추가해야한다면 동일한 기록의 두 개의 추가 사본이 생성되고 잠재적으로 동기화를 수행해야 할 수 cherry-pick있습니다. 따라서 "올바른"방식으로 느껴지더라도 항상 가장 실용적인 것은 아닙니다.
Chuim

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.