git-diff에서 패치 호환 출력을 얻을 수 있습니까?


160

나는 매우 간단한 것을하고 있습니다. 일반 패치 파일을 준비하려고하므로 몇 가지 변경 사항을 다시 적용 할 수 있습니다.

$ git diff > before
$ git diff something_here > save.patch
$ git checkout . 
$ patch < save.patch
$ git diff > after
$ diff before after
$

함께 something_here 거의 작동하지만 파일 이름은 잘하지 않습니다. 옵션이 누락 된 것 같습니다.

실제로는 결제 후 병합을 수행 할 예정이므로 패치가 실패 할 수 있지만 내가 뭘 받고 있는지 알 수 있습니다.

잘못된 질문을하기 위해 여기에서 내 잘못을 편집 하십시오. 실제 질문은 변경 사항을 저장하고 병합하고 가능한 경우 변경 사항을 다시 적용하고 싶습니다. 패치를 사용하여 이러한 종류의 문제를 해결하는 데 익숙해 졌기 때문에 잘못된 방법으로 물어 git diff보았습니다.

Charles Bailey의 의견 에는 정답이 있습니다. 저에게는 git-apply가 올바른 일입니다 (git-stash는 내가 필요로하는 것보다 더 무겁게 보이고 rebasing하고 번들은 확실히 현재 기술 수준을 넘어서는 것입니다.) Charles가 보낸 대답을 받아 들일 것입니다. 댓글을 수락 할 수 없습니다). 모든 제안에 감사드립니다.

6 년 후 편집 이 주제에 익숙한 사람이 알고 있듯이의 어려움을 과대 평가했습니다 git stash. 거의 매일 정도, 나는 다음 순서를 사용합니다 :

$ git stash
$ git merge
$ git stash pop

8
patch보다 구체적으로 사용하고 싶은 이유 가 git apply있습니까?
CB Bailey

3
그럼에도 불구하고 실제로 git stash다른 툴이나 다른 git 툴 보다는 패치가 필요 합니까?
CB Bailey

3
사후 편집, 나는 그것이 git stash당신이하려는 일에 대한 가장 쉬운 해결책 이라고 생각 하지만 작동하는 많은 접근법이 있습니다.
CB Bailey

1
@Malvolio : 사실, 패치를 저장하기 위해 임시 파일 이름을 생각할 필요조차 없습니다.
CB Bailey

4
@Charlse, 때로는 전체 git 저장소가없는 누군가에게 패치를 보내야합니다. 예를 들어를 사용하는 경우 git-svn.
Elazar Leibovich

답변:


139

패치를 사용하려면 a/ b/git이 기본적으로 사용 하는 접두사 를 제거해야합니다 . --no-prefix옵션을 사용 하여이 작업을 수행 할 수 있습니다 (패치 -p옵션을 사용 하여 수행 할 수도 있음 ).

git diff --no-prefix [<other git-diff arguments>]

일반적으로 스트레이트 git diff를 사용하고 출력을 사용하여 피드 하는 것이 더 쉽습니다 git apply.

대부분 텍스트 패치를 사용하지 않으려 고합니다. 일반적으로 하나 이상의 임시 커밋이 rebase와 결합되어 git stash번들이 관리하기가 더 쉽습니다.

귀하의 유스 케이스에는 이것이 stash가장 적절 하다고 생각합니다 .

# save uncommitted changes
git stash

# do a merge or some other operation
git merge some-branch

# re-apply changes, removing stash if successful
# (you may be asked to resolve conflicts).
git stash pop

7
git diff --no-prefix master > diff.patch그리고git checkout master patch -p0 < diff.patch
Natim

1
@Natim 최고의 안전 patch --dry-run < diff.patch을 위해 마지막 명령을 실행하기 전에 사용 하는 것이 좋습니다 .
ᴠɪɴᴄᴇɴᴛ

1
@ ᴠɪɴᴄᴇɴᴛ 그렇게하면 어떤 이점이 있습니까? 우리는 자식을 사용하고 있기 때문에 아무것도 풀지 않을 것입니까?
Natim

1
@Natim 내가 말했듯이, 최고의 안전을 위해 오류가 발생했을 때 아무것도 취소 할 필요가 없습니다. 또한이를 읽고 더 일반적인 유스 케이스에서 patchgit 외부 에서 사용하려고하는 사람들 (에 의해 생성 된 패치 파일 사용 diff)에 대해 생각하고있었습니다.
ᴠɪɴᴄᴇɴᴛ

패치에 파일 을 포함 시키려면 패치에 "git diff --no-prefix --cached" 포함시켜야합니다. 더 좋은 방법이 있을까요?
jamshid

219

그냥 사용 -p1: 당신이 사용해야합니다 -p0--no-prefix그냥 떠날 수 있도록, 어쨌든 케이스 --no-prefix및 사용을 -p1:

$ git diff > save.patch
$ patch -p1 < save.patch

$ git diff --no-prefix > save.patch
$ patch -p0 < save.patch

1
당신이 궁금해하는 경우 왜, 그 사람의 문서는 멋지게 그것을 요약 - 소스 .
tutuDajuju

3
이름 변경에는 작동하지 않습니다. 무시 git diff하는 줄을 출력 patch합니다. git apply갈 길입니다.
hraban

17

git diff에는 파일 경로 앞에 추가 경로 세그먼트가 있습니다. 패치와 함께 -p1을 지정하여 경로에서이 항목을 제거 할 수 있습니다.

patch -p1 < save.patch

10
  1. 현재 HEAD에 대해 현재 디렉토리 (커밋되지 않은 파일 포함)의 diff를 저장합니다.
  2. 그런 다음 save.patch파일을 이진 파일을 포함한 모든 위치로 전송할 수 있습니다 .
  3. 대상 컴퓨터에서 다음을 사용하여 패치를 적용하십시오. git apply <file>

참고 : 현재 준비된 파일도 다릅니다.

$ git diff --binary --staged HEAD > save.patch
$ git reset --hard
$ <transport it>
$ git apply save.patch

하하하 재밌 네요 나는 거의 4 년 전에이 질문을했고, 내가했던 방식이 발전했지만 어제 어떻게해야하는지 물었다면, 나는 당신의 대답을했을 것이고 나는이 질문에 대한 대답으로부터 그것을 얻었을 것입니다. (사실 나는 아마 베어 사용합니다 git diff > save.patchgit checkout .대신 리셋의,하지만 그래 ...
말볼 리오

오 4 년 된 것을 눈치 채지 못했습니다 : P. Btw, 재설정은 작동하는지 보여주기위한 것입니다. 또한 git apply상태와 관련된 diff를 사용 하거나 만드는 사람 과 마지막 커밋에 대한 포인터를 볼 수있는 사람은 없습니다. 다만 이렇게는 git diff전혀 아무 짓도하지 않은
마테이

그래, 이제 내가 어떻게 알았는지 궁금해 git apply. 가진 것은 git diff사용에서 IS (내 생각) git reset- 관계를 REPO, 인덱스 및 작업 영역 사이에이 문제입니다.
Malvolio

8

임시 패치 파일 생성을 피하는 유용한 방법 :

git diff | patch -p1 -d [dst-dir]

정확히 내가 원하는 것. 스 태쉬와 완벽하게 작동합니다! git stash show -p stash@{3} | patch -p1 -d [dst-dir]
dtmland
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.