LoginSignup
41
38

More than 5 years have passed since last update.

【Git】ファイルを間違えてプッシュした時の解決法

Last updated at Posted at 2018-12-09

先日、間違ったファイルをリモートブランチにプッシュしてしまいました。

何とか解決できたので、その時のコマンドの流れを忘れないように残しておこうと思います。

ここで登場する用語

参考記事

Git超絶まとめ

ワーキングツリー

  • ユーザーが作業しているディレクトリ領域

ステージング

  • コミット対象のファイルを登録する領域
  • git addでステージングできる
  • インデックスとも言うらしい

HEAD

  • 今いるブランチの最新コミット
  • HEAD^は1つ前のコミット

間違ったファイルをプッシュした

ここでは、push_test_01.txtをリモートブランチにプッシュする必要がなかった(もしくはプッシュしてはいけなかった)とします。

$ git add .
$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   push_test_01.txt
    new file:   push_test_02.txt
    modified:   test_01.txt
$ git commit -m "テスト3"
$ git push origin develop

間違えてプッシュしてしまいました。

こんな感じに戻したい

目的はこの2つです。

  • テスト3としてコミットする前の状態(テスト2の状態)に戻したい
  • けれど、ワークツリーの変更(push_test_01.txt, push_test_02.txt, test_01.txtの変更)はそのまま残したい

ログの確認

git logでログを確認します。

プッシュを取り消すには、まずコミットを取り消す必要があります。
取り消すと言うより、過去の状態に戻すと言ったほうが正しいかもしれません。

ここでの巻き戻し先は、テスト2です。

$ git log -3
commit コミットID (HEAD -> develop, origin/develop)
Author: author_name <author@example.com>
Date:   Sun Dec 9 17:34:33 2018 +0900

    テスト3

commit コミットID
Author: author_name <author@example.com>
Date:   Sun Nov 18 16:31:46 2018 +0900

    テスト2

commit コミットID
Author: author_name <author@example.com>
Date:   Sun Nov 18 16:08:16 2018 +0900

    テスト1

コミットの巻き戻し

git resetでコミットを巻き戻すことができます。
コミットIDは、戻したい時点のコミットIDを指定します。

ここではテスト2の状態に戻したいので、テスト2のコミットIDを指定します。

$ git reset --soft テスト2のコミットID

softオプションを指定すると、ワークツリーの変更とステージングの状態はそのまま残ります。hardオプションを指定すると、どちらの内容も消えます。

デフォルトはmixedオプションです。(ワークツリーの変更は残るが、ステージングの状態は戻る。)

コマンド実行後、必ずgit logでログを確認します。
テスト3のコミットが消えました。

$ git log -3
commit コミットID
Author: author_name <author@example.com>
Date:   Sun Nov 18 16:31:46 2018 +0900

    テスト2

commit コミットID
Author: author_name <author@example.com>
Date:   Sun Nov 18 16:08:16 2018 +0900

    テスト1

commit コミットID
Author: author_name <author@example.com>
Date:   Sun Nov 18 16:08:16 2018 +0900

    テスト0

ワークツリーもそのままです。ファイルを変更した後、ステージングされた状態(git add後の状態)に戻っています。

$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   push_test_01.txt
    new file:   push_test_02.txt
    modified:   test_01.txt

プッシュしたくないファイルをステージングから除く

プッシュしたくないファイルをステージングから除きます。

git reset HEAD ファイル名を実行します。

$ git reset HEAD push_test_01.txt
$ git status
On branch develop
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   push_test_02.txt
    modified:   test_01.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    push_test_01.txt

再コミット

正しくステージングがされていることを確認したら、もう一度コミットします。

$ git commit -m "テスト3 その2"

再プッシュ

プッシュをもう一度行います。

fオプションを使用して強制的にプッシュします。

$ git push -f origin develop

これでプッシュしたくないファイルは、リモートリポジトリから消えました。

プッシュしなかったファイルは?

今回のpush_test_01.txtは追跡されていないファイルなので、削除したり.gitignoreに記述したりします。

.gitignoreについては、こちらの記事が参考になります。

[Git] .gitignoreの仕様詳解

追跡されているファイルの場合、変更(ワークツリーにある状態)自体を取り消したい場合は、git checkout ファイル名でHEAD(最新コミット)の状態に戻すこともできます。

$ git checkout test_01.txt

この場合、既にコミットされている状態に戻るため、コマンド実行後はgit statusに表示されることはありません。

また、コミットIDを指定して、特定のコミットの状態に戻すこともできます。

おまけ

コミットはしたくないけれどブランチを切り替えたい場合は、git stash -uをよく使います。

ファイルの一時退避に使えるコマンドです。uオプションで、新規作成のファイルも対象に含める事ができます。

気を抜くと、ブランチもスタッシュも乱立されています・・・適宜削除しなければです。

参考記事

【git stash】コミットはせずに変更を退避したいとき

41
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
38