내용을 삭제하지 않고 많은 수의 파일을 스테이지 해제하는 방법


454

실수로 많은 임시 파일을 추가했습니다. git add -A

다음 명령을 사용하여 파일을 스테이지 해제하고 더티 인덱스를 제거했습니다.

git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

위의 명령은에 나열되어 있습니다 git help rm. 그러나 슬프게도 캐시 옵션을 제공했지만 파일이 실행되면 삭제되었습니다. 내용을 잃지 않고 색인을 지우려면 어떻게해야합니까?

이 파이프 작동 방식을 누군가가 설명 할 수 있다면 도움이 될 것입니다.


8
rm -fgit 명령이 아니며 --cached옵션 이 없습니다 . 로컬 파일은 실행하기 전에 삭제 git rm되었으므로 합법적 git rm으로 아무것도 비난 할 수 없다고 생각합니다 .
CB Bailey

8
@sarat는에서 매우 upvoted 대답 정답 변경을 고려하시기 바랍니다 이안 매덕스를 (가)로, git reset --hard이다 정답없는 사실 내용을 삭제합니다. 나처럼 사용자를 혼란스럽게 할 것입니다.
Marco Pashkov

2
마르코가 말한 것처럼 @sarat. 이 페이지에는 많은 트래픽이 발생합니다.
Ross

@MarcoPashkov & Ross 감사합니다. 끝난.
sarat

답변:


986

git reset

지나치게 원하는 "git add"실행을 취소하는 것이 전부라면 :

git reset

변경 사항이 준비되지 않아 원하는대로 다시 추가 할 수 있습니다.


실행하지 마십시오 git reset --hard.

추가 된 파일의 스테이지를 해제 할뿐만 아니라 작업 디렉토리에서 변경 한 내용을 되돌립니다. 작업 디렉토리에 새 파일을 만든 경우 삭제 하지는 않습니다 .


15
나는 당신에게 파인트 이안 빚
DasBooten

1
나는 종종 공연 git checkout -- *도 해야한다는 것을 알게 되었다
Den-Jason

1
많은 노력을 절약했습니다. 고마워
RajnikantDixit

35

당신은 자연 그대로의 REPO가 (또는 HEAD가 설정되어 있지 않은) 경우 [1] 당신은 단순히 수

rm .git/index

물론, 이것은 당신이 한 파일을 다시 추가 할 필요 않은 추가되어야합니다.


[1] 참고 (주석에 설명 된 바와 같이)는 일반적으로 리포지토리가 아주 새로운 경우 ( "원래") 또는 커밋이 수행되지 않은 경우에만 발생합니다. 기술적으로, 체크 아웃 또는 작업 트리가 없을 때마다.

더 명확하게 :)


그러나 생성 된 인덱스 자체를 삭제하는 것과 비슷합니다. 좋은 점은 git을 다시 초기화 할 필요가 없다는 것입니다. 감사!
sarat

안전한 작동입니까? 방금이 작업을 수행하고 (실제로 인덱스를 이동하지 못함) 다른 모든 파일을 삭제하도록 준비했습니다.
inger

@inger "당신은 깨끗한 저장소가 있다면". 당신은 분명히 가지고 있지 않았습니다.
sehe

실제로, 나는 당신이 "원래의 레포"가 무엇을 의미하는지 궁금했습니다. (Google도 운이 좋지 않습니다). 그래서 당신은 실제로 빈 레포를 의미합니까?
inger

1
@inger 동의합니다. 나는 OP 가이 정확한 상황을 겪었다 고 가정해야했습니다. 그는 그것을 지정하지 않지만 그의 설명은 가능성을 남깁니다. 어쨌든, 나는 :( 단지 정보를 공유하고있어, 그리고 투표에 영향을 미칠 수 없습니다 유무는 응답 텍스트에 대한 경고의 단어를 추가, 경우에 그것은 미래에 다른 사람을 도움이됩니다..
sehe

15

git reset HEAD파일을 제거하지 않고 색인을 재설정하는 데 사용하십시오 . 인덱스의 특정 파일 만 재설정 git reset HEAD -- /path/to/file하려면 그렇게 할 수 있습니다 .

쉘에서 파이프 연산자 stdout는 왼쪽의 프로세스를 가져 와서 stdin오른쪽의 프로세스 로 전달합니다 . 그것은이다 본질적으로 동등한 :

$ proc1 > proc1.out
$ proc2 < proc1.out
$ rm proc1.out

그러나 대신 $ proc1 | proc2, 두 번째 프로세스는 첫 번째 프로세스가 데이터를 출력하기 전에 데이터를 가져 오기 시작할 수 있으며 실제 파일은 없습니다.


여러 파일과 함께 사용하는 방법. 나는이 파일들을 전에 커밋 한 적이 없다.
sarat

3
git reset HEAD다른 것을 지정하지 않고 입력 하면 전체 색인이 재설정됩니다. 그런 다음 원하는 파일 만 다시 추가하면됩니다.
Amber

다음과 같은 오류가 발생했습니다. 나는이 물건들을 전에 결코 저지른 적이 없다. $ git reset HEAD fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
sarat

1
git reset없이 바로 시도 하십시오 HEAD.
Amber

나는 이미 다음과 같은 오류로 끝내려고 노력했다. $ git reset fatal: Failed to resolve 'HEAD' as a valid ref.
sarat

9
git stash && git stash pop

2
git stash && git stash pop을 수행하여 숨김이 삭제되도록합니다. '적용'은 숨김을 숨김 목록에 그대로 둡니다.
chitti

8

HEAD가 설정되지 않은 경우 (즉, 아직 커밋이 없지만 .git유지하려는 다른 리포지토리 구성을 이미 설정했기 때문에 날려 버리지 않으려는 경우) 할 수도 있습니다.

git rm -rf --cached .

모든 것을 무대에서 풀어야합니다. 이것은 실제로 sehe의 솔루션과 동일하지만 Git 내부와의 혼잡을 피합니다.


이것은 실제로 Git에게 캐시 된 영역의 모든 것을 삭제하라고 지시합니다.
Visionary Software Solutions

1
캐시는 준비 영역이라고도하는데, 무엇을 받고 있는지 잘 모르겠습니다.
jjlin

sehe에서 rm .git / index는 매우 위험합니다. 새로운 저장소에 대한 메모를 읽으십시오! 이것은 다른 99.999 %의 시간 동안 훨씬 안전합니다. 나는주의 깊게 읽지 않았고 작업 사본에서 rm .git / index를 수행 한 후 작업 사본을 날려 버리고 다시 복제해야했습니다.
phpguru

이 명령을 사용하지 마십시오! 모든 프로젝트를 추적되지 않은 상태 (스테이지되지 않은 상태 포함)로 변경합니다. 이것은 원래 질문에 대한 해결책이 아닙니다. 'git rm'명령을 사용하는 올바른 해결책은 스테이지 해제하려는 파일 만 지정하는 것입니다. git rm -rf --cached <스테이징 해제하려는 파일>.
Monte Cresor

새의 repo있는 경우에만이 명령을 사용해야 없는 커밋과 아직 (이 수단 "HEAD가 설정되지 않은"것입니다)하지만, 그냥 날려 싶지 않아 .git다른 환매 특약 설정을 설정했기 때문에 유지하고 싶다. 이것을 명확히하기 위해 편집했습니다.
jjlin

5

경고 : 커밋되지 않은 작업을 잃고 싶지 않으면 다음 명령을 사용하지 마십시오!

사용법 git reset이 설명되었지만 파이프 명령에 대한 설명도 요청했습니다.

git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached

이 명령 git ls-files은 git이 알고있는 모든 파일을 나열합니다. 이 옵션 -z은에 예상되는 형식으로 특정 형식을 적용한 xargs -0다음이를 호출 rm -f하여 승인 여부를 확인하지 않고 제거합니다.

즉, "git이 알고있는 모든 파일을 나열하고 로컬 사본을 제거하십시오".

그런 다음 git diffgit이 알고있는 다른 버전의 항목 사이의 변경 사항을 보여줍니다. 서로 다른 트리 간 변경, 로컬 복사본과 원격 복사본 간의 차이점 등이 될 수 있습니다.
여기에 사용 된 비 단계적 변경 사항이 표시됩니다. 변경했지만 아직 커밋하지 않은 파일 이 옵션 --name-only은 (전체) 파일 이름 만 원하고 --diff-filter=D삭제 된 파일에만 관심이 있음을 의미합니다. (이봐, 우리는 단지 많은 것들을 삭제하지 않았습니까?) 그러면 xargs -0이전에 보았던 파이프로 파이프되어 호출 git rm --cached됩니다. 이는 그것들을 캐시에서 제거하는 반면, 작업 트리는 단독으로 남겨 두어야합니다. 작업 트리에서 모든 파일을 제거했습니다. 이제 색인에서 제거되었습니다.

다시 말해, 단계적이든 비 단계적이든 모든 변경 사항이 사라지고 작업 트리가 비어있는 것입니다. 외침을하고, 원본 또는 원격에서 파일을 새로 체크 아웃 한 후 작업을 다시 수행하십시오. 이 지옥의 선을 쓴 사디스트를 저주하십시오. 나는 왜 누군가가 이것을하고 싶어하는지 전혀 모른다.


TL; DR : 당신은 모든 것을 호스로 쳤습니다. 다시 시작 git reset하여 지금부터 사용하십시오 .


2

명령 줄 중 첫 번째 줄이 작업 복사본에서 git의 준비 영역에있는 모든 파일을 무조건 삭제 한 것이 두려워요. 두 번째는 추적되었지만 이제 삭제 된 모든 파일의 스테이지를 해제했습니다. 불행히도 이는 해당 파일에 대한 커밋되지 않은 수정 사항이 손실되었음을 의미합니다.

작업 복사본과 인덱스를 마지막 커밋 상태로 되돌리려 면 다음 명령을 신중하게 사용할 수 있습니다 .

git reset --hard

나는 git reset --hard 작업 카피 와 색인 에서 커밋되지 않은 변경을 없애기 때문에 "조심스럽게"말합니다 . 그러나이 상황에서는 마지막 커밋시 상태로 돌아가고 커밋되지 않은 변경 사항이 손실 된 것처럼 보입니다.

업데이트 : 아직 HEAD를 해결할 수 없기 때문에 커밋을 만들지 않았다는 Amber의 답변에 대한 귀하의 의견에서 들리므로 도움이되지 않습니다.

어떻게 그 파이프 작업에 관해서는 : git ls-files -zgit diff --name-only --diff-filter=D -z모두 출력 파일 이름 목록은 바이트로 구분 0. (이것은 줄 바꿈과 달리 0바이트가 유닉스 계열 시스템의 파일 이름에서 발생하지 않기 때문에 유용 합니다.) 프로그램 xargs은 기본적으로 표준 입력에서 행을 가져 와서 끝에 추가하여 표준 입력에서 명령 행을 작성 합니다. 명령 줄 이 -0옵션은 표준 입력이 0바이트 로 구분되어 있다고 말합니다 . xargs표준 입력에서 모든 매개 변수를 사용하기 위해 명령을 여러 번 호출하여 명령 행이 너무 길어지지 않도록하십시오.

간단한 예로, test.txt다음과 같은 내용 의 파일이있는 경우 :

hello
goodbye
hello again

... 그러면 명령 xargs echo whatever < test.txt이 명령 을 호출합니다.

echo whatever hello goodbye hello again

나는 커밋을하지 않았으므로 HEAD를 해결할 수없는 것처럼 말할 것입니다. 그러한 상황에서 우리가하는 일. 파이프를 자세히 설명해 주셔서 감사합니다.
sarat

8
방금 git ignore를 변경하고 많은 파일을 포함하기 위해 git add --all을 수행 한 경우 git reset --hard를 실행하여 스테이지를 해제하지 마십시오. 그들은 삭제 될 것입니다!
Ajoy

5
우와 아 !! 어쩌면 "주의해서" 라는 단어를 강조해야 할 수도 있습니다 . 방금이 세 단어 "git reset --hard"를 보았고 준비되지 않은 모든 파일은 ... fufff !! 지나간!!!!!
Vineeth Chitteti

1

모든 변경 사항을 취소하려면 아래 명령을 사용하십시오.

git reset --soft HEAD

변경 사항을 스테이지 해제하고 작업 디렉토리에서 되돌리려면,

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