2016-05-15 14 views
1

私はちょうど私がGitを理解していないことに気付いた非常に大きなgit blunderを作った。 はここに何が起こったのです - マスターから構内製git revertとgit mergeを理解する

  1. 、そのブランチにそのブランチの変化
  2. プルマスターを作りました。
  3. マスターブランチに切り替えました(オリジナル/マスターからプルしなかったため、マスターブランチに最新のマスターがありません)
  4. 私の私用ブランチをマージしてマスターにプッシュしました。
  5. 私が納得して引っ張ってプッシュできず、マスターを引っ張ってきたというエラーが表示されました。そしてそれを私のコミットと一緒に押し込んだ。
  6. 私がコミットしたところで、マスターからプライベートブランチに移動し、ローカルマスターにはなかったすべての変更がそこにありました。
  7. コミットを元に戻し、元に戻されなかったすべての変更を元に戻し、コミット履歴がすべての変更に対して消えました。

なぜ個々のファイルのコミット履歴が消えたのか分かりません。誰かが私にこれを理解させるのを助けることができるか

P.S.レッスンは学んだ - 常にプッシュする前に引いて、しばしば

+0

元に戻すには歴史を破壊しないだけの引数からコミット戻り:

は、ここで私は私の毎日の仕事でやっているものです。今回の状態に戻す前にマスターを元の状態に戻し、適切なコミットを元に戻すことを検討してください。 – Basilevs

+0

@Basilevsコミットの履歴はありますが、個々のファイルのコミット履歴が失われている場合はあります。私はコミットの歴史を破壊すべきではないが、なぜファイルの履歴が失われたのか分からないという印象を受けていた。 –

答えて

0

を引くコミット差し戻し、元に戻すには、私はしなかったすべてのそれらの変更を元に戻すと、コミット履歴はすべてのそれらの変更のために行っています。

コミット履歴は、そのブランチ(git log)の一部であるか、少なくともreflogである必要があります。
git revertは、既存のコミットの上に新しいコミット(古いものを取り消すコンテンツ)を作成することになっています。

正しいコミットを見つけたら、つまり、プライベートブランチでマージして元に戻す前に、プライベートブランチをリセットしてください(git reset --hard:ローカルの変更がないか、最初にgit stashを実行してください)

その後、もう一度やり直してください最初のマスター(gitのプル)

0

我々は行うとgit mergeまたはgit fetch and git mergeにほぼ等しいgit pull、成功した結果の2種類のマージ、早送り(FF)のいずれかがあるか非早送り(no-ff)マージが行われます。参照:git-merge。 「FAST-FORWARD MERGE」と「TRUE MERGE」をご覧ください。

一部のリモートリポジトリでは、非ffマージになるプッシュの受け入れを拒否する戦略があります。プッシュする直前にローカルブランチがリモートブランチの適切なスーパーセットであることを常に確認する方がよいでしょう。

ここでは、適切なスーパーセット、または厳密なスーパーセットは、適切なサブセットと共に、数学の意味を示します。

ブランチマスタがA-B-C-Dの場合、ブランチプライベートはA-B-C-D-E-Fのようになりますが、マスタはプライベートの適切なサブセットです。プライベートからマスターへ、またはプライベートをマスターにプッシュする、またはプライベートをマスターにマージするには、早送りマージを行います。マスターからプライベートへ、またはマスターからプライベートに、またはマスターをプライベートにマージすると、あなたにすべてのことを知らせることを除いて、何も起こりません。

ブランチプライベートがA-B-C-Eの場合、マスターはプライベートのサブセットではなく、その逆もあります。プル、プッシュ、マージはすべて、早送りではないマージにつながります。

git fetch origin master 
git checkout -b master FETCH_HEAD 
#change the code 
git add . 
git commit 
#right before I am going to `git push` 
git fetch origin master 
git cherry HEAD FETCH_HEAD 
#if there is any new commit in the remote master, `git cherry` will list it. 
#if `git cherry` outputs nothing, which means the local master is a 
#superset of the remote master, my `git push` will make a 
#fast-forward merge. 
git push origin master:master 
... 
#else if `git cherry` outputs something, like `+ 12345667800abcdef`, 
#which measn someone else has updated the remote master, 
#my `git push` will make a non-fast-forward merge. 
#suppose the local master is like `A-B-C-D` and the remote master is like `A-B-C-E-F` 
git reset C --hard 
git pull origin master 
git cherry-pick D 
#now the local master is like `A-B-C-E-F-D'`, which is now a proper 
#superset of the remote master 
git push origin master:master