Git 커밋에서 파일 제거


1612

나는 Git을 사용하고 있으며 사용하는 파일이 거의 없다.

git commit -a

나중에 파일이 커밋에 실수로 추가 된 것을 발견했습니다.

마지막 커밋에서 파일을 어떻게 제거합니까?


2
이 링크는 귀하의 질문에 완벽합니다 : stackoverflow.com/questions/307828/…
b3h3m0th

@CharlesB : 그렇습니다, 이것은 나의 마지막 커밋입니다
Lolly

8
커밋을 서버에 푸시 했습니까?
Paritosh Singh

4
난 그냥 사용 :git reset filepath
felipekm

답변:


3088

실수로 커밋 된 파일을 변경 사항을 취소하지 않고 이전 커밋에서 스테이징 영역으로 다시 이동시키는 문제이기 때문에 여기에 다른 답변이 잘못되었다고 생각합니다. 이것은 Paritosh Singh이 제안한 것처럼 수행 할 수 있습니다.

git reset --soft HEAD^ 

또는

git reset --soft HEAD~1

그런 다음 원하지 않는 파일을 재설정하여 커밋에서 제외하십시오.

git reset HEAD path/to/unwanted_file

이제 다시 커밋하면 동일한 커밋 메시지를 다시 사용할 수도 있습니다.

git commit -c ORIG_HEAD  

86
고마워 이미 (잘못 된) 커밋을 이미 푸시하고 이제 git pushrepo까지 수정 하려고 하면 불평 할 것 Updates were rejected because the tip of your current branch is behind its remote counterpart.입니다. 푸시하려는 경우 (예 : 포크) -f옵션을 사용 하여 푸시를 강제 할 수 있습니다 ( 예 :) git push origin master -f. (다른 사람들이 가져 오는 업스트림 저장소에는이 작업을 수행하지 마십시오)
andy magoon

57
git reset --soft HEAD^가장 일반적인 실행 취소 작업입니다
funroll

2
@PabloFernandez는 무엇보다도 OP가 찾고있는 답변 일 수 있습니다 (또한 몇 달 전에 게시되었습니다). 두 번째로, 찬성표 수에 관계없이 허용되는 답변은 항상 최상위에 있습니다.
MITjanitor

4
모든 답변 맨 위에있는 @PabloFernandez는 답변 순서를 제어 할 수있는 세 개의 탭 ( 활성 , 가장 오래된투표)을 제공 합니다. 내 생각 엔 너의 것이 가장 오래된 것 입니다. 수락 된 답변이 여전히 최상위에 있더라도 투표로 전환하십시오 .이 답변은 두 번째입니다.
ahsteele

15
나는 이것에 대해 많이 알고 있었지만 git reset기존의 커밋에 영향을 줄 수있는 방법을 원했다. 방금 배웠습니다 git commit -C. 나에게있어, 내가 원하는 것은 "새로운 커밋"이라는 또 하나의 단계가있는 정확한 레시피입니다 git commit -C [hash of original HEAD commit from first step].
metamatt

323

주의 ! 이전 커밋에서 파일을 제거하고 디스크에 보관하려면의 juzzlin의 답변을 읽으 십시오 .

이것이 마지막 커밋이고 로컬 및 원격 저장소에서 파일완전히 삭제 하려는 경우 다음을 수행 할 수 있습니다.

  1. 파일을 제거 git rm <file>
  2. 수정 플래그로 커밋 : git commit --amend

amend 플래그는 git에게 다시 커밋하도록 지시하지만 마지막 커밋과 함께이 커밋을 "병합"합니다 (두 가지를 병합한다는 의미는 아님).

주석에서 언급했듯이 git rm여기서 사용하는 것은 rm명령 자체를 사용하는 것과 같습니다 !


120
당신은 또한 git rm --cached디스크에 파일을 유지하는 데 사용할 수 있습니다
Arkadiy Kukarkin

14
이 답변을 탐색하는 사람들에게 경고 : 커밋 목록에서 파일을 제거하지 말고 파일을 삭제하십시오 (사라진 것처럼!).
Scott Biggs

8
다른 사람의 말에 추가하려면 (그리고 쉽게 당신이 정말로 원하는하지 않는 한이 작업을 수행하지 기억 할 수 있도록) : 명령이 되는 일을 자체 않습니다! rmgitrm
yo '

@CharlesB보다 가시성을 높이기 위해 Arkadiy Kukarkin의 의견에 대한 메모를 답변에 추가해 주시겠습니까?
mopo922

2
파일이 여전히 복원 할 수 있습니다, 경우에 당신은 당신의 마음을 변경의 전에 커밋 git commit --amend아직 거기와와 예를 들어 찾을 수 있습니다 git reflog. 따라서 다른 의견에서 제안한 것처럼 나쁘지 않습니다.
Steohan

165

기존 답변은 마지막 커밋 에서 원하지 않는 파일을 제거하는 것에 관한 것 입니다.

오래된 파일에서 원하지 않는 파일을 제거하려면 커밋 (푸시조차도) 새 커밋을 생성하지 않으려는 경우 작업으로 인해 필요하지 않습니다.

1.

파일이 준수 할 커밋을 찾으십시오.

git checkout <commit_id> <path_to_file>

많은 파일을 제거하려는 경우이 작업을 여러 번 수행 할 수 있습니다.

2.

git commit -am "remove unwanted files"

삼.

파일이 잘못 추가 된 커밋의 commit_id를 찾으십시오. 여기에서 "35c23c2"라고하겠습니다.

git rebase 35c23c2~1 -i  // notice: "~1" is necessary

이 명령은 설정에 따라 편집기를 엽니 다. 기본 설정은 vim입니다.

"원치 않는 파일 제거"마지막 커밋을 잘못된 커밋의 다음 줄 (이 경우 "35c23c2")로 이동하고 명령을 fixup다음 과 같이 설정하십시오 .

pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files

파일을 저장 한 후에는 양호해야합니다.

끝내기 위해 :

git push -f

불행히도 충돌이 발생하면 수동으로 해결해야합니다.


2
나노로 이것을하는 것은 훌륭합니다! Ctrl + K, Ctrl + U, 'f', Ctrl + X, 'y'및 voila를 입력하십시오!
sequielo

6
파일 시스템이 아닌 repo에서 파일을 실제로 이전 버전으로 되 돌리는 대신 파일을 제거하려면 1 단계 대신 수행하십시오 git rm --cached <file(s)>.
waldyrious

2
대화식 리소스 파일에서 커밋을 마음대로 움직일 수 있습니까?
Dan Rosenstark

2
당신은 완전히 할 수는 있지만 갈등을 일으킬 수도 있습니다.
Brian

6
이 프로세스 --fixup=35c23c2git commit명령 에 추가 하여 조금 더 쉽게 만들 수 있습니다 . 이렇게하면 커밋이 필수 커밋 수정으로 자동 설정되므로 리베이스에서 커밋을 지정할 필요가 없습니다. 또한 명령에 추가 --autosquash하면 git rebasegit이 자동으로 커밋을 올바른 위치로 이동하므로 대화식 리베이스에서 아무것도 할 필요가 없습니다. 결과를 저장하면됩니다 -i. 어쨌든 그것을 사용하여 모든 것이 예상대로 보이도록하고 싶습니다.)
거스

144

수락 된 답변에서 알 수 있듯이 전체 커밋을 재설정하여이 작업을 수행 할 수 있습니다. 그러나 이것은 다소 무거운 접근 방식입니다.
더 확실한 방법은 커밋을 유지하고 변경된 파일을 간단히 제거하는 것입니다.

git reset HEAD^ -- path/to/file
git commit --amend --no-edit

git reset그 이전 있다는 파일을 커밋 인덱스에 무대됩니다. 작업 디렉토리의 파일은 변경되지 않습니다.
그러면 git commit인덱스가 커밋되고 현재 커밋으로 스쿼시됩니다.

기본적으로 이전 커밋에 있던 파일 버전을 가져 와서 현재 커밋에 추가합니다. 결과적으로 순 변경이 없으므로 파일이 커밋에서 효과적으로 제거됩니다.


5
이것은 전체 커밋을 점검하지 않고 단일 파일 만 제거하면 훨씬 더 나은 대답입니다.
nimish

이것은이 답변과 정확히 동일합니다 : D stackoverflow.com/a/27340569/1623984
ThatsAMorais

@ThatsAMorais 실제로 :-). 이 질문이 다른 질문과 병합되었는지 궁금해서 그 질문을 보지 못했습니다. 아니면 맹인일 수도 있습니다. 어느 쪽이든, 나는 그것이 더 인기있는 것처럼 보입니다 (사람들은 짧고 직접적인 대답을 선호 할 수도 있습니다).
Patrick

꼭 맡겨주세요! :) 우리는 올바른 아이디어를 분명히 가지고 있었고, 그 목적은 돕는 것입니다. 병합은 좋은 이론이라고 생각합니다.
ThatsAMorais

이미 github의 브랜치로 푸시 한 경우 어떻게합니까? 이 수정을 수행 한 후 푸시하려고했는데 "현재 지점의 끝이 힌트 뒤에 있기 때문에 업데이트가 거부되었습니다. 원격 상대방"이라는 메시지가 나타납니다.
Ollie Williams

41

서버에서 변경 사항을 푸시하지 않은 경우 사용할 수 있습니다

git reset --soft HEAD~1

모든 변경 사항을 재설정하고 하나의 커밋으로 되돌립니다.

변경 사항을 적용한 경우 @CharlesB의 답변에 따라 단계를 수행하십시오.


2
-1 자식 리셋 제거합니다 변경 스테이징 영역에서 파일을 일어, 여기에 변화가 최선을 다하고있다
CharlesB

좋아,하지만 OP가 원하는 것이 아니기 때문에
다운 보트를 유지할 것이다

괜찮아요.하지만 상대방이 이것을 원하지 않는 이유는 무엇입니까? 무엇이 문제입니까?
Paritosh Singh

OP는 마지막 커밋에서 원하지 않는 파일을 제거하기를 원하기 때문에 커밋하기 전에 상태로 재설정합니다. 여전히 커밋을 다시해야합니다.
CharlesB

3
@Aris는 <git diff --cached>를 사용하여 변경 사항을 확인합니다.
Paritosh Singh

37

rm을 사용하여 파일을 제거하면 파일이 삭제됩니다!

항상 제거하지 않고 git에서 커밋을 추가하고 있으므로이 경우 파일을 첫 번째 커밋 이전 상태로 되돌립니다 (파일이 새로운 경우 'rm'삭제 작업 일 수 있음). 다시 커밋하면 파일이 이동합니다.

파일을 이전 상태로 되돌리려면

    git checkout <commit_id> <path_to_file>

또는 원격 HEAD의 상태로 되돌리려면 :

    git checkout origin/master <path_to_file>

그런 다음 커밋을 수정하면 파일이 목록에서 사라지고 디스크에서 삭제되지 않았 음을 알 수 있습니다.


36
git checkout HEAD~ path/to/file
git commit --amend

1
이것은 푸시되지 않은 마지막 커밋을 수정하는 가장 좋은 방법입니다. 한 파일의 변경 사항을 재설정하여 마지막 커밋에서 해당 파일을 효과적으로 제거합니다.
Alex Bravo

이것은 또한 파일을 변경했습니다. 파일에서 로컬 변경 사항을 유지하는 방법은 무엇입니까?
theonlygusti

29

다음은 OP가 요청한 파일의 스테이지를 해제합니다.

git reset HEAD^ /path/to/file

다음과 같은 것을 보게 될 것입니다 ...

커밋 할 변경 사항 : ( "git reset HEAD ..."를 사용하여 스테이지 해제)

수정 : / path / to / file

커밋을 위해 준비되지 않은 변경 사항 : (커밋 될 내용을 업데이트하려면 "git add ..."사용) (작업 디렉토리에서 변경 사항을 무시하려면 "git checkout-..."사용)

수정 : / path / to / file

  • "커밋 변경"은 커밋 이전의 파일의 이전 버전입니다. 파일이 존재하지 않으면 삭제 된 것처럼 보입니다. 이 변경 사항을 커밋하면 브랜치의 파일 변경 사항을 되 돌리는 개정판이 있습니다.
  • "커밋을 위해 준비되지 않은 변경 사항"은 커밋 된 변경 및 파일의 현재 상태입니다.

이 시점에서 다른 버전으로 재설정하는 등 파일에 원하는 모든 작업을 수행 할 수 있습니다.

커밋 할 준비가되면 :

git commit --amend -a

또는 (커밋하지 않으려는 다른 변경 사항이있는 경우 아직 커밋하지 않음)

git commit add /path/to/file
git commit --amend

3
juzzlin의 대답은 훌륭하지만, 단 한 단계 만 취소하고 싶을 때 전체 커밋을 단계 해제하는 것은 과도합니다. 현재 커밋의 파일을 변경하지 않은 경우 커밋에서 전체 커밋을 취소하면 문제가 발생할 수 있습니다.
ThatsAMorais

27

예를 들어 설명해 드리겠습니다.
A, B, C를 3 개의 연속 커밋으로 둡니다. 커밋 B에는 커밋해서는 안되는 파일이 있습니다.

git log  # take A commit_id
git rebase -i "A_commit_ID" # do an interactive rebase
change commit to 'e' in rebase vim # means commit will be edited
git rm unwanted_file
git rebase --continue
git push --force-with-lease <branchName>    

특정 파일이 마지막 또는 이전 커밋에없는 경우 가장 우아한 방법입니다. 나는 그것이 일반적으로 가장 우아한 방법이라고 말합니다. 나는 대화식 리베이스를 좋아합니다.
bvgheluwe '

단일 커밋의 경우 또는 다음 noop으로 변경하십시오.edit [A_commit_ID]e [A_commit_ID]
TamusJRoyce

23

간단하게 시도 할 수 있습니다.

git reset --soft HEAD~1

새로운 커밋을 만듭니다.

그러나 멋진 소프트웨어 "gitkraken"이 있습니다. git으로 작업하기가 쉽습니다.


1
그리고 주목할 사항 :이 후에 git commit --amend는 마지막 커밋에서 파일 제거를 업데이트해야합니다. 그리고 나서, 실제로 제거되었는지 확인할 수 있습니다git log -1 --stat
sdbbs

13
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"

여전히 로컬 파일을 남겨 둡니다. 파일을 로컬로 원하지 않으면 --cached 옵션을 건너 뛸 수 있습니다.

모든 작업이 로컬 지점에있는 경우 나중에 커밋에 파일을 보관해야하며 깨끗한 기록을 유지하는 것처럼 더 간단한 방법은 다음과 같습니다.

git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit --squash <commit_id>
git add <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "brand new file!"
git rebase --interactive <commit_id>^

그러면 더 복잡한 명령을 기억하거나 메시지를 커밋하거나 입력하지 않고도 쉽게 리베이스를 완료 할 수 있습니다.


이것은 나를 위해 작동합니다. 믹스에 파일을 다시 추가하려면 git add -A 또는 git add 만 사용하십시오. 그리고 그들은 돌아왔다.
Alexander Mills

11

git GUI를 사용하면 이전 커밋에서 파일을 간단하게 제거 할 수 있습니다.

이것이 공유 브랜치가 아니며 history를 다시 쓰는 것을 신경 쓰지 않는다면 다음을 실행하십시오.

git gui citool --amend

실수로 커밋 된 파일의 선택을 해제 한 다음 "Commit (커밋)"을 클릭하십시오.

여기에 이미지 설명을 입력하십시오

커밋에서 파일이 제거되지만 disk에 유지됩니다 . 따라서 실수로 파일을 추가 한 후 확인을 취소하면 추적되지 않은 파일 목록에 표시됩니다 (실수로 파일을 수정 한 후 확인을 취소하면 커밋 목록에 대해 변경되지 않은 변경 사항에 표시됨).


2
우분투에서 git gui를sudo apt-get install git-gui
JDiMatteo

감사합니다! .git repo를 포함하는 폴더가 추가되고 모든 일반 제거 명령이 작동하지 않는 문제 (버그?)가 발생했습니다. 그러나 이것은 도움이되었습니다. 그것은 몇 가지 커밋으로, 먼저 git rebase -i HEAD~4편집기를 열고 명령을 실행했습니다. 또 다른 메모 : "Unstaging"은 "Commit"메뉴에서 찾을 수 있습니다.
Johny Skovdal 2016 년

가장 쉬운 솔루션입니다. 기억하는 것이 가장 간단합니다. 그리고 git reset --soft HEAD^--soft arg를 기억하는 것보다 오류가 발생하기 쉽지 않으며, git commit -c ORIG_HEAD--amend 대신에 모든 것을 망칩니다 .
브렌트 파우스트

9

커밋을 유지하려면 (자세한 커밋 메시지를 작성하고 잃고 싶지 않은 경우가 있지만) 커밋에서 파일을 제거하고 리포지토리에서 완전히 제거하지 않으려는 경우 :

git checkout origin/<remote-branch> <filename>
git commit --amend

6

다음 명령을 순서대로 수행하십시오.

//to remove the last commit, but preserve changes  
git reset --soft HEAD~1

//to remove unneded file from the staging area  
git reset HEAD `<your file>` 

//finally make a new commit  
git commit -m 'Your message'

이 단계를 수행하려고 시도했지만이 오류 오류가 표시됩니다. 일부 참조를 'git ...'로 푸시하지 못했습니다. 기록을 잃지 않도록하기 위해, 빠른 전달이 아닌 업데이트가 거부되었습니다. 원격 변경 사항을 병합하십시오 (예 : 다시 밀어 넣기 전에 'git pull') 자세한 내용은 'git push --help'의 '빨리 감기에 대한 참고 사항'섹션을 참조하십시오. (git pull 후 동일한 변경 사항이 있음)
Dezigo

로컬 작업을 수행하는 동안 원격 저장소의 상태가 변경되었음을 의미합니다. 그리고 'git pull'후에는 로컬 변경 사항을 원격 변경 사항과 병합해야합니다. 물론 변경 사항은 그대로 유지해야합니다.
Sergey Onishchenko

즉, @Dezigo 오류가 발생하면 -f 플래그를 추가하여 업데이트를 강제 실행하십시오.
jungledev

5

추가 명령을 실행해야하기 때문에 최고의 답변을 보완하고 싶었습니다.

git reset --soft HEAD^
git checkout origin/master <filepath>

건배!


어서 오십시오. 명령이 실제로 무엇을하는지 설명하면이 대답이 더 나을 것입니다.
Mark Chorley

3

나를 위해 일했지만 여전히 더 나은 해결책이 있어야한다고 생각합니다.

$ git revert <commit_id>
$ git reset HEAD~1 --hard

다른 커밋에서 삭제하려는 변경 사항을 그대로 두십시오.

$ git commit --amend // or stash and rebase to <commit_id> to amend changes

3

git reset --soft HEAD^커밋을 되돌리고 입력 git status하면 수행 할 작업을 알려줍니다.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

2

사실, 더 빠르고 쉬운 방법은 git rebase 대화 모드를 사용하는 것입니다.

git rebase -i head~1  

(또는 머리 ~ 4, 얼마나 가고 싶은지)

그런 다음 'pick'대신 'edit'을 사용하십시오. 나는 '편집'이 얼마나 강력한 지 몰랐습니다.

https://www.youtube.com/watch?v=2dQosJaLN18

도움이 되길 바랍니다.


동영상은 10 분이며 그리 유용하지 않습니다
MolbOrg

2

하나의 파일 만 되돌리려는 로컬 브랜치에서 변경 사항이있는 동일한 문제가 있습니다. 나를 위해 일한 것은-

( 아래의 feature / target_branch 는 특정 파일에 대해 실행 취소하려는 변경 사항을 포함하여 모든 변경 사항이있는 곳입니다)

( origin / feature / target_branch 는 변경 사항을 푸시하려는 원격 지점입니다)

( 기능 / 스테이징 은 하나의 파일에 대한 변경을 제외하고 원하는 모든 변경 사항을 추진할 임시 준비 지점입니다.)

  1. origin / feature / target_branch 에서 로컬 브랜치를 만듭니다 ( feature / staging 이라고 함).

  2. 작동중인 로컬 지점 기능 / target_branch기능 / 스테이지 지점으로 병합

  3. 기능 / 스테이징 을 체크 아웃 한 후 git reset --soft ORIG_HEAD (이제 기능 / 스테이징의 모든 변경 사항은 준비되었지만 커밋되지 않습니다.)

  4. 불필요한 변경으로 이전에 체크인 한 파일을 스테이지 해제

  5. 기능 / 스테이지 의 업스트림 브랜치 를 origin / feature / target_branch로 변경했습니다.

  6. 나머지 단계적 변경 사항을 적용하고 원격 원점 / 기능 / target_branch로 업스트림으로 푸시


1

더 이상 해당 파일이 필요하지 않으면 할 수 있습니다

git rm file
git commit --amend
git push origin branch

1

GitHub를 사용 중이고 아직 커밋을 푸시하지 않은 경우 GitHub Desktop은이 문제를 쉽게 해결합니다.

  1. 저장소-> 가장 최근 커밋 실행 취소를 선택하십시오.
  2. 실수로 추가 한 파일을 선택 취소하십시오. 이전 커밋 메시지는 이미 대화 상자에 있습니다.
  3. 커밋 버튼을 누르십시오!

1

이전 커밋에서 파일을 제거하려면 필터를 사용하십시오.

git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached "file_to_be_removed.dmg"'

이 오류가 표시되면

새 백업을 만들 수 없습니다. 이전 백업이 이미 refs / original /에 존재합니다. -f를 사용하여 백업을 덮어 씁니다.

로컬 리포지토리에서 심판 백업을 제거하십시오.

$ rm -rf .git/refs/original/refs

1

변경 사항을 아직 자식으로 푸시하지 않으면

git reset --soft HEAD~1

모든 변경 사항을 재설정하고 하나의 커밋으로 되돌립니다.

이것이 마지막 커밋이고 로컬 및 원격 저장소에서 파일을 삭제하려면 다음을 시도하십시오.

git rm <file>
 git commit --amend

또는 더 나은 :

먼저 재설정

git reset --soft HEAD~1

원치 않는 파일을 재설정

git reset HEAD path/to/unwanted_file

다시 커밋

git commit -c ORIG_HEAD  

위와 동일하지만 실제로 교차 점검하는 데 도움이 됨
Reshma

0

이것은 파일을 처음에 분기로 푸시 한 비트 버킷 저장소에서 파일을 제거하기 위해 작동합니다.

git checkout origin/develop <path-to-file>
git add <path-to-file>
git commit -m "Message"
git push

0

현재 파일을 다른 폴더에 복사 한 다음 다음과 같이 푸쉬되지 않은 모든 변경 사항을 제거하십시오.

git reset --hard @{u}

그런 다음 다시 복사하십시오. 커밋, 푸시


0

이 명령을 간단히 사용할 수 있습니다.

git restore --staged <file>

0
Here is the step to remove files from Git Commit.

>git reset --soft HEAD^1(either commitid ) -- now files moved to the staging area.
>git rm --cached filename(it will removed the file from staging area)
>git commit -m 'meaningfull message'(Now commit the required files)

-1

현재로서는 어떤 대답도 합리적이지 않습니다. https://github.com/git/git/blob/master/Documentation/SubmittingPatches : 실제 솔루션을 제안해야 할만 큼 충분한 수요가있는 것처럼 들립니다.

git --uncommit <파일 이름>

좋은 것. 히스토리를 수정하고 싶지는 않지만 로컬이고 실수로 로컬 "hack"파일을 추가하고 커밋에서 제거하려는 경우 매우 유용합니다.

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