커밋을 병합하지 않고 변경 내용을 단일 파일로 병합하려면 어떻게합니까?


382

두 개의 분기 (A 및 B)가 있으며 분기 A의 단일 파일을 분기 B의 해당 단일 파일과 병합하려고합니다.


2
이미 여기에서 논의 stackoverflow.com/questions/449541/...
양전자

27
다른 게시물에 대한 대부분의 응답은 파일이 아닌 커밋 을 선택적으로 병합하는 방법에 관한 것 입니다. 선택한 답변이 잘못되었습니다. 질문은 대답하지 않은 채 남아 있습니다.


이 답은 바로 IMO입니다. git diff branch_name > patch git apply patch. stackoverflow.com/a/9473543/1091853
blamb

답변:


630

나는 같은 문제를 겪었다. 정확하게 말하면, 나는 두 개의 브랜치 AB동일한 파일을 가지고 있지만 일부 파일에서는 프로그래밍 인터페이스가 다릅니다. 이제 f두 가지의 인터페이스 차이와 무관 한 file의 메소드가 branch B에서 변경되었지만 두 가지 모두에서 변경이 중요합니다. 따라서, 난 그냥 파일을 병합해야 할 f지점을 B파일로 f지점 A.

모든 변경 사항이 분기 A와 모두에 커밋되어 있다고 가정하면 간단한 명령으로 이미 문제가 해결되었습니다 B.

git checkout A

git checkout --patch B f

첫 번째 명령 은 파일의 버전 A을 병합하려는 지점으로 전환 B됩니다 f. 두 번째 명령은 파일을 패치 ffHEADB. 패치의 단일 부분을 수락 / 삭제할 수도 있습니다. 대신에 B당신이 어떤 여기에 커밋을 지정할 수 있습니다, 그럴 필요하지 않습니다 HEAD.

커뮤니티 편집 : 파일 경우 f에이 B에 존재하지 않는 A아직 다음 생략 --patch옵션을 선택합니다. 그렇지 않으면 "변경 사항 없음"이 표시됩니다. 메시지.


10
파일을 업데이트하려는 경우에만 작동합니다. 지점 B에서 지점 A로 새 파일을 추가하려면 어떻게합니까?
Umair A.

25
@UmairAshraf --patch 옵션을 제거하여 B에서 A로 새 파일을 추가 할 수 있어야합니다.
bbak

9
흠 ...이 시도하면 "변경 없음"이라는 메시지가 표시되지만 변경 사항이 분명히 있습니다. 좋아, 관련 파일이있는 폴더에 있어야했습니다. 편집 : 이것은 아마도 내가 stackoverflow에서 본 문제에 대해 내가 가장 좋아하는 솔루션 일 수 있습니다 :
-D

2
나는 git checkout --patch B -- f이것을 작동시키기 위해 사용해야 했다.
user545424

8
그냥 당신이있는 경우에 것을 추가해야 할 여러 변화 (심술쟁이) 파일의를 당신이 원하는 모두를 무대에 , 당신은 누르면 a누르는 대신, 대화 형 단계 y마다. 또는 git checkout B -- f대신 명령을 사용하십시오.
Dmitry Gonchar

17

이 상황에서 내가하는 일이 있습니다. 그것은 kludge이지만 그것은 나를 위해 잘 작동합니다.

  1. 작업 지점을 기반으로 다른 지점을 만듭니다.
  2. git pull / git은 복사하려는 파일이 포함 된 수정본 (SHA1)을 병합합니다. 따라서 모든 변경 사항이 병합되지만이 분기 만 사용하여 하나의 파일을 가져옵니다.
  3. 충돌 등을 수정하여 파일을 조사하십시오.
  4. 당신의 작업 지점을 체크 아웃
  5. 병합에서 커밋 된 파일을 체크 아웃하십시오.
  6. 커밋하십시오.

패치를 시도했는데 상황이 너무 추했습니다. 요약하자면 다음과 같습니다.

워킹 브랜치 : A 실험 브랜치 : B (폴더로 바꾸고 싶은 변경 사항이있는 file.txt를 포함합니다.)

git checkout A

A를 기반으로 새 지점을 만듭니다.

git checkout -b tempAB

B를 tempAB에 병합

git merge B

병합의 sha1 해시를 복사하십시오.

git log

commit 8dad944210dfb901695975886737dc35614fa94e
Merge: ea3aec1 0f76e61
Author: matthewe <matthewe@matthewe.com>
Date:   Wed Oct 3 15:13:24 2012 -0700

Merge branch 'B' into tempAB

작업 지점을 확인하십시오.

git checkout A

고정 파일을 확인하십시오.

git checkout 7e65b5a52e5f8b1979d75dffbbe4f7ee7dad5017 file.txt

그리고 거기에 있어야합니다. 결과를 커밋하십시오.


3
하나의 파일을 병합하기 위해이 모든 작업을 수행해야합니까? 파일을 복사하여 다른 브랜치에 붙여 넣기가 더 쉬울
Robin

1
병합하면 분기 A와 B가 다른 파일의 변경 내용이 유지되므로 @Robin이 아닐 수 있습니다. 파일을 복사하면 작업 분기 A와 B에서 가져 오려는 항목 간의 추가 차이점을 덮어 씁니다. 해당 항목 / 편집 예를 들어, 용의자 AB다른 방법으로 시작하여 다른 것으로 시작했습니다. 복사는 이러한 차이점을 극복합니다.
blamb

13

이것은 git의 내부 difftool을 사용합니다. 어쩌면 조금만 노력해도되지만.

#First checkout the branch you want to merge into
git checkout <branch_to_merge_into>

#Then checkout the file from the branch you want to merge from
git checkout <branch_to_merge_from> -- <file> 

#Then you have to unstage that file to be able to use difftool
git reset HEAD <file> 

#Now use difftool to chose which lines to keep. Click on the mergebutton in difftool
git difftool

#Save the file in difftool and you should be done.

1
--(빈 인수 레이블) 사용을 명확히하기 위해 git checkout docs : ARGUMENT DISAMBIGUATION : " git checkout -- <pathspec>이 경로를 색인 밖으로 체크 아웃 하려면 사용 하십시오." 같은 이름으로 분기와 파일 / 경로를 모두 가질 수 있기 때문입니다. 이 경우 분기 또는 경로가 둘 다있을 때 분기 또는 경로를 체크 아웃 해야하는지 묻지 않고 git은 기본적으로 분기를 체크 아웃하도록 선택합니다. 그러나 계속 진행하면 --git은 대신 파일 / 경로를 체크 아웃합니다.
SherylHohman

8

이 방법이 간단하고 유용하다는 것을 알았습니다. 다른 지점에서 특정 파일을 "병합"하는 방법

결과적으로 우리는 너무 열심히 노력하고 있습니다. 우리의 좋은 친구 git checkout은 작업에 적합한 도구입니다.

git checkout source_branch <paths>...

git checkout에 기능 분기 A의 이름과 마스터 분기에 추가하려는 특정 파일의 경로를 제공 할 수 있습니다.

더 많은 이해를 위해 전체 기사를 읽으십시오


2
이것은 파일을 덮어
Alex G

당신을 위해, 그것은 당신이하는 일과 달성하려는 일에 달려 있습니다. 여기의 아이디어는 분기 B가 A 포크이며 B에서 4 개의 파일을 수정하지만 B에서 A로 2 만 병합하려는 경우입니다. 일반 병합은 4를 모두 병합하므로 여기에서 선택할 수 있습니다. B에는 본질적으로 새로운 파일이 포함되어 있기 때문에 재정의 된 것처럼 보일 수 있습니다. 몇 가지 증거를 통해 경험을 뒷받침해야합니다.
Pawel Cioch

덮어 쓰기에 동의합니다. -p그 명령 에서 옵션을 사용했다고 생각합니다 . 그런 다음 패치 변경 이전에 체크 아웃 한 지점에서 이전에 분기 한 워크 트리 파일의 모든 부분을 불행히도 덮어 씁니다.
blamb

글쎄, 아이디어는 2009 년부터 git의 새 버전이 다르게 동작하고 -p 또는 다른 것이 필요하지만 게시 할 때 다시 작동했지만 다시는 파일이 재정의되는 것처럼 신경 쓰지 않았습니다. 최신 버전은 내가 필요한 것입니다
Pawel Cioch


3

다음 명령은 (1) 올바른 분기의 파일을 마스터 (2)와 비교하여 적용 할 수정 사항을 대화식으로 묻습니다.

git checkout-패치 마스터


0

편집 내용이 거부되었으므로 여기에서 원격 지점의 병합 변경 사항을 처리하는 방법을 첨부하고 있습니다.

잘못된 병합 후이 작업을 수행해야하는 경우 다음과 같이 할 수 있습니다.

# If you did a git pull and it broke something, do this first
# Find the one before the merge, copy the SHA1
git reflog
git reset --hard <sha1>

# Get remote updates but DONT auto merge it
git fetch github 

# Checkout to your mainline so your branch is correct.
git checkout develop 

# Make a new branch where you'll be applying matches
git checkout -b manual-merge-github-develop

# Apply your patches
git checkout --patch github/develop path/to/file
...

# Merge changes back in
git checkout develop
git merge manual-merge-github-develop # optionally add --no-ff

# You'll probably have to
git push -f # make sure you know what you're doing.

0

B가 현재 분기라고 가정합니다.

$ git diff A <file-path> > patch.tmp
$ git apply patch.tmp -R

로컬 파일에만 변경 사항이 적용됩니다. 나중에 커밋해야합니다.


나를 위해 이것은error: <file-path>: already exists in working directory
kontur를

현재 디렉토리에 특정 파일 또는 파일 경로가 있어야합니다. 사용 중git diff Branch_A <file-path, filename> -- hash_commit > file_name.temp
R.Chatsiri

0

이전 버전의 파일을 체크 아웃하여 병합하여 다른 이름으로 저장 한 다음 두 파일에서 병합 도구를 실행하십시오.

예.

git show B:src/common/store.ts > /tmp/store.ts (여기서 B는 지점 이름 / 커밋 / 태그입니다)

meld src/common/store.ts /tmp/store.ts


0

나는 그것을 할 것이다

git format-patch branch_old..branch_new file

파일에 대한 패치가 생성됩니다.

대상 branch_old에 패치 적용

git am blahblah.patch


안전을 위해 패치를 쉽게 살펴볼 수 있습니까?
XavierStuvw
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.