Gitコミットからファイルを削除する


1613

私はGitを使用していて、

git commit -a

後で、ファイルが誤ってコミットに追加されたことがわかりました。

最後のコミットからファイルを削除するにはどうすればよいですか?


2
:このリンクは、あなたの質問に最適です stackoverflow.com/questions/307828/...
b3h3m0th

@CharlesB:はい、これが私の最後のコミットです
Lolly

8
コミットをサーバーにプッシュしましたか?
Paritosh Singh 2012

4
:私はちょうどそれを使用して行うgit reset filepath
felipekm

回答:


3090

これは他の答えは間違っていると思います。これは、誤ってコミットされたファイルを以前のコミットからステージング領域に戻し、それらに加えられた変更を取り消さないようにするためです。これは、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 push、修正をレポまで実行しようとすると、文句が表示されますUpdates were rejected because the tip of your current branch is behind its remote counterpart.。あなたがそれらをプッシュしたいことが確かである場合(例えば、それがあなたのフォークである場合)-f、プッシュを強制するオプションを使用することができますgit push origin master -f。(他のユーザーが取得している上流のリポジトリに対してこれを行わないでください)
andy magoon 2013

57
git reset --soft HEAD^私の最も一般的な元に戻す操作です
funroll

2
@PabloFernandez、まず第一に、受け入れられた答えは、OPが探していたものであった可能性があります(また、数か月前に投稿されました)。第二に、賛成票の数に関係なく、受け入れられた回答が常にトップになります。
MITjanitor 2013

4
すべての回答の上部にある@PabloFernandezは、回答の順序を制御できる3つのタブです。アクティブ最古、および投票です。私の推測では、あなたは最古に設定されています。承認された回答がまだトップにある場合でも、投票に切り替えます。この回答は2番目になります。
ahsteele 2013

15
私はこれについてはよく知っていましgit resetたが、「インプレース」の既存のコミットに影響を与える方法を望んでいました。について学んだgit commit -C。だから私にとって、私が欲しいのは、もう1つのステップを含む正確なレシピgit commit -C [hash of original HEAD commit from first step]です。
metamatt 2014年

323

注意!以前のコミットからファイルを削除し、それをディスク保持したいだけの場合は、上記のjuzzlinの答えを読んでください

これが最後のコミットであり、ローカルおよびリモートリポジトリからファイル完全に削除する場合は、次のことができます。

  1. ファイルを削除する git rm <file>
  2. 修正フラグでコミット: git commit --amend

amendフラグはgitに再度コミットするように指示しますが、(2つのブランチをマージする意味ではなく)このコミットを最後のコミットと「マージ」します。

コメントで述べたように、git rmここでの使用はrmコマンド自体の使用と似ています!


120
git rm --cachedファイルをディスクに保存するためにも使用できます
Arkadiy Kukarkin

14
この回答を閲覧する人への警告:コミットリストからファイルを削除するだけでなく、ファイルが削除されたことを確認してください(削除された場合など)。
Scott Biggs

8
他の人の発言に追加するには(そして、本当に望んでいない限り、これを行わないことを覚えやすくするため):コマンドrminは、それ自体行うことです!gitrm
よ '

@CharlesB Arkadiy Kukarkinのコメントからのメモを回答に追加して、より目立つようにできますか?
mopo922 2016

2
気が変わった場合に備えて、ファイルは引き続き復元できることに注意してください。以前のコミットgit commit --amendはまだそこにあり、たとえばで見つけることができますgit reflog。したがって、他のコメントが示唆するほど悪くはありません。
Steohan

165

既存の答えはすべて、最後のコミットから不要なファイルを削除することについて話している。

古いコミットから不要なファイルを削除したい場合(プッシュした場合でも)、新しいコミットを作成したくない場合は、アクションのために不要です。

1。

ファイルに準拠させるコミットを見つけます。

git checkout <commit_id> <path_to_file>

多数のファイルを削除する場合は、これを複数回実行できます。

2。

git commit -am "remove unwanted files"

3。

ファイルが誤って追加されたコミットの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
nanoでこれを行うのは素晴らしいです!Ctrl + K、Ctrl + U、 'f'、Ctrl + X、 'y'、そして出来上がり!
sequielo 2016年

6
単にファイルを以前のバージョンに戻すのではなく、実際にリポジトリから(ファイルシステムではなく)削除したい場合は、ステップ1の代わりに行いますgit rm --cached <file(s)>
16年

2
インタラクティブなリベースファイルの周りにコミットを自由に移動できるのを待っていますか?
Dan Rosenstark

2
完全に可能ですが、競合する可能性があります(またはできない場合もあります)。
ブライアン

6
このプロセスは--fixup=35c23c2git commitコマンドに追加することで少し簡単になります。これにより、必要なコミットのフィックスアップとしてコミットが自動的に設定されるため、リベースで指定する必要はありません。さらに、コマンドに追加する--autosquashgit rebase、gitはコミットを正しい場所に自動的に移動するので、インタラクティブなリベースで何もする必要はありません。結果を保存するだけです(つまり、-iフラグを立てる必要さえありません。とにかく私はそれを使ってすべてが期待どおりに見えることを確認するのが好きです)。
ガス2017年

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ウィリアムズ

41

サーバーに変更をプッシュしていない場合は、使用できます

git reset --soft HEAD~1

すべての変更をリセットし、1つのコミットに戻ります

変更をプッシュした場合は、@ CharlesBが回答した手順に従います。


2
-1 git resetは変更されたファイルをステージング領域から削除します。ここでは変更がコミットされました
CharlesB

OK、しかしOPが望むものではないので、私は自分の投票を続けます:)すみません
CharlesB

私には大丈夫ですが、なぜ対戦相手はこれを望まないのですか。何が問題ですか?
Paritosh Singh 2012

大したことではありませんが、OPは最後のコミットから不要なファイルを削除する必要があるため、コミットする前の状態にリセットされるだけです。それでも、コミットをやり直す必要があります。
CharlesB 2012

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
これは、プッシュされていない最後のコミットを変更するための最良の方法です。これにより、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の答えは素晴らしいですが、1つだけステージングを解除したい場合、コミット全体をステージング解除するには過度です。コミット全体のステージングを解除すると、そのコミットのファイルで現在ステージングされていない変更を失いたくない場合、問題が発生する可能性があります。
ThatsAMorais 2014

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を使用すると、以前のコミットからファイルを簡単に削除できます。

これが共有ブランチではなく、履歴を書き換えても構わないと想定して、次のコマンドを実行します。

git gui citool --amend

誤ってコミットしたファイルのチェックを外して、「コミット」をクリックします。

ここに画像の説明を入力してください

ファイルはコミットから削除されますが、ディスク上保持されます。そのため、誤って追加した後でファイルのチェックを外すと、追跡されていないファイルのリストに表示されます(誤って変更した後でファイルのチェックを外すと、コミットリストにステージングされていない変更に表示されます)。


2
Ubuntuでは、git guiをインストールできますsudo apt-get install git-gui
JDiMatteo

ありがとうございました!.gitリポジトリを含むフォルダーが追加され、通常の削除コマンドがすべて機能しないという問題(バグ?)に悩まされました。しかし、これは役に立ちました。それは数回のコミットgit rebase -i HEAD~4でしたが、私は最初に利用してから、コマンドを実行してエディターを開きました。別のメモ:「ステージング解除」は「コミット」メニューにあります。
ジョニーSkovdal

すべての最も簡単なソリューション。覚えるのが最も簡単。また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、2016年

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  

(またはhead〜4、どこまで行きたいか)

次に、「選択」の代わりに「編集」を使用します。「編集」がいかに強力であるかを理解していませんでした。

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

お役に立てれば幸いです。


ビデオは10分であまり役に立ちません
MolbOrg

2

ローカルブランチで1つのファイルだけを元に戻したいという変更があったのと同じ問題がありました。私のために働いたのは-

(以下のfeature / target_branchには、特定のファイルで元に戻したい変更を含むすべての変更があります)

origin / feature / target_branchは、変更をプッシュするリモートブランチです)

機能/ステージングは一時的なステージングブランチであり、その1つのファイルへの変更を除くすべての必要な変更からプッシュします)

  1. origin / feature / target_branchからローカルブランチを作成します- フィーチャー/ステージングと呼ばれます

  2. 機能しているローカルブランチのfeature / target_branchfeature / stagingブランチにマージしました

  3. チェックアウト機能/ステージングその後、gitのリセット--soft ORIG_HEADを (今機能/ステージング」からのすべての変更が上演が、コミットされていないされます。)

  4. 以前に不要な変更を加えてチェックインしたファイルをアンステージングしました

  5. 機能/ステージングの上流ブランチを origin / feature / target_branchに変更しました

  6. ステージングされた残りの変更をコミットし、上流のリモートorigin / feature / target_branchにプッシュしました


1

そのファイルが不要になった場合は、

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

1

GitHubを使用していてまだコミットをプッシュしていない場合、GitHubデスクトップはこの問題を簡単に解決します。

  1. リポジトリ->最新のコミットを元に戻すを選択します
  2. 誤って追加したファイルの選択を解除します。以前のコミットメッセージは既にダイアログボックスにあります。
  3. コミットボタンを押してください!

1

以前のコミットからファイルを削除したい場合は、フィルターを使用してください

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

このエラーが表示された場合:

新しいバックアップを作成できません。以前のバックアップは既にrefs / original /に存在し、バックアップを-fで強制的に上書きします

ローカルリポジトリのrefsバックアップを削除するだけです

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

1

変更をまだgitにプッシュしない場合

git reset --soft HEAD~1

すべての変更をリセットし、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
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 <ファイル名>

いいだろう。履歴を変更したくないのですが、ローカルで誤ってローカルの「ハック」ファイルを追加して、それをコミットから削除したい場合、これは非常に役立ちます。

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