Git:「変更されたがコミットされていない」で頑固にスタックしている2つのファイルを元に戻すにはどうすればよいですか?


84

ローカルで変更したと思われる2つのファイルがあるリポジトリがあります。

だから私はこれで立ち往生しています:

$ 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")

Doinggit diffは、ファイルの内容全体が変更されたと言っていますが、目で見てみると正しくないように見えます(diffでは見落とされているように見える一般的な行範囲があるようです)。

興味深いことに、これらのファイルをローカルで変更したことを覚えていません。このリポジトリは、1つのリモートリポジトリ(プライベート、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つのファイルは「変更されたがコミットされていない」としてスタックしたままです。

一体何が原因で2つのファイルがこのようにスタックし、一見「テーブルを元に戻さない」のでしょうか?

PS私がすでに試したコマンドを示している上記のリストでgit revert、私が意図しgit checkoutたときに誤って書いた。申し訳ありませんが、試してみるべきだと答えてくれた皆さんに感謝しますcheckout。質問を編集して修正しました。私は間違いなくすでに試しましたcheckout


git diff --ignore-space-changegit diff --ignore-all-spaceの出力の違いを作りますかgit diff
jdd 2011年

@jermiahdはい!どちらのフラグでもgit diff、ファイルは同一であると言います。
グレッグヘンダーショット2011年

2
stackoverflow.com/questions/2016404/…の重複の可能性。とにかくそこで受け入れられた答えが好きです。それはgit config --global core.autocrlf false「true」の代わりに設定することです。
ヨハン

2
[ここ] [1]の答えは私や他の多くの人に役立ちました。[1]:stackoverflow.com/questions/2016404/…–
Mike K

2
これは、大文字と小文字を区別しないファイルシステムで、同じディレクトリに大文字と小文字が異なる2つ以上のファイルを含むリポジトリがチェックアウトされている場合にも発生します。問題を解決するには、ファイルの1つを削除するか名前を変更します。
465544 2016年

回答:


33

ファイルの行末は何ですか?私は彼らがCRLFだと確信しています。もしそうなら、このガイドをチェックしてください:http//help.github.com/line-endings/

つまり、コミット時に行末をLFに変換するようにgitが設定されていることを確認してから、それらのファイルをコミットする必要があります。gitを正しく設定していると仮定すると、リポジトリ内のファイルは常にLFであり、チェックアウトされるファイルはOSのネイティブである必要があります。


1
ありがとう。私はすでに持っgit config --global core.autocrlf trueているので、相手もGitHubのリポジトリにプッシュしています。
グレッグヘンダーショット2011年

1
次に<pre>、そのガイドの最後のブロックのビットを実行して、リポジトリ内のファイルを修正する必要があります。
tekkub 2011年

5
私は、行末が常にリポジトリ内のLFである必要あり(特に他の誰かがすでにCRLFをコミットしている場合)、OSが常にネイティブである必要があることに同意しません。私のWindowsエディターと環境(主にPHP、HTML、CSSなど)は、LF行末に完全に対応しています。
サイモンイースト

天才的な答えです。最近、gitattributesを使用してリポジトリファイルのLFを強制し、gitがファイルを自動変更することを期待していなかったことを忘れていました。WindowsとLinuxの開発者が混在しており、さまざまなプラットフォームの編集者がラインターミネーターを切り替え続けていたため、変更が波及した後は、これがすべてなくなるはずでした。
オリバーダンジー2016年

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 {}

次回はこれを自分のプレースホルダーとして追加しましたが、他の人にも役立つことを願っています。

-アル


9
頑固なファイルがいくつかあり、このコマンドを実行すると、git statusは変更されませんが、ブランチを変更しようとすると、これら2つのファイルにローカルの変更があるため、ブランチを変更できないと表示されます。私が何を間違えたかはわかりませんが、問題を修正するのではなく、問題を隠蔽したように見えましたか?また、そのコマンドを実行した後、ファイルをコミットできませんでした。私にとっての解決策は、それらを削除し、ブランチをコミットして交換することでした。
rodH257 2013年

5
ありがとう!私は見つけることができる他のすべての答えに記載されているすべてのトリックを試しました-どれもうまくいきませんでした。Macではこの行をそのまま使用できませんでした。各ファイルでgitupdate-index --assume-unchanged <filename>を実行するだけで、問題は解決しました。
ヨナタンカルニ2014年

2
このファイルのローカル変更を絶対にコミットしないようにする場合は、「-assume-unchanged」オプションを使用する必要はありませんか?テンプレートWebサイトの構成ファイルをチェックアウトし、リポジトリに保存してはならない機密情報で更新するときのように?
マキシムロッシーニ

6
これはまさに私が必要としていたものですが、Macのxargsの動作は少し異なるようです(私は10.10 Yosemiteを実行しています)。これは最終的に私のために働いた:git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
ダニエル

3
コマンドの効果を元に戻すには:git ls-files -v|grep '^h' | cut -c3- | xargs -i git update-index --no-assume-unchanged "{}"
Marinos

20

これは私が私の場合に同じ問題を修正した方法です:open .gitattributes change:

* text=auto

に:

#* text=auto

ヒントをくれた@SimonEastのおかげで、保存して閉じてから、元に戻すかリセットします


1
text=auto.gitattributesの設定を削除するとうまくいき、その後git reset --hard、その設定を元に戻すと、ファイルが変更されたものとして表示されなくなりました。
ErikE 2016

1
このtext=auto設定には明らかに問題があります。私は複数のOSからのコミットを使用してリポジトリで作業していますが、それを維持するか削除するかなど、さらに問題が発生する原因がまだわかりません。
マリノス

1
@MarinosAnはい、具体的には、gitを使用すると、この設定を最初に追加したときに、既存のテキストファイルの行末を間違ったままにすることができます。それは間違っており、自分でそれを行うことを覚えていない限り、最終的にはこれらの元に戻せない変更の1つに遭遇します。
ローマンスターコフ2017年

12

もう1つの可能性は、違い(checkoutコマンドでこれらのファイルを元に戻すことができない)がファイルモードの1つであるということです。これが私に起こったことです。私のバージョンのgitでは、次を使用してこれを見つけることができます

git diff dir1 / foo.aspx

また、ファイルモードの変更が表示されます。ただし、それでも元に戻すことはできません。そのためにはどちらか

git config core.filemode false

または、テキストエディタでgit.configを追加して変更します

[芯]

filemode = false

これを行った後、あなたは使用することができます

git reset HEAD dir1 / foo.aspx

ファイルが消えるはずです。

(これはすべて、gitにモード変更を無視させる方法(chmod)への回答から得ましたか?


1
Windowsを使用している場合は、Eyalの診断/解決策を最初に推測する必要があります
AlcubierreDrive

cmd.exeのcygwingitを使用しないように特に注意してください。cmd.exeでgitが必要な場合は、msysgitをインストールします。
AlcubierreDrive

これが実際にWindowsの問題であったことを確認するためだけに。
デヤンMarjanović

Windowsの私にとって、これは問題ではありませんでした(core.filemodeすでにfalseに設定されていました)。私の場合、修正/回避策はAlanForsythの回答にあるものでした。
Venryx

3

ローカルの変更元に戻してみてください:

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

私は脳に「元に戻す」ことがあり、書くつもりcheckoutでした。私はすでに試しましたcheckout。とにかく答えてくれてありがとう。それは私の最初の質問に対する良い答えだったので、私は賛成します。
グレッグヘンダーショット2011年

3

変更されたものとして表示されていたが、実際には同一であるいくつかの幻の変更されたファイルがありました。

このコマンドを実行すると、機能する場合があります:(
gitの「スマート」であるが、多くの場合役に立たない行末変換をオフにします)

git config --local core.autocrlf false

しかし、別のケース.gitattributesでは、ルート内のファイルに行末設定があり、autocrlfオフになっている場合でも特定のファイルに適用しようとしていたことが原因であることがわかりました。それは実際には役に立たなかったので、削除.gitattributesしてコミットすると、ファイルが変更されたものとして表示されなくなりました。


text=auto.gitattributesの設定を削除するとうまくいき、その後git reset --hard、その設定を元に戻すと、ファイルが変更されたものとして表示されなくなりました。
ErikE 2016


2

また、大文字と小文字を命名するディレクトリに関連する問題が発生した可能性があります。同僚の中には、ディレクトリの名前をたとえばmyHandlerからMyHandlerに変更した可能性があります。後で元のディレクトリのファイルの一部をプッシュおよびプルした場合、リモートリポジトリには2つの個別のディレクトリがあり、ローカルマシンには1つしかありません。これは、Windowsでは1つしか持つことができないためです。そして、あなたは困っています。

その場合を確認するには、リモートリポジトリが二重構造であるかどうかを確認します。

これを修正するには、リポジトリの外部に親ディレクトリのバックアップコピーを作成してから、親ディレクトリを削除してプッシュします。プルして(削除済みとしてマークされた2番目のマークがステータスに表示される場合)、もう一度プッシュします。その後、バックアップから構造全体を再作成し、変更を再度プッシュします。


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

私は同じ問題を抱えていましたが、ファイルがWindowsで変更されたという興味深い追加がありましたが、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ユーザーはこの状況になります。

解決策は、ファイルの内容が正しいことを確認してから、それを再コミットすることです。2つのファイルの内容が異なるため、それらをマージする必要がありました。次にプルすると、重複ファイルを削除することで解決できるマージの競合が発生します。マージ解決を再コミットすると、安定した状態に戻ります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.