私の開発部門の1つでは、コードベースにいくつかの変更を加えました。私が取り組んでいた機能を完成させることができる前に、私は現在のブランチをmasterに切り替えていくつかの機能をデモしなければなりませんでした。しかし、単に "git checkout master"を使っても私の開発ブランチで行った変更は保存されているので、masterの機能のいくつかは壊れています。だから私は自分の開発ブランチでコミットメッセージ "temporary commit"を使って変更をコミットしてからデモのマスターをチェックアウトしました。
デモを終了して開発ブランチの作業に戻ったので、行った変更を保持しながら、行った「一時的なコミット」を削除します。それは可能ですか?
それはこれと同じくらい簡単です:
git reset HEAD^
git reset
または--hard
のない--soft
は、ファイルを変更することなく、指定されたコミットを指すようにHEAD
を移動します。 HEAD^
は現在のコミットの(最初の)親コミットを指します。これはあなたの場合は一時的なコミットの前のコミットです。
別の選択肢として、通常どおりに続行してから、次のコミットポイントで代わりに実行することができます。
git commit --amend [-m … etc]
代わりに 編集 /最新のコミットが行われ、上記と同じ効果があります。
他の誰かがそれを引っ張ってきた場所に悪いコミットをすでに押し付けている場合、これは(ほとんどすべてのgit回答と同様に)問題を引き起こす可能性があることに注意してください。それを避けよう
これを処理する方法は2つあります。どちらが簡単かはあなたの状況によります
リセット
取り除きたいコミットが最後のコミットであり、追加の作業を何もしていない場合は、単にgit-reset
を使用できます。
git reset HEAD^
現在のHEADの直前にあるブランチをコミットに戻します。ただし、実際には作業ツリーのファイルは変更されません。その結果、そのコミットにあった変更は修正されたものとして現れます - それは 'uncommit'コマンドのようなものです。実際には、それを行うためのエイリアスがあります。
git config --global alias.uncommit 'reset HEAD^'
そうすれば、将来git uncommit
を使って1つのコミットをバックアップすることができます。
スカッシュ
コミットを潰すとは、2つ以上のコミットを1つにまとめることを意味します。私はこれをかなり頻繁にします。あなたのケースでは、半分完了した機能がコミットされています、そして、あなたはそれを終えてそして適切な、永久のコミットメッセージで再びコミットするでしょう。
git rebase -i <ref>
これはコミットがいくつでも戻ってくる可能性があることを明確にしたいためです。 git log
を実行して取り除きたいコミットを見つけ、そのSHA1をコピーして<ref>
の代わりに使用します。 Gitは対話式リベースモードにあなたを連れて行きます。現在の状態と<ref>
の代わりに行ったものとの間のすべてのコミットが表示されます。したがって、<ref>
が10コミット前の場合、10コミットすべてが表示されます。
各コミットの前に、それはWord pick
を持ちます。取り除きたいコミットを見つけて、それをpick
からfixup
またはsquash
に変更します。 fixup
を使用すると、そのコミットメッセージを破棄し、変更内容をリスト内の直前のものにマージします。 squash
キーワードでも同じことができますが、新しく組み合わせたコミットのコミットメッセージを編集できます。
エディタを終了すると、コミットはリストに表示されている順序でコミットされます。そのため、一時的なコミットを行い、その後同じブランチで他の作業を行い、後のコミットで機能を完了した場合は、rebaseを使用してコミットを再ソートしてそれらをスカッシュすることができます。
警告:
履歴を変更することでリベース - あなたが他の開発者とすでに共有したことのあるコミットに対してこれを行わないでください。
隠し場所
将来的には、この問題を回避するために、コミットされていない作業を一時的に保管するためにgit stash
を使用することを検討してください。
git stash save 'some message'
これはあなたの隠しリストの横にあなたの現在の変更を保存します。上記はstashコマンドの最も明示的なバージョンです。あなたが何を隠しているのかを説明するコメントを入れることができます。 git stash
を実行するだけで他には何もできませんが、メッセージは保存されません。
あなたはあなたの隠し場所リストを閲覧することができます...
git stash list
これはあなたのすべての隠し場所、それらが行われた枝、そして各行の先頭とメッセージ、そしてstash@{#}
のような識別子を表します。
Stashを元に戻すには(stashが最初に作成された場所に関係なく、どのブランチでも実行できます)、単に実行するだけです。
git stash apply stash@{#}
繰り返しますが、#はstashの配列内の位置です。復元したい隠し場所が0
の位置にある場合、つまりそれが最新の隠し場所である場合。そうすれば、スタッシュ位置を指定せずにコマンドを実行することができます。gitは、最後の位置を意味するものと想定します:git stash apply
。
したがって、たとえば、自分が間違ったブランチに取り組んでいることに気付いた場合、次のような一連のコマンドを実行します。
git stash
git checkout <correct_branch>
git stash apply
あなたの場合は、もう少し枝を移動しましたが、それでも同じ考え方が当てはまります。
お役に立てれば。
私はあなたがこれを探していると思います
git reset --soft HEAD~1
そのコミットで行われた変更をステージングに維持しながら、最新のコミットを取り消します。
はい、変更を削除せずにコミットを削除できます。git reset @〜
Zshを使っている人は、次のようにしなければなりません。
git reset --soft HEAD\^
ここで説明しました: https://github.com/robbyrussell/oh-my-zsh/issues/449
URLが無効になった場合、重要な部分は次のとおりです。
あなたのコマンドで^をエスケープする
毎回それをエスケープする必要がないようにあなたは代わりにHEAD〜を使うことができます。
私の場合、私はすでにレポにプッシュしました。痛い!
次のようにすれば、ローカルファイルの変更を維持しながら特定のコミットを元に戻すことができます。
git revert -n <sha>
このようにして私は私が必要とした変更を保存し、すでにプッシュされたコミットを取り消すことができました。
もう1つの方法があります。
一時コミットの先頭にコミットを追加してから、次のようにします。
git rebase -i
2つのコミットを1つにマージするには(コマンドでテキストファイルを開いて編集します)。
あなたはgit reset HEAD^ --soft
かgit reset HEAD^ --mixed
を探しています。
docs に記載されているように、resetコマンドには3つのモードがあります。
git reset HEAD^ --soft
git commit
を元に戻します。作業ツリー(プロジェクトフォルダ)+インデックス(--cached)にはまだ変更があります。
git reset HEAD^ --mixed
git commit
+ git add
を元に戻します。作業ツリーにはまだ変更があります
git reset HEAD^ --hard
あなたがコードベースにこれらの変更を加えたことがないように。作業ツリーから変更がなくなりました。