コミットでファイルへの変更を元に戻す


126

特定のコミットによって行われた変更を特定のファイルのみに戻したい。

そのためにgit revertコマンドを使用できますか?

それを行う他の簡単な方法はありますか?



奇妙な...なぜそれらすべての年の後に変化が起こるのですか?
VonC、2017

回答:


222

これを行うために私が見た最もきれいな方法はここに説明されています

git show some_commit_sha1 -- some_file.c | git apply -R

VonCの応答に似ていますが、git showおよびを使用しgit applyます。


10
よくできました。このため、スクリプトソリューションはやりすぎです。なぜgit revert sha-1 filenameだけができないのですか?
Mark Edington、2014

16
これは、私のMac上で動作しますが、(Cygwinの下)は、Windows上で、それは私を与える:fatal: unrecognized input
ケダルMhaswade

1
@MerhawiFissehaye:git checkoutは変更を再び元に戻すだけで、コミットされた状態にフォールバックすると思います。私はgit add filenameを実行しました。git commit --amend 'は、ファイルをコミットから削除します。
ViFI

3
ほんの少しのヒント-3ですが、パッチが失敗した場合、通常は変更を少し前に修正しているため、ほぼ常にgit applyにフラグを追加して、3者間マージを行う必要があります。
angularsen 2016年

2
ほとんどの場合some_file.cは明らかですが、ファイルへのパスが含まれている場合は、それが含まれていることを確認してください。それ以外の場合は何も
通知せ

35

コミット履歴を変更しても問題ない場合、以前のコミットで単一ファイルの変更を元に戻すワークフローを次に示します。

たとえばbadfile.txt、コミットで1つのファイル()の変更を元に戻したいとしますaaa222

aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit

ベースコミットに基づいてリベースし、問題のコミットを修正して続行します。

1)インタラクティブなリベースを開始します。

git rebase -i aaa111

2)(編集用)に変更pickして、エディターで問題のコミットを編集用にマークeします。

e aaa222
pick aaa333

3)不正なファイルへの変更を元に戻します:

git show -- badfile.txt | git apply -R

4)変更を追加してコミットを修正します。

git add badfile.txt
git commit --amend

5)リベースを終了します。

git rebase --continue

これは、git履歴を編集できることを前提としています。上記のいくつかの回答は、履歴を編集せずに特定の変更を元に戻す新しいコミットを作成しますが、これは常に可能/許可されているわけではありません。
angularsen 2016年

素晴らしい。これはまさに私が探していたものでした。私はすでにこのアイデアを思いつきましたが、インタラクティブなリベースを実行するときに混乱してしまい、実行中のファイルeditが変更されたように表示されませんでした。しかし、git show -- badfile.txt | git apply -R私が必要とする答えは<3
mraxus

このgit apply -Rを理解すると、そのファイルのコミットが削除され、元の変更された状態に戻りますか?
DaImTo

19

git revert コミット内のすべてのファイルコンテンツ用です。

単一のファイルの場合、スクリプトで記述できます

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

smtlaissezfairegit-shell-scriptsユーティリティから)


注意:

現在の変更をまだコミットしていない場合は、ここで別の方法を説明します

git checkout -- filename

git checkout ファイルにはいくつかのオプションがあり、HEADからファイルを変更し、変更を上書きします。


Dropped.on.Capricaコメントで言及されています

gitにエイリアスを追加git revert-file <hash> <file-loc>して、特定のファイルを元に戻すことができます。この要点を
参照してください。

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh

ここのディスカッションに追加するために、エイリアスをgitに追加して、git revert-file <hash> <file-loc>その特定のファイルを元に戻すことができます。私はこの答えから離れました(ただし、正しく機能するためにいくつかの編集を行う必要がありました)。私の.gitconfigスクリプトと編集したスクリプトのコピーは、gist.github.com
droppedoncaprica

@ Dropped.on.Caprica良い点。私はより多くの可視性のために答えにそれを含めました。
VonC、2015

12

--no-commitオプションを使用して、git-revert最後にコミットする前に、インデックスから元に戻したくないファイルを削除します。2番目に新しいコミットでfoo.cへの変更だけを簡単に元に戻す方法を示す例を次に示します。

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

最初はgit-resetすべてのファイルを「ステージング解除」します。これにより、元に戻したいファイルを1つだけ追加して戻すことができます。最後git-reset --hardは、残したくない残りのファイルの復元を取り除きます。


9

はるかに簡単:

git reset HEAD^ path/to/file/to/revert

その後

git commit --amend   

その後

git push -f

ファイルはなくなっており、コミットハッシュ、メッセージなどは同じです。


完全にするために、git checkout -- path/to/file/to/revertステップが必要ですか?また、ハッシュが同じであるというのは本当ではありませんよね?「最後のコミットは、元に戻されたファイルへの変更が含まれていないという点のみが異なる新しいコミットに置き換えられるという結果になります。」
ケビン

@ケビンあなたはおそらく正しいです。最後の行を再確認する必要がありますが、これを数年前から振り返ると、コミットハッシュが変更されていない場合は驚きます。
フォレスト

6
git reset HEAD^ path/to/file/to/revert/in/commit

上記のコマンドはファイルのコミットを解除しgit statusますが、には反映されます。

git checkout path/to/file/to/revert/in/commit

上記のコマンドは変更を元に戻します(結果として、HEADと同じファイルが取得されます)。

git commit

--amendコミットを修正するためにパスします。)

git push

これにより、すでにコミットされているファイルが削除され、元に戻されます。

上記の手順は、コミットが行われるブランチから実行する必要があります。


5

この手順に従うことができます:

  1. git revert -n <*commit*>-nすべての変更を元に戻しますが、コミットしません)
  2. git add <*filename*> (元に戻してコミットするファイルの名前)
  3. git commit -m 'reverted message' (元に戻すためのメッセージを追加)
  4. コミット後、他のファイルの変更を破棄して、元に戻す前にコミットした変更でファイルが更新されたままになる

1

最後のコミットからのファイルの変更をリセットしたい場合、これは私が通常使用しているものです。これが最も簡単な解決策だと思います。

ファイルがステージング領域に追加されることに注意してください。

git checkout <prev_commit_hash> -- <path_to_your_file>

それが役に立てば幸い :)

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