2017-05-08 11 views
2

私は2つのブランチで作業し、すべてを混ぜました。支店Aのために意図されたいくつかの変更は支店Bとその反対です。いくつかのコミットには、正しいブランチへの変更と誤った不正な変更が同時に含まれます。私はこのミックスでいくつかのコミットをしました。git:ブランチを混在させて - クリーンアップする方法

その後、私は正しいブランチで再度変更を行いました。 だから私は正しいブランチのすべての変更に終わったが、それぞれのブランチには、もう一方のブランチに属する古い変更もあった。 次に、支店Aのためにプッシュし、支店Bのために私は既にプルリクエストを行いました。

質問1:どのように私は、各ブランチからそこに属していない変更内容を削除することができますか? ブランチ内のどのファイルを元の状態に戻す必要があるのか​​を正確に知っています。

質問2:既にプルリクエストを変更するにはどうすればよいですか?

+0

はプルリクエストが既に受信者によってマージされていたのですか? – quetzalcoatl

+0

いいえ合併していません –

+0

まだ合併していない場合、**プルリクエスト**は意味がありません。本質的には、「私のパブリックリポジトリブランチフーバーをあなたのものにマージしてください」という「メモ」だけを記憶しています。クリーンアップしてそのクリーンアップを公開/プッシュすると、プル要求は変更されません。それはまだ**同じことを言っている: "あなたのバーフーに私のfoobarをマージしてください"。しかし、今、明らかに、あなたのfoobarはクリーンアップ後になるでしょう。>したがって、あなたは "プルリクエスト"が自動的に自己更新していると考えることができます。もちろん、便利ですが、まだ統合されていない限りです。 – quetzalcoatl

答えて

1

、プッシュする前にこれをクリーンアップするためにはるかに安全だろう。あなたは(新しい名前で)新しいブランチを作成し、それらのそれぞれに必要な変更を移行することができ

  • :この時点では、2つの選択肢があります。既存の支店は放棄されてしまいます。

  • 既存の枝を修正するために、「歴史を書き換える」ことができます。既存のブランチを取り出したり引っ張ったりした人は、回復手順を実行する必要があります(この問題の一般的な説明については、git rebaseのドキュメントの「上流からの回復」を参照してください)。

この手順は、いくつかの点でより安全であるため、最初のオプションを前提として書きます。代わりにヒストリの書き換えを使用する場合は、手順を調整する方法についていくつかの注意を払います。私はbranchAを行う方法を示し、branchBの手順は本質的に同じです。私はブランチがmasterから作成されたと仮定します(そうでなければ、masterへのすべての参照を適切な "親ブランチ"に置き換えてください)。

既存のブランチを確認してください。

git checkout branchA 

新しい枝がmasterの先端に移動することにしたくないと仮定すると、あなたは、分岐点を見つける必要があります。イラストレーションを簡略化するために、その時点で一時タグを作成してください(技術的には、このコミットにSHA1 IDを使用することもできます)。

だから、

x --- A --- x <--(master) 
     \ 
     A1 --- B1 --- AB1 --- A2 <--(branchA) 

を持っていて、Aを見つける必要があります。それはmasterから分割した後に(この例では)があることbranchAの4つのコミットを知っている場合は、番号がわからない場合、あなたはGUIフロントエンドからそれを眼球するか、

git tag rootA branchA~4 

を言うことができますまたはgit log --graph master branchAから(コミットの歴史が、これは実用的であることを十分に小さい場合)、またはされていない場合:

git rev-list master..branchA 

出力の最後の行はそのためだと仮定すると、は、まずあなたのブランチにコミットのためにSHA1です31337c0d3あなたが希望

git tag rootA 31337c0d3^ 

(最後は^です)。

一つの方法または他のあなたは今

[rootA] 
     | 
x --- A --- x <--(master) 
     \ 
     A1 --- B1 --- AB1 --- A2 <--(branchA) 

今すぐ新しいブランチを作成する必要があります(ただし、「歴史の書き換え」オプションを使用する場合は、このステップをスキップすることができます)。

git checkout -b new_branchA 

今、あなたは「TODO」リストで、テキストエディタ、コミットを表す各ラインを取得します、対話型リベースセッション

git rebase -i --onto rootA master 

を開始します。 branchBに属してコミットするためにbranchAに属してコミットするために

、そのままライン(pickコマンド)を残し

- あなたはすでにbranchB上で、これらの変更を持っていることを考慮すると - あなただけのpickからdropにコマンドを変更することができます

コミット変更(branchAに属するいくつかの、branchBに属している他の人)が混在している場合は、pickからedit

にコマンドを変更

保存し、テキストエディタを終了し、gitのはリベースを開始します。あなたがeditでコミットをマークした場合、Gitは一時停止して、あなたの編集を行い、その後、リベースを再開するよう指示するように求められます。リベースはあなたが持っているよ行われ

[rootA] 
     | 
x --- A --- x <--(master) 
     |\ 
     | A1 --- B1 --- AB1 --- A2 <--(branchA) 
     \ 
     A1' --- Ab1' --- A2' <--(new_branchA) 

Ab1'BranchAのためのものだけで変更が保持されたAB1のために編集交換です)。

履歴を書き換えた場合、branchAA2'を指しますが、もちろんnew_branchAはありません。

一時タグをクリーンアップすることができます。

git tag --delete rootA 

、あなたの歴史は古いbranchAを必要としなくなっあなたを書き換えた場合を除き:

git branch --delete branchA 

最後に、あなたがリモート

git push 

場合(にプッシュすることができます履歴書き換えの場合は、-fオプションが必要です)。

+0

Tkx ,,これは非常に明確です。私たちはまた、brancheに複数の機能がありました。あなたのソリューションでは、各機能のための新しいbrancheを作成し、RootAから始め、その機能の変更を選択することが可能になると思います。その後、フォームRootAを開始してフィーチャ2のブランチを作成し、フィーチャ2に属する変更のみを再度選択します。すべての機能が分割されている場合は、brancheAを削除します。これは正しいです? –

+0

@JacJacはい、正しいです。 –

0

あなたはまだそれらの枝をプッシュしていない場合、あなたがすることができます

  • tmpAtmpBあなたがAからtmpAに必要
  • git cherry-pickコミット(origin/Aorigin/Bからのインスタンスの)ブランチを作成、 BからtmpBまで;あなたがコミット使用]オプション--no-commitを編集する必要がある場合は、git reset希望の変更を追加し
  • Bのために同じ、Agit branch -f A tmpAtmpAにそれらの支店をリセットし、結果をコミットするだけにgit add -p続く、インデックスをクリアします。
  • tmpAおよびtmpB。今後の参考のために
+0

Tkx、チェリーピックは1つのコミットを分けることが可能ですか?あるコミットでは、brancheAとnrancheBのために時々変更があります。私はチェリーピックが全部コミットすると思った? –

+0

@JacJacはい、 '--no-commit'オプションで' git cherry-pick'を使うことができます。次に 'git reset'を実行すると、' git add -p'で必要なものだけを追加できます。必要なファイル(またはファイルの一部)を追加したら、コミットし、 'git clean -fd'を実行します。 – VonC

関連する問題