다른 자식 저장소에서 커밋을 체리 피킹 할 수 있습니까?


725

첫 번째 아무것도 모르는 다른 git 리포지토리에서 커밋이 필요한 git 리포지토리로 작업하고 있습니다.

일반적으로 HEAD@{x}reflog에서를 사용하여 cherry-pick을 선택 하지만 .git이 reflog 항목 (다른 물리적 디렉토리)을 알지 못하기 때문에 어떻게 이것을 체리 피킹 할 수 있습니까?

을 사용하고 git-svn있습니다. 내 첫 분기 사용 git-svntrunk서브 버전의 repo의, 다음 분기 사용되는 git-svn서브 버전 분기에.


2
이것이 Ben Lee 가이 질문에 대한 현상금을 개설 한 이유입니다 . "정답이 아니라 정답에 현상금을 수여 할 것입니다. 24 시간 만 기다려야합니다." 그러나 나는이 중 어느 것이 "올바른 답"이되어야하는지, 그리고 왜 받아 들여진 대답이 "바르지"않은지 이해하지 못한다.

1
문제의 본질이 무엇인지 명확하지 않습니다. 서로 다른 repos는 어떤 관련이 있습니까? 하나는 다른 것의 포크입니까? 아니면 실제로 두 개의 완전히 분리되고 관련이없는 프로젝트입니까?

@ 컵 케이크, 받아 들인 대답은 좋으며 OP를 분명히 도왔으므로 받아 들여야합니다. "올바른"이라는 말은 정말로 "나에게 맞는"이라는 의미였습니다. 나는 단지 현상금을 준 사람이 받아 들여진 대답만큼 많은 담당자에게 자격이 있다고 생각했습니다.
벤 리

답변:


555

다른 저장소를 원격으로 추가 한 다음 변경 사항을 가져와야합니다. 거기에서 커밋을보고 체리 픽을 선택할 수 있습니다.

그렇게 :

git remote add other https://example.link/repository.git
git fetch other

이제해야 할 모든 정보가 git cherry-pick있습니다.

리모컨 작업에 대한 자세한 정보는 https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes


1
git-svn을 사용하면 어떻게됩니까? 내 첫 번째 지점은 트렁크의 git-svn을 사용하고 다음은 지점에서 git-svn을 사용하고 있습니다 (빠른 답변 감사)
gitcoder182

1
Subversion 저장소를 처음 복제 할 때는 트렁크 만이 아니라 전체 저장소 를 복제해야합니다 . 또한 --stdlayoutSubversion에서 표준 트렁크 / 분기 / 태그 레이아웃을 사용하는 경우 git-svn 옵션 을 사용해야합니다 . 그러면 Subversion 브랜치는 단순한 원격 git 브랜치가됩니다.
wilhelmtell

33
Github을 사용하는 경우 커밋 URL에 .patch를 추가 한 다음 패치를 적용하여 패치를 가져올 수 있습니다 git am < d821j8djd2dj812.patch. GH 외부에서, 아래의 대안 적 답변에서 참조 된 것과 유사한 개념이 수행 될 수 있습니다.
radicand

2
@radicand 아래의 "대체"답변은 무엇입니까? 그것에 연결하십시오.


854

주어진 대답은 format-patch를 사용하는 것이지만 질문은 다른 폴더에서 체리를 선택하는 방법 이었기 때문에 다음과 같은 작업을 수행하는 코드가 있습니다.

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k

( @cong ma의 설명 )

git format-patch명령은 some_other_repoSHA로 지정된의 커밋 ( -1한 번의 커밋 만) 에서 패치를 만듭니다 . 이 패치는 git am로 패치되어 로컬로 패치를 적용합니다 ( -3패치가 제대로 적용되지 않으면 3 방향 병합 시도). 그것이 희망입니다.


18
이것은 자리에 있지만 누군가가 이것을 확장 할 수 있다면 좋을 것입니다-정확히 무슨 일이 일어나고 있는지 (특히 그 깃발로) 고장 나면 매우 유용 할 것입니다.
Nick F

45
@NickF, git format-patch명령은 some_other_repoSHA로 지정된의 커밋 ( -1한 번의 커밋 만) 에서 패치를 만듭니다 . 이 패치는 git am로 패치되어 로컬로 패치를 적용합니다 ( -3패치가 제대로 적용되지 않으면 3 방향 병합 시도). 그것이 희망입니다.
Cong Ma

3
오류 : 패치 실패 : somefile.cs : 85 오류 : somefile.cs : 패치가 적용되지 않습니다 패치를 직접 수정 했습니까? 인덱스에 기록 된 Blob에는 적용되지 않습니다. 3 방향 병합으로 돌아갈 수 없습니다. 0001에서 패치 실패 GUI 부품이 추가되었습니다. 실패한 패치의 사본은 <some_other_repo> /. git / rebase-apply / patch에 있습니다.이 문제를 해결 한 경우 "git am --continue"를 실행하십시오. 이 패치를 건너 뛰려면 대신 "git am --skip"를 실행하십시오. 원래 브랜치를 복원하고 패치 적용을 중지하려면 "git am --abort"를 실행하십시오.
Tom

8
@Tom을 사용해보십시오 --ignore-whitespace. 전체 명령 : git --git-dir=../<some_other_repo>/.git format-patch -k -1 --stdout <commit SHA> | git am -3 -k --ignore-whitespace
Jake Graham Arnold

7
@BoomShadow 더 간단하기 때문입니다. 리모컨을 추가하고 가져 오면 다른 리포지토리의 모든 변경 사항이 적용됩니다. 이 명령 행은 일회성 조치입니다.
Jonathon Reinhart

151

다음은 remote-fetch-merge의 예입니다.

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB

그럼 당신은 할 수 있습니다 :

git cherry-pick <first_commit>..<last_commit>

또는 전체 지점을 병합 할 수도 있습니다

git merge projectB/master

54
git merge projectB/master 아주, 아주 잘못 사용하면 단일의 변경 커밋 적용되지 있기 때문에, (체리 - 선택 하시겠습니까), 당신이 실제로에 병합하고 모든 변경 사항projectB/master자신에 포함되지 않은master지점입니다.

4
이것이 원래의 포스터 의도 였다는 것이 나의 가정이었다. 그렇지 않으면, 이것이 올바른 옵션이 아닙니다.
Brian

5
이것은 두 저장소가 관련되어있을 때 훌륭하게 작동합니다.
Ronny Ager-Wick

1
나는 git 저장소에서 사본을 만들었고 (원본 저장소를 깨지 않고 "재생"하기 위해) 소스와 함께 최신 상태로 유지하기 위해 Brian의 대답은 정확히 내가 필요한 것입니다. "잘못된"것이 아니라 또 다른 유스 케이스입니다. D : 그러나 당신이 잠재적 인 재난 지적하는에서 좋은
ferrari2k

6
IMO 이것은 허용되는 솔루션이어야합니다. 또한 체리 따기 작업을 마친 후 리모컨을 삭제하려면을 사용하십시오 git remote rm projectB. 또한 git tag -d tag-name원격 저장소에서 가져온 태그를 제거하는 데 사용 하십시오. 원격 커밋은 더 이상 히스토리에 표시되지 않으며, 프룬 (prune)하면 결국 스토리지에서 제거됩니다.
ADTC

130

할 수 있지만 두 단계가 필요합니다. 방법은 다음과 같습니다.

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

대체 <remote-git-url>당신이에서 체리 - 선택하고자하는 저장소의 URL 또는 경로.

대체 <branch>당신이 원하는 지점 또는 태그 이름으로 원격 저장소에서 벚꽃 선택하십시오.

FETCH_HEAD지점에서 git SHA로 바꿀 수 있습니다 .

업데이트 : @pkalinow의 피드백에 따라 수정되었습니다.


8
분기 이름에는 작동하지만 SHA에는 작동하지 않습니다. 해시로 표시된 커밋을 체리 피킹하려면 대신 이것을 사용하십시오 git fetch <repo-url> <branch> && git cherry-pick <sha>.
pkalinow

감사. 이것은 하나의 저장소에서 다른 저장소로 여러 커밋을 삽입하는 데 필요한 것입니다.
wojciii

이것은 서로 다른 클라이언트 (각각 자신의 저장소 / 포크를 가지고있는)를 위해 많은 코드를 사용자 정의 구현하여 필요한 것입니다. 우리는 기본 커밋에 특정 커밋을 가져 오는 방법이 필요했습니다. 감사!
RedSands

이것은 repos에서 one-shot cherry pick에 허용되는 답변이어야합니다. 이미 로컬 인 저장소 사이를 선택할 때 항상 사용합니다. 원격 URL은 로컬 파일 시스템 경로입니다.
Amedee Van Gasse

61

다음은 원격을 추가하고 분기를 가져오고 커밋을 선택하는 단계입니다.

# Cloning our fork
$ git clone git@github.com:ifad/rest-client.git

# Adding (as "endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git

# Fetch their branches
$ git fetch endel

# List their commits
$ git log endel/master

# Cherry-pick the commit we need
$ git cherry-pick 97fedac

출처 : https://coderwall.com/p/sgpksw


17

Git으로 패치를 작성하고 적용하는 방법을 참조하십시오 . (질문의 말에서,이 다른 저장소는 완전히 다른 코드베이스를위한 것이라고 가정했습니다. 동일한 코드베이스의 저장소라면 @CharlesB가 제안한 것처럼 원격으로 추가해야합니다. 코드베이스, 여전히 원격으로 추가 할 수는 있지만 전체 분기를 저장소로 가져 가고 싶지 않을 수도 있습니다 ...)


11

다음과 같이 한 줄로 할 수 있습니다. 체리 선택 변경이 필요한 자식 저장소에 있고 분기를 수정했는지 확인하십시오.

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# 

git fetch [브랜치 URL] [브랜치에서 체리 픽으로 선택] && git cherry-pick [커밋 ID]


1
환호, ssh://부분이 필요하지 않았습니다https://
레오

5

예. 리포지토리를 가져온 다음 원격 지점에서 체리 픽을 선택합니다.


1

가정 A당신이 원하는 REPO되어에서 체리 선택, 그리고 B당신이 원하는 것을, 당신은 추가하여이 작업을 수행 할 수 있습니다에 체리 - 선택 </path/to/repo/A/>/.git/objects</path/to/repo/B>/.git/objects/info/alternates. 이 alternates파일이 없으면 작성하십시오 .

이렇게하면 repo B가 repo A의 모든 자식 객체에 액세스하고 체리 선택이 작동합니다.


0

내 상황은 팀이 추진하는 맨손의 레포와 그 옆에 그 복제품이 있다는 것입니다. Makefile 의이 줄은 나에게 올바르게 작동합니다.

git reset --hard
git remote update --prune
git pull --rebase --all
git cherry-pick -n remotes/origin/$(BRANCH)

Bare Repo의 마스터를 최신 상태로 유지함으로써 Bare Repo에 공개 된 제안 된 변경 사항을 체리 픽픽 (catch-pick) 할 수 있습니다. 또한 통합 검토 및 테스트를 위해 여러 개의 브레이 치를 체리 픽킹하는 (더 복잡한) 방법이 있습니다.

"아무것도 알지 못한다"는 것이 "원격으로 사용할 수 없음"을 의미하는 경우 도움이되지 않지만이 워크 플로를 생각해 내기 위해 인터넷 검색을 할 때이 SO 질문이 제기되어 다시 기여할 것이라고 생각했습니다.


-n은 git docs 에 따라 커밋을 의미하지 않으며 커밋 하기 전에 변경 사항을 확인하는 것이 매우 중요합니다.
canbax

0

주어진 커밋에 도달 할 때까지 주어진 파일에 대해 여러 커밋을 체리 피킹하려면 다음을 사용하십시오.

# Directory from which to cherry-pick
GIT_DIR=...
# Pick changes only for this file
FILE_PATH=...
# Apply changes from this commit
FIST_COMMIT=master
# Apply changes until you reach this commit
LAST_COMMIT=...

for sha in $(git --git-dir=$GIT_DIR log --reverse --topo-order --format=%H $LAST_COMMIT_SHA..master -- $FILE_PATH ) ; do 
  git --git-dir=$GIT_DIR  format-patch -k -1 --stdout $sha -- $FILE_PATH | 
    git am -3 -k
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.