git selectionはファイルからローカルの変更を元に戻します


149

svn repoを追跡しているgit repoで、1つのファイルにいくつかの編集を加えました。

これらの変更(svn revertなど)を元に戻したいのですが、ファイルの一部のみです。

ファイルの差分を表示し、不要な変更を破棄(元に戻す)し、必要な変更を保持したい。

git add -i 

コマンドにはそれを行うオプションがあるようですが、まだこれをステージングしたくありません。

回答:


91

あなたは直接それを行うことができますgit checkout -p。以下のダニエル・シュッツバッハの回答を参照してください。


以前の回答(checkout -p導入前):

あなたはこのようにそれを行うことができます:

git add -i

(保持するハンクを選択します)

git commit -m "tmp"

これで、保持したい変更のみを含むコミットが作成され、残りはステージングされません。

git reset --hard HEAD

この時点で、コミットされていない変更は破棄されているので、コミットしたままにしておく変更がクリーンな作業ディレクトリになっています。

git reset --mixed HEAD^

これにより、最後のコミット(「tmp」)が削除されますが、変更は作業ディレクトリにステージングされずに保持されます。

EDIT:交換し--soft--mixed、ステージング領域をクリーンアップします。


これは私が保持したい変更をコミットしますね?これらの変更はまだコミットしたくありません。たぶん私はあまりにも真剣にコミットしている。たぶん、ローカルリポジトリにいるので、今はリラックスする必要があります。ところでgit reset --soft HEAD ^は何をしますか?
Pradeep、

"git reset --soft HEAD ^"は、作業ディレクトリとインデックスをそのまま維持するという意味でコミットを取り消し、現在のブランチを1コミット戻します。
JakubNarębski、2009

Jakubに感謝します。Paoloなぜヘッドへのソフトリセット-ここで1が必要ですか?部分的なコミットとハードリセットで十分なはずですが、一部の変更を保持し、他の変更を破棄しませんか?
Pradeep、

1
以下のダニエルの答えは非常にシンプルで、正しい方法のように見えます。
Umang

309

私はあなたがそれを最も簡単に行うことができると信じています:

git checkout -p <optional filename(s)>

マンページから:

   −p, −−patch
       Interactively select hunks in the difference between the <tree−ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree−ish> was specified, the index).
       This means that you can use git checkout −p to selectively discard
       edits from your current working tree.

1
また、これを選択的に実行したくない場合は、「git checkout-<file> ...」を使用して変更を破棄できます。
db42

ディレクトリを扱いますか?
bbum

1
これは、変更を破棄するときに多くの場合失敗するようです( "エラー:パッチが失敗しました<ファイル>"、 "エラー:<ファイル>パッチは適用されません")。不思議なことにa、パッチモードのオプションを使用してファイル全体を破棄すると、これらのエラーが表示されますが、git checkout -- <file>期待どおりに機能します。誰もが理由を知っていますか?
chrnola 2014年

ファイルに既にパッチが適用されている場合は、何度かそのエラーが発生したため、現在のファイルに適用されているパッチでインタラクティブパッチが古くなりました。ソースツリーのようなGUIツールを使用しているときに、ハンクを誤って2回破棄した場合に発生しました。2回目はそのエラーを生成します。
フィアット2016

3

git diffファイルを実行し、結果の差分を保存し、編集して保存たい変更を削除し、それを実行してpatch -R残りの差分を元に戻すことができます。

git diff file.txt> patch.tmp
#patch.tmpを編集して、保持するハンクを削除します
パッチ-R <patch.tmp

パッチファイルに2つのハンクがあり、1つを削除しました。理由はわかりませんが、パッチ-Rはこれで拒否され続けます。
Pradeep、

2
git diff変更されたファイル全体を示す別のコメントで言及します。これは通常、以前とは異なる行末を使用してファイルを保存した場合に発生します。これによりpatch、パッチファイルが拒否されます。それは何が起こったのでしょうか?
グレッグヒューギル

あなたが正しいです。patchコマンドを使用するたびに、行末が切り替わっています。私はwindowsにいて、クリーム/ vimを使用しています。最初にこれを整理する必要があると思います。
Pradeep、

Windowsのパッチに関する問題を解決できませんでした。私はこれがうまくいくと確信していますが、パオロのレシピを使用することを好みます。これらのインタラクティブなコマンドを気に入って、git add -iを使用してdiffを操作します。
Pradeep、

3

あなたが望むように見えます

 git revert --no-commit $REVSISON 

次に使用できます

 git diff --cached

コミットする前にどのような変更が行われるかを確認する(元に戻すとは、過去の変更の逆を複製する、順方向のコミットに過ぎないため)

純粋なGitリポジトリを使用している場合は、目的に応じて、インタラクティブなリベース(git rebase -i)を使用して不要なコミットに戻り、コミットを遡及的に編集して、望ましくない変更が発生しないようにすることができますが、唯一のあなたがいる場合のために、一般的にthatsの知っているあなたは再びそれを見てみたいことは決してないだろう。


あなたが以前のリビジョンに言及したように私は元に戻しました(それは正しいですか?)今、git diffはファイル全体が変更されたと表示します。私が行った編集を表示することになっていますか?
Pradeep、

1

質問をもう一度読んでみると、以前にコミットされた変更ではなく、作業ツリーにある変更を元に戻したいようですが、他のいくつかの回答は私の読みが間違っているように聞こえます。明確にできますか?

変更が作業コピーだけにある場合、これを行う最も簡単な方法は、保持したい変更をステージングすることです。

git add -i <file>

次に、インデックスバージョンをチェックアウトして、保持したくない変更を破棄します。

git checkout -- <file>

次に、変更をまだステージングしたくない場合は、ステージングを解除します。

git reset -- <file>

このレシピは、選択したファイル(または指定したファイル)の変更のみを元に戻し、元に戻す必要がある一時的なコミットを作成しません。

以前のコミットで行われた変更の一部のみを選択的に適用する場合は、最初にファイルを以前のコミットされた状態にリセットできます。

git reset <commit_before_first_unwanted_change> -- <file>

次に、前のレシピに従って、git add -i <file>保持したい変更をステージングしgit checkout -- <file>、不要な変更をgit reset -- <file>破棄して、変更を「ステージング解除」します。


0

ここで回答に記載されているコマンドラインオプションは、ファイルがssh端末を介してアクセスしているサーバー上にある場合に便利です。ただし、ファイルがローカルマシンにある場合は、次の方法を使用します。

netbeansエディター(gitサポートに付属)でファイルを開きます。Netbeansは、行番号に赤、緑、青のマークを付けて、(それぞれ)削除/追加/変更された場所を示します。

これらのマークのいずれかを右クリックすると、その変更を元に戻すオプションが表示されます。さらに、赤と青のマークを右クリックして、古いバージョンをポップアップで確認できます。

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