git selective 파일에서 로컬 변경 사항을 되돌리기


149

svn repo를 추적하는 git repo에서 단일 파일을 여러 번 편집했습니다.

이제 svn revert와 같은 변경 사항을 되돌리고 싶지만 파일의 일부만 되돌리고 싶습니다.

파일에서 diff를보고 원하지 않는 변경 사항을 버리고 (변경) 원하는 변경 사항을 유지하고 싶습니다.

그만큼

git add -i 

명령에 옵션이있는 것 같지만 아직이 단계를 수행하고 싶지 않습니다.

답변:


91

로 직접 할 수 있습니다 git checkout -p. 아래의 Daniel Stutzbach의 답변을 참조하십시오.


이전 답변 (이전 checkout -p소개) :

다음과 같이 할 수 있습니다 :

git add -i

(보관하려는 덩어리를 선택하십시오)

git commit -m "tmp"

이제 유지하려는 변경 사항 만 커밋하고 나머지는 준비되지 않았습니다.

git reset --hard HEAD

이 시점에서 커밋되지 않은 변경 사항이 삭제되었으므로 계속 커밋하려는 변경 사항이있는 깨끗한 작업 디렉토리가 있습니다.

git reset --mixed HEAD^

이렇게하면 마지막 커밋 ( 'tmp')은 제거되지만 작업 디렉토리의 수정 사항은 스테이지되지 않은 상태로 유지합니다.

편집 : 교체 --soft로는 --mixed, 준비 영역을 청소합니다.


이것은 내가 유지하고 싶은 변경 사항을 적용하지 않습니까? 나는 그 변화를 아직 저지르고 싶지 않다. 음 어쩌면 나는 커밋을 너무 진지하게 받아들이고 있습니다. 어쩌면 지금은 로컬 리포지토리에 있기 때문에 휴식을 취해야 할 것입니다. git reset --soft HEAD ^는 무엇을합니까?
Pradeep

"git reset --soft HEAD ^"는 작업 디렉토리와 색인을 그대로 유지하고 현재 브랜치를 한 커밋으로 이동 시킨다는 의미에서 커밋을 취소합니다.
Jakub Narębski

감사합니다. Paolo 왜 1로 소프트 리셋을해야합니까? 부분 커밋과 하드 리셋만으로도 일부 변경 사항을 유지하고 다른 변경 사항을 버릴 수 있습니까?
Pradeep

1
아래의 Daniel의 대답은 매우 간단하며 올바른 방법으로 보입니다.
Umang

309

나는 당신이 가장 간단하게 할 수 있다고 믿습니다.

git checkout -p <optional filename(s)>

맨 페이지에서 :

   −p, −−patch
       Interactively select hunks in the difference between the <tree−ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree−ish> was specified, the index).
       This means that you can use git checkout −p to selectively discard
       edits from your current working tree.

1
또한 선택적으로이 작업을 수행하지 않으려면 "git checkout-<file> ..."을 사용하여 변경 사항을 취소 할 수 있습니다.
db42

디렉토리를 다루나요?
bbum

1
변경 사항을 버릴 때 ( "오류 : 패치 실패 <file>", "오류 : <file> 패치는 적용되지 않습니다") 이것은 나에게 많은 실패로 보입니다. 이상하게도 a패치 모드 에서 옵션을 사용하여 전체 파일을 버릴 때 이러한 오류가 발생 하지만 git checkout -- <file>예상대로 작동합니다. 왜 그런지 아는 사람이 있습니까?
chrnola

파일이 이미 패치 된 경우 해당 오류가 몇 번 발생하여 현재 파일의 적용된 패치에서 대화식 패치가 오래되었습니다. 실수로 덩어리를 두 번 버린 경우 소스 트리와 같은 GUI 도구를 사용할 때 발생했습니다. 두 번째로 해당 오류가 발생합니다.
phyatt

3

git diff파일에서 실행 하고 결과 diff를 저장하고 편집하여 변경 사항을 제거 할 수 있습니다 않습니다 후, 저장할 그것을 통해 실행patch -R 남아있는 차이점을 취소 할 수 있습니다.

git diff file.txt> patch.tmp
# 유지하려는 덩어리를 제거하려면 patch.tmp를 편집하십시오.
패치 -R <patch.tmp

패치 파일에 2 개의 덩어리가 있었고 하나를 제거했습니다. 이유가 무엇인지 확실하지 않지만 패치 -R은 계속해서 거부됩니다.
Pradeep

2
다른 주석 git diff에서 전체 파일이 변경된 것으로 표시합니다. 이것은 일반적으로 이전과 다른 줄 끝을 사용하여 파일을 저장했을 때 발생합니다. 또한 patch패치 파일이 거부됩니다. 무슨 일이 있었을 것 같습니까?
Greg Hewgill

네 말이 맞아 patch 명령을 사용할 때마다 줄 끝이 토글됩니다. 나는 창문에 크림 / vim을 사용하고 있습니다. 먼저 이것을 정렬해야합니다.
Pradeep

Windows의 패치 관련 문제를 해결할 수 없습니다. 나는 이것이 효과가 있다고 확신하지만 Paolo의 레시피를 사용하는 것을 선호합니다. 대화식 명령을 좋아하면 git add -i를 사용하여 diff를 사용하십시오.
Pradeep

3

당신이 원하는 것 같습니다

 git revert --no-commit $REVSISON 

그런 다음 사용할 수 있습니다

 git diff --cached

커밋하기 전에 어떤 변경 사항이 있는지 확인하십시오.

순수한 Git 리포지토리를 사용했다면 목표에 따라 대화 형 리베이스 ( git rebase -i)를 사용하여 마음에 들지 않는 커밋으로 돌아가 커밋을 소급하여 편집하여 원하지 않는 변경 사항이 발생하지 않도록 할 수 있습니다. , 그러나 일반적으로 알고있는 경우에만 다시 표시되지 않습니다.


이전 개정판에 대해 언급했듯이 되돌 렸습니다 (정확합니까?). git diff는 전체 파일이 변경된 것으로 표시합니다. 내가 한 편집 내용을 보여 주어야합니까?
Pradeep

1

질문을 다시 읽으면 작업 트리에있는 변경 사항을 되돌리고 싶지만 이전에 커밋 된 변경 사항은 되 돌리지 않지만 다른 답변 중 일부는 내 읽기가 잘못 된 것처럼 들립니다. 당신은 명확히 할 수 있습니까?

변경 사항이 작업 복사본에있는 경우 가장 쉬운 방법은 다음과 같이 변경 내용을 준비하는 것입니다.

git add -i <file>

그런 다음 인덱스 버전을 확인하여 유지하지 않으려는 변경 사항을 버립니다.

git checkout -- <file>

그런 다음 아직 준비하지 않으려면 변경 사항을 취소하십시오.

git reset -- <file>

이 레시피는 선택한 변경 사항을 파일 (또는 지정한 파일)로 되돌리고 임시 커밋을 작성하지 않고 되돌릴 필요가 있습니다.

이전 커밋에서 이루어진 일부 변경 사항 만 선택적으로 적용하려면 먼저 파일을 이전 커밋 된 상태로 재설정 할 수 있습니다.

git reset <commit_before_first_unwanted_change> -- <file>

그런 다음 이전 레시피에 따라 git add -i <file>유지하려는 변경 사항을 스테이징하고, git checkout -- <file>원치 않는 변경 사항을 버리고 변경 사항 git reset -- <file>을 '스테이지 해제'할 수 있습니다.


0

여기 답변에 설명 된 명령 줄 옵션은 파일이 ssh 터미널을 통해 액세스하는 서버에있을 때 편리합니다. 그러나 파일이 로컬 컴퓨터에 있으면 다음 방법을 선호합니다.

netbeans 편집기 (git 지원과 함께 제공)에서 파일을 엽니 다. Netbeans은 행 번호에 빨간색 / 녹색 / 파란색 표시를하여 항목이 삭제 / 추가 / 수정 된 위치를 나타냅니다 (각각).

이 마크를 마우스 오른쪽 버튼으로 클릭하면 해당 변경을 취소 할 수 있습니다. 또한 빨간색과 파란색 표시를 마우스 오른쪽 버튼으로 클릭하면 팝업에서 이전 버전을 볼 수 있습니다.

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