2016-09-25 5 views
16

私の同僚は、オープンプルリクエストにいくつかの変更を行い、ローカルブランチに対してベースブランチをリベースします(しばしば、変更を以前のコミットに縮小する)押す。強制プッシュプルリクエストの旧バージョンと新バージョンの比較

古いバージョンのPRと新しいバージョンのPRの間で何が変更されたかを確認するにはどうすればよいですか?

は私がPRが最初に提起されたときにgit pullgit checkout $BRANCH_NAMEが、その後、git fetch、その後git diff $BRANCH_NAME..origin/$BRANCH_NAME PRが更新された後に行うことができると思います - しかし、それはまた、ベースブランチ(通常はマスター)に導入された変更を表示し、リベースを介してPRに持ち込んだ。そのノイズを取り除き、PR自体に何が変わったのかを表示することは可能ですか?

+0

実際、TopGitブランチを使用してTopGitブランチをプッシュしても、この問題は発生しません。つまり、TopGitブランチを見て、何が変更されたのかを知ることができます。なぜなら、TopGitはリベースの代わりにマージを行い、その後、PRを公開するときに、エクスポート(ヒストリを変更しない不安定なリベースのようなものです)のためです。それは私の同僚が彼らのgitのワークフローを変更する必要があります。 –

+0

2番目の考えでは、問題のあるマージの解像度がマージコミット内に隠れてしまう可能性があるため、常に問題を解決するとは限りません。 –

+0

サイドノート:GitHubは "rebase on merge"マージ戦略をサポートしていますので、実際にプルリクエストをリベースする必要はありません。 –

答えて

7

チェックアウトthisあなたが達成しようとしているものに非常に似た何かをしたい別の質問にお答えください。

それはこのように自分の状況を説明します。

newcommit -> the new pull request commit 
oldcommit -> the old pull request commit 
upstream -> the base branch commit the new pull request is based on 

は今、この操作を行います。

git commit-tree newcommit^{tree} -p oldcommit -p upstream -m "message" 
git show <commit id returned by previous command> 

をアイデアは、そのコミットツリーがoldcommitupstreamの間に偽のマージをnewcommitツリーを生成するため、含まれますです正確にnewcommitのコード。 現在のブランチはまったく変更されません。新しいヘッドレスコミットが作成され、そのIDが与えられます。 つまり、git showはすべての変更を競合解決としてリストします。これは、新しいPRと古い競合の正確な違いです。

これを可能にするには、gitリポジトリの前のPRをどこかに置く必要があります(強制的にプッシュが実行された場合、gitの履歴は書き換えられ、PCやあなたはサーバーreflogにアクセスできます)。これについての詳細は、VonCの回答を参照してください。

と仮定:

  • ベース支店:あなたはローカルで古いPRの分岐を有していてmaster
  • $BRANCH_NAME
  • リモートブランチでの新しいPR:origin/$BRANCH_NAME
あなたが好き行うことができます

これは:

# fetch locally upstream changes (origin/$BRANCH_NAME) 
git fetch 
# produce the fake merge commit 
git commit-tree origin/$BRANCH_NAME^{tree} \ 
     -p $BRANCH_NAME \ 
     -p `git merge-base master origin/$BRANCH_NAME` \ 
     -m "message" 
# see "fake" conflict resolution = difference between the two PR 
git show <commit id returned by previous command> 

git merge-baseは、2つのブランチ間の共通の祖先を見つけるために使用されます。この場合は、コミットIDを直接書くことができる場合は、新しいブランチがベースブランチに基づいています。

+0

それは賢いようです(私の答えよりも潜在的です)+1 – VonC

+1

あなたの答えは、とにかく便利です:)あなたがそれを説明するのに十分であったので、私はそれを書いていませんでした;) –

+0

'checkout -b'コマンドでは、あなたのHEADがその前にどこにあるのか明確にすることができました。 'temp'は' master'と同じ場所を指していますか? – Wildcard

6

分岐力押しの前のHEADが含まれるリモートレポのreflogでのみ利用できるようになるPR

、古いバージョン。
リモートリポジトリはGitHubなので、プッシュイベントを見ることで古いコミットを推測できます。「Does github remember commit IDs?」を参照してください。

帽子も正確に、あなたは常にベースからコミットが含まれる(共通の祖先に対する相違点がありますベースのブランチに導入された変更(通常はマスター)

詳細が表示されますmasterのような分岐)

What are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?

http://mythic-beasts.com/~mark/git-diff-help.png

を参照してください。

だからあなたの場合には、お使いの強制プッシュブランチは、リモートリポジトリ上で次のようになります。彼らはの一部であるとして

 x--x--x  (old branch in reflog) 
    /
m--M0--M--M (master) 
      \ 
      X--X--X (new branch forced push) 

差分old_HEAD..newHEADは、ベースブランチから数Mコミットが含まれるであろう共通の祖先(M0)パス。

これで、(プッシュイベントを監視し、そのブランチの前のHEADを知っていれば)強制プッシュされたブランチを比較できます。
しかし、共通の祖先パスがない2つのブランチを簡単に比較することはできません。

関連する問題