커밋의 파일 변경 사항 되돌리기


답변:


222

내가 본 가장 깨끗한 방법은 여기에 설명되어 있습니다.

git show some_commit_sha1 -- some_file.c | git apply -R

VonC의 응답 git show과 유사하지만 및 git apply.


10
잘하셨습니다. 스크립트 솔루션은 이것에 대해 과잉입니다. 왜 git revert sha-1 filename이 없을 수 있습니까?
Mark Edington 2014

16
이것은 나의 Mac에서 작동하지만, (Cygwin에서 아래) 윈도우에 나와 있습니다 :fatal: unrecognized input
게달 Mhaswade

1
@MerhawiFissehaye : 나는 git checkout이 커밋 상태로 돌아 가기 위해 변경 사항을 다시 되돌릴 것이라고 생각합니다. 나는 'git add filename; git commit --amend '는 커밋에서 파일을 제거합니다.
ViFI

3
팁으로, -3패치가 실패 할 때 git apply for three-way merge에 플래그 를 추가해야 합니다. 왜냐하면 저는 보통 시간을 거슬러 올라가서 변경 사항을 수정하기 때문입니다.
angularsen

2
대부분의 사람들에게 분명 할 수도 있지만 파일 경로some_file.c포함해야 합니다. 그렇지 않으면 아무 것도 자동으로 패치하지 않습니다. :)
Warpling

35

커밋 기록을 변경해도 좋다고 가정하면 다음은 이전 커밋에서 단일 파일의 변경 사항을 되 돌리는 워크 플로입니다.

예를 들어 badfile.txtcommit 에서 1 개 파일 ( )의 변경 사항을 되돌리려 고합니다 aaa222.

aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit

기본 커밋을 기반으로 문제 커밋을 수정하고 계속하십시오.

1) 대화 형 리베이스 시작 :

git rebase -i aaa111

2) 문제를 마크 변경하여 편집기에서 편집 커밋 picke(편집 용) :

e aaa222
pick aaa333

3) 변경 사항을 잘못된 파일로 되돌립니다.

git show -- badfile.txt | git apply -R

4) 변경 사항 추가 및 커밋 수정 :

git add badfile.txt
git commit --amend

5) 리베이스 완료 :

git rebase --continue

이것은 git 히스토리를 편집 할 수 있다고 가정한다는 점을 지적하고 싶습니다. 위의 일부 답변은 기록을 편집하지 않고 특정 변경 사항을 되 돌리는 새로운 커밋을 생성하며 항상 가능하거나 허용되지는 않습니다.
angularsen

환상적입니다. 이것이 바로 제가 찾던 것입니다. 나는 이미이 아이디어를 가지고 있었지만 대화식 리베이스를 수행 할 때 파일 edit이 변경된 것으로 표시되지 않는 혼란스러워했습니다 . 그러나이 git show -- badfile.txt | git apply -R필요한 응답 I 준 <3
mraxus

이 git apply -R을 이해하면 해당 파일에 대한 커밋을 제거하여 원래 변경된 상태로 다시 설정합니까?
DaImTo

19

git revert 커밋 내의 모든 파일 내용을위한 것입니다.

단일 파일의 경우 다음과 같이 스크립팅 할 수 있습니다 .

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

( smtlaissezfairegit-shell-scripts 유틸리티에서 )


노트 :

현재 수정 사항을 아직 커밋하지 않은 경우 다른 방법이 여기설명되어 있습니다 .

git checkout -- filename

git checkout 파일에 대한 몇 가지 옵션이 있으며 HEAD에서 파일을 수정하고 변경 사항을 덮어 씁니다.


Dropped.on.Caprica댓글에서 언급합니다 .

git에 별칭을 추가하여 git revert-file <hash> <file-loc>특정 파일을 되돌릴 수 있습니다. 이 요점을
참조하십시오 .

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh

여기서 토론에 추가하기 위해 git에 별칭을 추가하여 git revert-file <hash> <file-loc>특정 파일을 되돌릴 수 있습니다. 나는이 대답에서 벗어났습니다 (올바르게 작동하기 위해 몇 가지 편집해야했지만). 내 .gitconfig및 편집 된 스크립트 의 사본은 여기에서 찾을 수 있습니다 . gist.github.com/droppedoncaprica/5b67ec0021371a0ad438
AlbertEngelB 2015

@ Dropped.on.Caprica 좋은 지적입니다. 더 많은 가시성을 위해 답변에 포함했습니다.
VonC 2015

12

--no-commit옵션을 사용하여 git-revert마지막으로 커밋하기 전에 인덱스에서 되 돌리지 않으려는 파일을 제거합니다. 다음은 최근 두 번째 커밋에서 foo.c의 변경 사항 만 쉽게 되 돌리는 방법을 보여주는 예입니다.

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

첫 번째는 git-reset모든 파일을 "언 스테이징"하여 되돌리려는 파일 하나만 다시 추가 할 수 있도록합니다. 마지막 git-reset --hard은 우리가 유지하고 싶지 않은 나머지 파일 되돌림을 제거합니다.


9

훨씬 간단합니다.

git reset HEAD^ path/to/file/to/revert

그때

git commit --amend   

그리고

git push -f

파일이 사라지고 커밋 해시, 메시지 등이 동일합니다.


완전성을 위해 git checkout -- path/to/file/to/revert단계 가 필요 합니까? 그리고 나중에 해시가 똑같다는 것도 사실이 아니죠? 마지막 문장은 "마지막 커밋이 되 돌린 파일의 변경 사항을 포함하지 않는다는 점만 다른 새 커밋으로 대체됩니다."와 같이 더 좋을 수 있습니다.
Kevin

@ 케빈 당신이 아마 맞습니다. 마지막 줄을 다시 확인해야하지만 몇 년 전의 이것을 되돌아 보면 커밋 해시가 변경되지 않으면 놀랄 것입니다.
Forrest

6
git reset HEAD^ path/to/file/to/revert/in/commit

위의 명령은 커밋에서 파일을 가져 오지만 git status.

git checkout path/to/file/to/revert/in/commit

위의 명령은 변경 사항을 되돌립니다 (결과적으로 HEAD와 동일한 파일을 얻음).

git commit

( --amend커밋을 수정하려면 전달하십시오.)

git push

이를 통해 이미 커밋에있는 파일을 제거하고 되돌립니다.

위의 단계는 커밋이 이루어진 지점에서 따라야합니다.


5

다음 절차를 따를 수 있습니다.

  1. git revert -n <*commit*>( -n모든 변경 사항을 되돌 리지만 커밋하지는 않음)
  2. git add <*filename*> (되돌리고 커밋하려는 파일의 이름)
  3. git commit -m 'reverted message' (되돌릴 메시지 추가)
  4. 커밋 한 후에는 다른 파일 변경 사항을 무시하여 되돌리기 전에 커밋 한 변경 사항으로 파일이 업데이트 된 상태로 유지됩니다.

1

마지막 커밋에서 파일의 변경 사항을 재설정하려면 일반적으로 이것이 사용됩니다. 이것이 가장 간단한 해결책이라고 생각합니다.

파일이 준비 영역에 추가됩니다.

git checkout <prev_commit_hash> -- <path_to_your_file>

도움이되기를 바랍니다 :)

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