힘내 : "변경되었지만 커밋되지 않은"상태에서 완고하게 멈춘 파일 2 개를 되 돌리는 방법은 무엇입니까?


84

로컬로 변경 한 것으로 추정되는 두 개의 파일이있는 저장소가 있습니다.

그래서 나는 이것에 붙어 있습니다.

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use "git add" and/or "git commit -a")

Doing git diff은 사실이 아닌 것처럼 보이지만 전체 파일 내용이 변경되었다고 말합니다.

흥미롭게도이 파일을 로컬로 변경 한 기억이 없습니다. 이 저장소는 하나의 원격 저장소 (개인, GitHub.com, FWIW)와 함께 사용됩니다.

내가 무엇을 시도하든 이러한 로컬 변경 사항을 삭제할 수 없습니다. 나는 모두를 시도했다 :

$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f

, Git에서 단계 화되지 않은 변경 사항을 어떻게 폐기합니까?에 설명 된 모든 것을 시도했습니다 .게다가. 그러나 2 개의 파일은 "변경되었지만 커밋되지 않은"상태로 남아 있습니다.

도대체 두 개의 파일이 이렇게 멈춰 있고 겉보기에는 "테이블을 되돌릴 수 없음"으로 보이는 이유는 무엇입니까 ??

PS는 이미 시도 것 명령을 보여주는 위의 목록에서, 내가 잘못 쓴 git revert내가 의미하는 경우 git checkout. 미안하고 노력해야한다고 대답 해주신 분들께 감사드립니다 checkout. 나는 그것을 수정하기 위해 질문을 편집했습니다. 나는 이미 시도했다 checkout.


합니까 git diff --ignore-space-change또는 git diff --ignore-all-space출력에 변화를 git diff?
jdd

네! 두 플래그 모두 git diff파일이 동일하다고 말합니다.
Greg Hendershott

2
stackoverflow.com/questions/2016404/…의 중복 가능성이 있습니다. 어쨌든 나는 git config --global core.autocrlf false'true'대신 설정하는 대답이 더 좋습니다 .
Johann

2
대답은 [여기] [1] 저와 다른 많은 사람들에게 효과적이었습니다. [1] : stackoverflow.com/questions/2016404/…
Mike K

2
이는 대소 문자를 구분하지 않는 파일 시스템에서 대소 문자가 다른 동일한 디렉토리에 2 개 이상의 파일이 포함 된 저장소가 체크 아웃 된 경우에도 발생합니다. 문제를 해결하려면 파일 중 하나를 제거하거나 이름을 바꿉니다.
465544

답변:


33

파일의 줄 끝은 무엇입니까? 나는 그들이 CRLF라고 확신합니다. 그렇다면이 가이드를 확인하세요. http://help.github.com/line-endings/

간단히 말해, 커밋시 줄 끝을 LF로 변환하도록 git이 설정되어 있는지 확인한 다음 해당 파일을 커밋해야합니다. 저장소의 파일은 항상 LF 여야하며 체크 아웃 된 파일은 git을 올바르게 설정했다고 가정하고 OS의 기본 파일이어야합니다.


1
감사. 나는 이미 가지고 git config --global core.autocrlf true있고 상대방도 GitHub의 저장소로 밀어 넣습니다.
Greg Hendershott

1
그런 다음 <pre>해당 가이드 의 마지막 블록에 있는 비트를 수행 하여 저장소의 파일을 수정해야합니다.
Tekkub 2011 년

5
줄 끝은 항상 repo에서 LF 여야하고 (특히 다른 사람이 이미 CRLF를 커밋 한 경우) OS가 항상 네이티브 여야한다는 데 동의하지 않습니다 . 내 Windows 편집기 및 환경 (주로 PHP, HTML, CSS 등)은 LF 줄 끝을 완벽하게 처리합니다.
사이먼 이스트

천재적인 대답, 나는 최근에 gitattributes를 사용하여 repo 파일에서 LF를 강제하고 git이 파일을 자동으로 변경하지 않을 것이라고 생각했습니다. 우리는 Windows와 Linux 개발자가 혼합되어 있고 다른 플랫폼의 편집자들이 계속해서 라인 터미네이터를 바꾸었기 때문에 우리를 화나게 만들었습니다.
Oliver Dungey

120

비슷한 문제를 해결하기 위해 몇 시간을 보냈습니다. 체크 아웃 한 원격 지점에서 모든 파일을 삭제하고 git checkout -f다시 실행할 때에도 4 개의 파일이 '변경되었지만 업데이트되지 않음'으로 완고하게 표시되었습니다 (또는이 게시물의 다른 변형)!

이 4 개의 파일은 필요했지만 내가 수정 한 것은 아닙니다. 내 마지막 해결책은 Git이 변경되지 않았다고 설득하는 것입니다. 다음은 모든 체크 아웃 된 파일에 대해 작동하며 '수정 됨'상태를 표시합니다. 실제로 수정 된 파일을 이미 커밋 / 숨겨 놓았는지 확인하십시오! :

git ls-files -m | xargs -i git update-index --assume-unchanged "{}"

그러나 Mac OSX에서는 xargs가 약간 다르게 작동합니다 (주석의 경우 Daniel).

git ls-files -m | xargs -I {} git update-index --assume-unchanged {}

나는 이것을 다음 시간을 위해 자리 표시 자로 추가했지만 다른 사람에게도 도움이되기를 바랍니다.

-알


10
몇 개의 완고한 파일이 있고이 명령을 실행했는데 git status는 이제 변경 사항이 없지만 분기를 변경하려고 할 때 git은 여전히 ​​두 파일에 로컬 변경 사항이 있기 때문에 분기를 변경할 수 없다고 말합니다. 내가 뭘 잘못했는지 확실하지 않지만 문제를 해결하는 대신 문제를 덮은 것처럼 보입니까? 또한 해당 명령을 실행 한 후 파일을 커밋 할 수 없습니다. 나에게 해결책은 그것들을 삭제하고, 커밋하고, 브랜치를 바꾸는 것이었다.
RodH257 2013

5
감사! 나는 내가 찾을 수있는 다른 모든 대답에서 언급 된 모든 트릭을 시도했습니다. Mac에서는 줄을 그대로 사용할 수 없었으며 각 파일에서 git update-index --assume-unchanged <filename>을 실행하면 문제가 해결되었습니다.
Yonatan Karni 2014-06-25

6
Mac의 xargs가 약간 다르게 작동하는 것처럼 보이지만 정확히 필요한 것입니다 (10.10 Yosemite를 실행 중입니다). 이것은 마침내 나를 위해 일했습니다.git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
Daniel

4
: 명령의 효과 되돌리려git ls-files -v|grep '^h' | cut -c3- | xargs -i git update-index --no-assume-unchanged "{}"
마리노스

3
이 솔루션은 문제를 해결하지 않습니다. 숨 깁니다. assume-unchaged@ RodH257의 경우처럼 이후 에 수행 할 수없는 몇 가지 작업이 있습니다 . 나는 명령 좋아하는 경우에 대한 가장 정확한 답을 믿고 git checkout -- file, git stashgit reset --hard HEAD편집 작업은 이미 대한 답변하지 않습니다.gitattributes
마리노스

20

이것은 내 경우에 동일한 문제를 해결하는 방법입니다. open .gitattributes change :

* text=auto

에:

#* text=auto

힌트를 위해 @Simon East에게 감사드립니다.


1
text=auto.gitattributes 에서 설정을 제거하면 저에게 효과적이었습니다. 그런 다음 git reset --hard해당 설정을 다시 넣으면 파일이 더 이상 수정 된 것으로 표시되지 않습니다!
ErikE 2016-08-29

1
text=auto설정에 분명히 뭔가 잘못된 것이 있습니다 . 여러 OS의 커밋을 사용하여 저장소에서 작업하고 있지만 더 많은 문제를 일으키는 원인을 파악하지 못했습니다. 유지하거나 삭제하는 것입니다.
Marinos An

1
예, 특히 git을 사용하면이 설정을 처음 추가 할 때 잘못된 줄 끝이있는 기존 텍스트 파일을 그대로 둘 수 있습니다. 그것은 단지 잘못된 것이며, 당신이 그것을 기억하지 않는다면, 결국 되돌릴 수없는 변화들 중 하나에 부딪 힐 것입니다.
Roman Starkov

12

또 다른 가능성은 차이점 (체크 아웃 명령으로 이러한 파일을 되 돌리지 못하게하는)이 파일 모드 중 하나라는 것입니다. 이것은 나에게 일어난 일입니다. 내 버전의 git에서는 다음을 사용하여 찾을 수 있습니다.

git diff dir1 / foo.aspx

그리고 파일 모드 변경을 보여줍니다. 그래도 되돌릴 수는 없습니다. 그 사용을 위해

git config core.filemode false

또는 추가하여 텍스트 편집기에서 git .config를 변경하십시오.

[핵심]

filemode = false

이렇게하면 다음을 사용할 수 있습니다.

git reset HEAD dir1 / foo.aspx

파일이 사라져야합니다.

(이 모든 것은 어떻게 git ignore mode changes (chmod)? )에 대한 답변에서 얻었습니다.


1
Windows에서 인 경우에, Eyal 님의 진단 / 해결 방법은 첫번째 추측해야한다
AlcubierreDrive

특히 cmd.exe에서 cygwin git을 사용하지 않도록주의하십시오. cmd.exe에서 git을 원하면 msysgit을 설치하십시오.
AlcubierreDrive

이것이 실제로 Windows의 문제인지 확인하기 위해서입니다.
Dejan Marjanović

Windows에서 이것은 문제가 아닙니다 ( core.filemode이미 false로 설정되었습니다). 제 경우에는 수정 / 해결 방법이 Alan Forsyth의 답변 이었습니다.
Venryx

3

하려고 노력하다 로컬 변경 사항 되 돌리십시오 .

git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx

나는 뇌에 "되돌리기"를 가졌고 checkout. 나는 이미 시도했다 checkout. 어쨌든 귀하의 답변에 감사드립니다. 내 원래 질문에 대한 좋은 답변 이었으므로 찬성하겠습니다.
Greg Hendershott 2011-06-13

3

수정 된 것으로 표시되는 일부 팬텀 변경 파일이 있었지만 실제로는 동일했습니다.

이 명령을 실행하면 때때로 작동합니다.
(git의 "스마트"하지만 종종 도움이되지 않는 줄 끝 변환을 끕니다)

git config --local core.autocrlf false

그러나 다른 경우 .gitattributes에는 일부 줄 끝 설정이있는 루트 의 파일 로 인해 autocrlf꺼져 있어도 특정 파일 에 적용하려고 했습니다. 실제로 도움이되지 않았기 때문에을 삭제 .gitattributes하고 커밋했으며 파일이 더 이상 수정 된 것으로 표시되지 않았습니다.


text=auto.gitattributes 에서 설정을 제거하면 저에게 효과적이었습니다. 그런 다음 git reset --hard해당 설정을 다시 넣으면 파일이 더 이상 수정 된 것으로 표시되지 않습니다!
ErikE 2016-08-29

2
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx

나는 뇌에 "되돌리기"를 가졌고 checkout. 나는 이미 시도했다 checkout. 어쨌든 귀하의 답변에 감사드립니다. 내 원래 질문에 대한 좋은 답변 이었으므로 찬성하겠습니다.
Greg Hendershott 2011-06-13

2

또한 문자 대소 문자를 명명하는 디렉토리와 관련된 문제가있을 수 있습니다. 동료 중 일부는 디렉토리 이름을 예를 들어 myHandler 에서 MyHandler로 변경했을 수 있습니다 . 나중에 원래 디렉토리의 일부 파일을 푸시하고 가져 오면 원격 저장소에 2 개의 개별 디렉토리 가 있고 Windows에서는 하나만 가질 수 있으므로 로컬 시스템 에는 하나만있을 것입니다. 그리고 당신은 곤경에 처했습니다.

이 경우인지 확인하려면 원격 저장소가 이중 구조인지 확인하십시오.

이 문제를 해결하려면 리포지토리 외부에있는 상위 디렉터리의 백업 복사본을 만든 다음 상위 디렉터리를 삭제하고 푸시합니다. 당겨서 (삭제 된 것으로 표시된 두 번째 항목이 상태에 표시되어야하는 경우) 다시 밀어 넣습니다. 그런 다음 백업에서 전체 구조를 다시 만들고 변경 사항을 다시 푸시하십시오.


2

문제 를 더 잘 이해하기 위해 문제재현하는 방법에 대한 힌트를 제공하는 것이 도움이 될 것이라고 생각합니다 .

$ git init
$ echo "*.txt -text" > .gitattributes
$ echo -e "hello\r\nworld" > 1.txt
$ git add 1.txt 
$ git commit -m "committed as binary"
$ echo "*.txt text" > .gitattributes
$ echo "change.." >> 1.txt

# Ok let's revert now

$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Oooops, it didn't revert!!


# hm let's diff:

$ git diff
 warning: CRLF will be replaced by LF in 1.txt.
 The file will have its original line endings in your working 
 directory.
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No actual changes. Ahh, let's change the line endings...

$ file 1.txt 
 1.txt: ASCII text, with CRLF line terminators
$ dos2unix 1.txt
 dos2unix: converting file 1.txt to Unix format ...
$ git diff
 git diff 1.txt
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No, it didn't work, file is still considered modified.

# Let's try to revert for once more:
$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Nothing. Let's use a magic command that prints wrongly committed files.

$ git grep -I --files-with-matches --perl-regexp '\r' HEAD

HEAD:1.txt

두번째 방법은 재현 : : 위의 스크립트에서이 줄을 교체
echo "*.txt -text" > .gitattributes

git config core.autocrlf=false
와 같이 라인의 나머지 부분을 계속


위의 모든 내용은 무엇입니까? 텍스트 파일이 있습니다 (일부 상황에서) (예를 들어, CRLF로 커밋 -text에서 .gitattributes/ 또는 core.autocrlf=false).

나중에 동일한 파일을 텍스트 ( -text-> text) 로 처리하려면 다시 커밋해야합니다.
물론 일시적으로 되돌릴 수 있습니다 ( Abu Assar 가 올바르게 답변 한대로 ). 우리의 경우 :

echo "*.txt -text" > .gitattributes
git checkout -- 1.txt
echo "*.txt text" > .gitattributes

대답은 다음과 같습니다. 파일을 변경할 때마다 동일한 문제가 발생하기 때문에 정말 그렇게 하시겠습니까?


기록을 위해 :

저장소에서이 문제를 일으킬 수있는 파일을 확인하려면 다음 명령을 실행하십시오 (git은 --with-libpcre로 컴파일해야 함).

git grep -I --files-with-matches --perl-regexp '\r' HEAD

파일을 커밋함으로써 (텍스트로 처리하고 싶다고 가정하면) 이러한 문제를 해결하기 위해 http://help.github.com/line-endings/ 링크에서 제안 된 작업을 수행하는 것과 동일 합니다. . 그러나을 제거 .git/index하고 수행하는 대신 reset파일을 변경 한 다음 수행 git checkout -- xyz zyf한 다음 커밋 할 수 있습니다.


2

나는 파일이 윈도우에서 변경되었지만 WSL에서 볼 때가 아니라 흥미로운 추가와 함께 동일한 문제가 발생했습니다. 라인 엔딩, 리셋 등을 어지럽히 지 않고 변경할 수 없었습니다.

결국 이 답변 에서 해결책을 찾았습니다 . 다음은 편의를위한 텍스트입니다.


다음 단계를 사용하여이 문제를 해결했습니다.

1) Git의 색인에서 모든 파일을 제거하십시오.

git rm --cached -r .

2) Git 인덱스를 다시 작성하여 모든 새 줄 끝을 선택하십시오.

git reset --hard

솔루션은 git 사이트 https://help.github.com/articles/dealing-with-line-endings/ 에 설명 된 단계의 일부였습니다.



1

이 문제는 git이 대소 문자 차이를 다른 파일로 취급하지만 Windows는이를 동일한 파일로 취급하기 때문에 발생할 수 있습니다. 파일 이름에 대문자 만 변경된 경우 해당 저장소의 모든 Windows 사용자는이 상황에 처하게됩니다.

해결책은 파일 내용이 올바른지 확인한 다음 다시 커밋하는 것입니다. 두 파일의 내용이 다르기 때문에 병합해야했습니다. 그런 다음 당기면 중복 파일을 삭제하여 해결할 수있는 병합 충돌이 발생합니다. 병합 해결을 다시 커밋하면 안정적인 상태로 돌아갑니다.

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