7

を使用してコードをプッシュしようとして$git push origin masterいますが、エラーが発生します

! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

私が行ったとき$ git fetch origin master$ git diff master origin/master2つのリポジトリ間で異なるすべてのファイルと変更のリストを取得しました. ただし、リモート リポジトリと最後$ git pull origin masterにローカル ボックスで実行したときとの間で変更されたファイルのリストにのみ関心があります。

これを行う方法はありますか?

4

3 に答える 3

7

git pull(または)git fetchが後に続くのと同じです。git mergegit rebase

git fetchどの参照が更新されたかを示します。次のように表示されます。

a8e5e4e..295bf31  master     -> origin/master

これは、最後にマスターをフェッチしたときは a8e5e4e で、現在は 295bf31 であることを意味します。次のような方法で、変更されたファイルを確認できます。

git diff --name-status a8e5e4e..295bf31

しかし、さらに興味深いのはgitk master...origin/master、フェッチ後の出力です。このようにして、自分側の変更とオリジン側の変更の両方を検査できます。

于 2013-08-18T08:26:06.413 に答える
5

michas の答えは、尋ねられた質問に対する正しい答えです。

古い参照、つまり のa8e5e4e部分がない場合はどうなりますa8e5e4e..295bf31 master -> origin/masterか? おそらく、あなたは実際には気にしません。彼が示唆したように、見るmaster...origin/masterことはさらに興味深いことです。1 しかし、この 3 つのドットの...構文は実際には何を意味するのでしょうか?

答えはgit rev-listドキュメントにあります:

もう 1 つの特別な表記法は<commit1>...<commit2>、マージに役立つものです。結果として得られるコミットのセットは、2 つのオペランド間の対称的な違いです。...

私が思うに、これは十分に紛らわしい言い回しです (実際にgit diffはまったく異なる意味を使用しています)。しかし、実際にはそれほど複雑ではありません。

次のように描画できるいくつかのコミットがあるとします。

master  origin/master

   E       G
   |       |
   D       F
     \   /
       C
       |
       B
       |
       A

あなたが持っているのは commit での相違Cです。masterorigin/masterの両方が を指しているときに、あなたは仕事を始めましたC。明らかに、あなたは と をコミットDE、「彼ら」 (誰であれ) は と をコミットFGました。Cちなみに、コミットはマージベースと呼ばれます。

master...origin/masterつまり、私を見つけて、C左側と右側の両方で、「そこから」すべてを渡してください。つまり、 と の両方のすべてのコミットでmaster あり origin/master、それらが最初に出会ったポイント以下のコミットは除外されます。

実行すると、それが表示されgitk master...origin/masterます: 2あなたが行ったすべてのコミットと、それらが行ったすべてのコミット。しかし、 を実行すると、これのほとんどが破棄されます。代わりに、右側の名前に対してマージ ベース3と diffを見つけます。git diff flags master...origin/mastergit diffC

master自分のブランチにいると仮定すると(つまり、HEAD単に「マスター」を意味します)、これをさらに短くすることができます。あなたのブランチと彼らのブランチが分岐してから変更されたファイルを確認するには、次のコマンドを実行します。

$ git diff --stat ...origin/master   # or --name-status, etc

名前を省略すると を意味するHEADので、これは とHEAD...origin/master同じmaster...origin/masterです。

git が十分に新しい場合@{u}は、「現在のブランチの上流ブランチ」(つまり、 from master、 find origin/master) を参照するため、次を実行できます。

$ git diff --stat '...@{u}'

(引用符はシェルからブレースを保護するためのものです。特定のシェルでは必要な場合とそうでない場合があります)。これは、アップストリームとして使用している場合でも、アップストリームとして使用しdevelopている場合でも機能します。origin/developfeatureXorigin/featureX


1持っていない場合はgitk、次を試してください。

$ git log --graph --boundary ...origin/master

(または'...@{u}'上記のとおり)。--boundaryマージコミットを含める必要があります。追加することもでき--oneline --decorateます。

2実際gitkには、脚注 1 のコマンドと同様に、マージ コミットも表示されます。つまり--boundary、ミーティング ポイント コミットを含めるために使用します (これはマージ ベースとまったく同じではありませんが、十分に近いものです)。

3これは、マージ ベース コミットが 1 つだけあることを前提としています。これらの場合、それは真実であるべきです。そこで、上流の分岐の先頭にあるツリーと forgit diffのツリーを比較します。おそらく恣意的な長いドライブで彼らが訪れた中間点に関係なく、「彼らがいた場所」と「彼らがたどり着いた場所」を比較します。:-) たとえば、commitでファイルを追加してから commitで再度削除すると、そのファイルは表示されません。CGFthis/thatG

于 2013-08-18T15:44:14.800 に答える