5

私のマスターブランチには、2つのファイルがあります。

file1.txt
file2.txt

そこからb1という名前の新しいブランチを作成しました。b1で、file2.txtを変更し、誤ってfile1.txtを削除しました(ディスクからWindowsエクスプローラーを開いてソースフォルダーに移動すると、file1.txtがありません)。ここで、file2.txtの変更を保持し、マスターからfile1.txtを回復したいと思います(削除されたバージョンは必要ありません)。マスターに切り替え、b1にマージしましたが、競合は発生しませんでした。「すべて最新」と表示されましたが、file1.txtがありません。私は何をすべきでしたか?

4

2 に答える 2

12

ここであなたが尋ねているいくつかの質問があると思います。最初のものは「どうすれば回復できfile1.txtますか?」のようです。リビジョングラフが次のようになっていると仮定します。

               M
(master)  o -- o --- o ------o  HEAD
                \           /
(b1)             o -- o -- o
                 A    B    C

file1.txtあなたは経由の前のコピーを得ることができますgit checkout

git checkout HEAD~1 -- file1.txt

それは復活file1.txtし、あなたの作業コピーにそれを上演します。あなたはそうすることができ、git commitファイルは戻ってきます。注:は、b1をマージする前のマスターの状態を指すHEAD~1の最初の親を取ると言います。HEADコミットIDがわかっている場合は、代わりにそれを使用できますHEAD~1

あなたが尋ねているように思われるもう1つの質問は、「これを回避するために、ブランチb1で何をすべきか」です。file1.txt最も明白な選択は、そもそも削除しないことでした。しかし、あなたが必要だと思って、選択が間違っていると判断したとしましょう。次に、変更をどこかにプッシュしてブランチb1を共有しなかったと仮定します。ファイルをすぐに削除したことに気付いた場合は、次のようにすることができます。

git checkout HEAD~1 -- file1.txt
git commit --amend

つまり、「file1.txtを返してから、そのファイルを最新のコミットにマージする」ということです。これには、最初からファイルを削除したことがないように見える効果があります。

ファイルがすぐに削除されたことに気づかず、その間にいくつかのコミットがあった場合は、git rebase問題を修正するために使用することを検討することをお勧めします。

独自のコミットでファイルを削除した場合git rebase -iは、ブランチの履歴からコミットを削除するために使用できます。Bそれがファイルを削除したコミットであり、それがそのコミットで行われる唯一のことであると仮定しましょう。b1を使用している間は、次のように実行します。

git rebase -i B~1

問題のあるコミット()を含む行を削除しB、保存して終了します。あなたのブランチは、その履歴がなくても書き直さBれました。たとえば、私が実行したgit rebase -iところ、これはエディターに表示されました。

pick 40f76a7 removed bar
pick 30a25f5 modified foo

次に、リストから削除40f76a7して、次のように残しました。

pick 30a25f5 modified foo

マージすると、履歴は次のようになります。

               M
(master)  o -- o --- o ------o  HEAD
                \           /
(b1)             o ------- o
                 A         C'

のコミットIDは、存在しなくなったためとC'は異なり、親のsha1はコミットIDの一部であることに注意してください。IOW、履歴を書き直したため、Cのsha1が変更されました。CB

同じコミットで削除file1.txtして他の変更をたくさん行った場合は、さらにいくつかの手順があります。まず、ファイルを戻し、コミットします。

git checkout B~1 -- file1.txt
git commit -m "Reinstate file1.txt"

新しいコミットを呼び出しましょうD。リビジョングラフは次のようになります

               M
(master)  o -- o --- o -----------o  HEAD
                \           
(b1)             o -- o -- o -- o
                 A    B    C    D

今、実行します:

git rebase -i B~1

そして、コミットIDDを含む行をコミットIDの直後に移動しB、に変更picksquashます。たとえば、実行時にこれを取得しますgit rebase -i B~1

pick 40f76a7 removed bar plus other changes
pick 30a25f5 modified foo
pick 6177cb7 add bar

6177cb7バーを復元するコミットです。だから私はそれをすぐ下に移動し40f76a7、コマンドを次のように変更しsquashます:

pick 40f76a7 removed bar plus other changes
squash 6177cb7 fix bar
pick 30a25f5 modified foo

保存して終了。コミットメッセージを修正するように求められます。それを行う。すべてが完了すると、次のような履歴になります。

               M
(master)  o -- o --- o -----------o  HEAD
                \           
(b1)             o -- o -- o
                 A    B'   C'

newB'は削除されなくなりましfile1.txtた。この時点で、マスターとマージする準備ができています。

いくつかの閉会の辞。に注意してくださいgit rebase。注意しないと、履歴を失う可能性があります。gitrebaseのマニュアルページを必ずお読みください。そこにはたくさんの役立つ情報があります。注:このすべての作業は、ファイルを履歴から削除したという事実を削除したい場合にgit rebaseのみ必要です。ファイルを戻すことを示すコミットがあれば問題ない場合は、必ず、を使用してファイルを復元し、コミットしてください。面倒ではなく、新しいgitユーザーにとっては簡単です。 かなり高度で、ある程度の練習が必要です。しかし、時間をかけてよく学べば、とても便利です。git checkoutgit rebase

于 2012-09-26T10:13:09.880 に答える
3

この場合、マージは実行しません。マスターにマージするときにGitが削除を保持するのは正常です。別のブランチまたはタグからファイルを取得する場合は、ですgit checkout master -- filename

あなたの場合、あなたは前にマージをキャンセルする必要があります:

  1. マスターを使用していること、および作業ディレクトリがクリーンであることを確認してください(git status変更はありません)
  2. 行ったマージをキャンセルします

     git reset --hard master@{1}
    
  3. b1に戻る

    git checkout b1
    
  4. file1.txt作業コピーのマスターからのチェックアウト :

    git checkout master -- file1.txt
    
  5. 以前のコミット、またはやりたいことをコミットまたは修正します
于 2012-09-26T10:08:15.710 に答える