gitのステージングされていない変更の一部を元に戻す


158

ステージングされていない変更の一部をgitで元に戻し、残りをステージングされていない状態にするにはどうすればよいですか?私が考え出した方法は:

git commit --interactive
# Choose the parts I want to delete
# Commit the changes
git stash
git rebase -i master # (I am an ancestor of master)
# Delete the line of the most recent commit
git stash apply

これは機能しますが、git commit --interactive変更を元に戻すだけのようなものがあるとよいでしょう。より良い方法はありますか?

回答:


264

を使用するとgit checkout -p、作業コピーとインデックス間の差分から個々のハンクを選択して元に戻すことができます。同様git add -pに、インデックスに追加するハンクを選択git reset -pでき、インデックスとHEADの間の差分から個々のハンクを選択して、インデックスからバックアウトできます。

$ git checkout -p file/to/partially/revert
# or ...
$ git checkout -p .

これらの変更を元に戻す前に保存するために事前にgitリポジトリのスナップショットを作成したい場合は、次のようにします。

$ git stash; git stash apply

これを頻繁に使用する場合は、別名を付けることができます。

[alias]
    checkpoint = !git stash; git stash apply

優れたエディターモードまたはプラグインを使用すると、個々のハンクまたは行を元に戻すのがさらに簡単になる場合があります。これは、元に戻す行を直接選択するサポートを提供-pする場合があります。私は、Gitの操作に非常に役立つEmacsモードであるMagitを使用しています。Magitでは、を実行しmagit-status、元に戻したい変更の差分を見つけ、元に戻したい行を選択します(または、一度に元に戻すのではなく、元に戻したいハンクにカーソルを置きます)一度に1行ずつ)、を押しkて特定の行を元に戻します。Emacsを使用する場合は、Magitを強くお勧めします。


これは私が最初に思いついたソリューションと同じくらい複雑だと思いますが、私の元のソリューションには、削除された行がコミットされるため、30日間保存できるという利点があると思います。私は多分それの周りに書かれたシェルスクリプトがあればいいのではないかと思っています。
asmeurer、2010年

1
申し訳ありませんが、これにはフラグgit checkoutもあることに気づきました。-pフラグは、単一のコマンドで要求したとおりのことを行います。以前の複雑なステップのセットに対する謝罪。そのまま使用できますgit checkout -p。何かを保存する限り、破壊的な可能性のある何かをする前に、現在のツリーをスタッシュに記録するgit stash; git stash apply(またはそれを行うエイリアスを作成するgit checkpoint)ことがよくあります。
ブライアンキャンベル

これで解決です。エイリアスに関しては、git commit -a -m "Backup Commit" --edit; git reset HEAD^ 他の何かに使用している可能性がある私の隠し場所の状態を汚すことがないので、次のようなもの が良いと考えています。その後、SHA1があれば、次の30日以内にチェリーピックできます。--editを使用すると、コミットメッセージに情報を追加して、必要に応じて後でSHA1を見つけるのに役立ちます。一方、これはgit reflogを汚してしまうので、あなたが何をしているかに基づくトレードオフだと思います。
asmeurer

チェックポイントエイリアスが機能しません。最初のコマンドのみが実行され、2番目のコマンドは実行されません。私はそれが好きだったので、それは悲しいです。私はgitバージョン1.7.10.4を使用しています。
Fabien

git checkout -pパッチをインデックスに適用せず、ステージングのみを行う方法はありますか?
ジェレミア2016年

28
git diff > patchfile

次に、パッチファイルを編集して、元に戻したくない部分を削除してから、次のようにします。

patch -R < patchfile

6
ただし、この答えは、その単純さと使いやすさの点で特に見事です。+1
完全に2015

生成さpatchfileれたvimは見栄えが良く、本当に役立ちます!
Bily

完璧です。WindowsでCygwinおよびUbuntu bashを使用するWindowsでも動作することを確認できます。
Checo R 2017

1
git apply -R代わりに使用することもできますpatch(gitのレルム内に留まるため、またはpatch利用できない別のイベントで)
user1556435

patch: **** malformed patch at line 41: @@ -428,9 +443,9 @@ you should place your code here."
HappyFace

5

あなたができる

git checkout master -- path/to/file

リセットするファイルごとに。


または、ブランチで作業する場合は、マスターの代わりにHEADを使用します。「git status」レポートで言うように(少なくとも最近のバージョンでは)。
Jonathan Leffler、2010年

1

いかがですか

  1. インデックスからの変更で影響を受けるファイルをバックアウトします
  2. 必要なgit add -p変更のみをインデックスに追加するために使用します。

1

「git status」を実行すると、次のように表示されます。

$ git status
# On branch fr/fr.002
# 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:   makefile
#
no changes added to commit (use "git add" and/or "git commit -a")
$

したがって、ステージングされていない編集をキャンセルするには、次のコマンドを実行するように指示します。

git checkout -- makefile

3
私は、一度にファイル全体ではなく、個々のハンクを元に戻す方法について疑問に思っていたと思います。もちろん、これはファイル内のすべての変更を元に戻す必要がある場合の解決策です。
ブライアンキャンベル

うん-私はあなたが正しいと思う。あなたが言ったように、 'git checkout -p'と 'git add -p'オプションが望まれているようです。
ジョナサンレフラー、2010年

1

Brian Campbellの答えは、理由が不明なため、私のgitバージョン1.9.2.msysgit.0をクラッシュさせるため、私のアプローチは、保持したいハンクをステージングし、作業コピーの変更を破棄して、ステージング解除することです。

$ git add -p
   ... select the hunks to keep
$ git checkout -- .
$ git reset HEAD .

1
もありgit stash -pます。あなたはできるgit stash -p; git reset --hard; git stash pop。これは、コミットメッセージを書く必要がないことを除いて、実際に行っていることと同じです。
asmeurer 2015年

@asmeurer乾杯。鉱山はコミットメッセージを必要としませんが、このためのインデックスよりもスタッシュを使用する方が理にかなっています。
G-Wiz

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