web-dev-qa-db-ja.com

github:既存のプルリクエストにコミットを追加する

Fork&Edit this filefileボタンを使用して、githubの Rails リポジトリへのプルリクエストを開きました。

さて、PRについてのフィードバックを受け取った後、さらにコミットを追加したいと思いました。だからここで私がやることで終わったものです

$ git clone [email protected]:gaurish/Rails.git #my forked repo
$ git rebase -i 785a2e5 #commit hash of my commit using which PR was opened
$ git checkout patch-3 #branch name I had to send my commits under to be shown in that PR
$ git commit -am "Changes done as per feedback"
$ git Push Origin patch-3

これはうまくいきましたが、非常に複雑なワークフローのようです。ここで何か間違っているのでしょうか?

私の質問は、私はこれを正しい方法でやっていますか?そうでない場合、これを行う適切な方法は何ですか?

80
CuriousMind

GitHubのツールを使用し、1つのファイルを変更するだけなので、GitHubで ファイルを参照 にすることもできます。左上の「tree:」ドロップダウン(patch-3あなたの場合)、そして今「このファイルを編集」を選択します。これで、変更がこのブランチにコミットされ、プルリクエストに表示されます。

55
Abe Voelker

私はつい最近 blogged このトピックについて:

この機能ブランチを最新の状態に保つにはどうすればよいですか?最新のアップストリームコミットをマージするのは簡単ですが、マージコミットの作成は避けたいと思います。アップストリームにプッシュしても評価されないためです。その後、アップストリームの変更を効果的に再コミットすると、それらのアップストリームコミットは新しいハッシュ(彼らは新しい親を取得します)。これは特に重要です。マージされたコミットは、それらの更新を個人のgithub機能ブランチにプッシュするときにGithubプルリクエストに反映されるためです(プルリクエストを発行した後に行った場合でも)。

そのため、マージする代わりにリベースする必要があります。

git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel

Gitのrebaseオプションとrebaseコマンドはどちらもツリーをクリーンに保ち、コミットのマージを回避します。ただし、これらはリベースされている最初のコミット(最初のプルリクエストを発行した人)であり、新しいコミットハッシュを持っていることに注意してください。これは、リモートgithubリポジトリブランチにまだある元のハッシュとは異なります。

現在、これらの更新を個人のGithub機能ブランチにプッシュすると、両方のブランチが異なるため、ここで失敗します。ローカルブランチツリーとリモートブランチツリーは、コミットハッシュが異なるため「同期していません」。 Gitは、最初にgit pull --rebase、次にPushを実行するように指示しますが、これは単純な早送りプッシュではなく、履歴が書き換えられるためです。しないでください!

ここでの問題は、最初に変更されたコミットを元の状態で再度フェッチすると、ローカルブランチ上でマージされることです。非同期状態のため、このプルはきれいに適用されません。コミットが2回表示されるb0rken履歴が表示されます。これらすべてをgithub機能ブランチにプッシュすると、これらの変更は元のプルリクエストに反映され、非常にpullいものになります。

私の知る限り、実際にはこれに対する完全にクリーンなソリューションはありません。私が見つけた最良の解決策は、ローカルブランチをgithubブランチに強制的にプッシュすることです(実際には、高速ではない更新を強制的に実行します)。

Git-Push(1)によると:

Update the Origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the Origin repository.

引っ張らないで、次のようにプッシュを強制します。

git Push svg +user-non-unique

または:

git Push svg user-non-unique --force

これにより、実際にはローカルブランチのすべてでリモートブランチが上書きされます。リモートストリームにある(および失敗の原因となった)コミットはそのまま残りますが、コミットがダングリングし、最終的にgit-gc(1)によって削除されます。大きな問題ではない。

私が言ったように、これはAFAICSの最もクリーンなソリューションです。これのマイナス面は、PRが最新のコミットで更新されることです。これにより、後日取得され、PRのコメント履歴で同期がとれなくなる可能性があります。大きな問題はありませんが、混乱を招く可能性があります。

特定のabc1234リビジョンではなく、masterにバインドされた新しいプルリクエストを作成することもできます。

これにより、リポジトリへの新しいコミット/プッシュがプルリクエストに追加されます。

5
cfedermann