「git push --set-upstream origin <branch>」を実行する必要があるのはなぜですか?


146

SolarisとSun Studioをテストするためのローカルブランチを作成しました。次に、ブランチを上流にプッシュしました。変更をコミットし、変更をプッシュしようとした後:

$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
 1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin solaris

なぜこれのために特別なことをしなければならないのですか?

誰かがを作成<branch><branch>てリモートにプッシュし、次にコミットが必要で<branch>はないと主張する合理的なユースケースはあります<branch>か?


私はこの質問と回答をStack Overflowでフォローしました。新しいローカルブランチをリモートGitリポジトリにプッシュし、それも追跡します。私は、不完全または間違った受け入れられた回答の別の例を推測しています。または、Gitの別のインスタンスが単純なタスクを取り、それを難し​​くしています。


これが別のマシンでのビューです。ブランチが明確に存在するため、作成およびプッシュされました。

$ git branch -a
  alignas
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris


2
@Alexiに感謝します。残念ながら、引用されたdupは、デフォルトで表されているとんでもない使用例を説明していません。(これらは修辞的な質問ではありません。私はUXデザインの理由に本当に興味があります)。
jww 2017年

1
これは構成可能であることに注意してください。あなたが行う場合はgit config --add push.default current、必要に応じて、その後にgit pushは自動的にリモートレポにブランチを作成します。
Gogowitsch

回答:


271

TL; DR: git branch --set-upstream-to origin/solaris


あなたが尋ねた-た「私は、上流を設定する必要があります」と、私は少し言い換えます質問への答えは、-is:いいえ、あなたはしていない持っているすべてのアップストリームを設定します。

ただし、現在のブランチのアップストリームがない場合、Gitはgit push、および他のコマンドの動作も変更します。

ここでの完全なプッシュストーリーは長く退屈で、Gitバージョン1.5より前の歴史にさかのぼります。それを全体的に短くするために、git push不十分に実装されました。1 Gitバージョン2.0以降、Gitには、push.defaultデフォルトでに設定された設定ノブが付いていますsimple。2.0より前と後のいくつかのバージョンのGitでは、実行するたびにgit push、Gitは多くのノイズを吐き出して設定を説得しようとしますpush.defaultgit pushて、シャットダウンするためだけに。

実行しているGitのバージョンや、設定したかどうかについては触れていないpush.defaultため、推測する必要があります。私の推測では、あなたはGitバージョン2ポイント何かを使用しており、それをシャットダウンするように設定push.defaultsimpleていると思います。長くて退屈な歴史があるためpush.default、正確にどのバージョンのGitを使用しているのか、また何を設定したのか重要ですが、結局、Gitからさらに別の苦情が寄せられているという事実、Git 過去の間違いの1つを回避するように構成されています。

アップストリームとは何ですか?

上流は、単に(通常、ローカル)分岐に関連する別の支店名、通常のリモート追跡ブランチです。

すべてのブランチには、1つのアップストリームセットを持つオプションがあります。つまり、すべてのブランチにアップストリームがあるか、アップストリームがないかです。ブランチが複数のアップストリームを持つことはできません。

アップストリーム、有効なブランチである必要がありますが、そうである必要はありません(リモート追跡のようなものか、ローカルのようなものか)。つまり、現在のブランチBにアップストリームUがある場合、動作するはずです。それが機能しない場合、つまりUが存在しないというメッセージが出た場合、ほとんどのGitは、アップストリームがまったく設定されていないかのように動作します。のようないくつかのコマンドは、上流の設定を表示しますが、「なくなった」とマークします。origin/Bmastergit rev-parse U git branch -vv

アップストリームとは何ですか?

あなたがいる場合push.defaultに設定されているsimpleupstream、上流の設定が行いますgit pushなし追加の引数、ちょうど仕事で使用し、。

それだけです—それだけですgit push。しかし、これgit pushはかなり重要です。なぜなら、単純なタイプミスが大きな頭痛の種となる場所の1つだからです。

あなたがいる場合push.defaultに設定されているnothingmatchingまたはcurrent、上流を設定すると、すべてのために何もしませんgit push

(これはすべて、Gitのバージョンが2.0以上であることを前提としています。)

上流の影響 git fetch

git fetch追加の引数なしで実行すると、Git は現在のブランチの上流を調べて、どのリモートからフェッチするを判断します。アップストリームがリモート追跡ブランチの場合、Gitはそのリモートからフェッチします。(アップストリームが設定されていないか、ローカルブランチの場合、Gitはフェッチを試みoriginます。)

上流も影響git mergegit rebaseます

実行するgit merge場合git rebase、または追加の引数を指定しない場合、Gitは現在のブランチの上流を使用します。したがって、これらの2つのコマンドの使用が短縮されます。

上流の影響 git pull

あなたはいけ2使用git pullとにかく、しかし、あなたがしなければ、git pullどのリモートブランチとマージやリベースに続いからフェッチし、ためにどの把握する上流の設定を使用します。つまり、git pull同じことをやっgit fetchて、実際に-because 実行します git fetch -そしてその後、同じことをしgit mergeたりgit rebase、それ実際にあるため実行 git mergegit rebase

(通常、少なくとも2つのステップを手動で実行する必要があります。少なくとも、どちらかのステップが失敗した場合にGitが十分に理解できるまでは、いずれかのステップが失敗し、最終的に何が問題だったかを認識し、それに対して何をすべきかを知っています。)

上流の影響 git status

これは実際には最も重要かもしれません。アップストリームセットを取得したら、git statusを取得すると、コミットに関して、現在のブランチとそのアップストリームの違いを報告できます。

通常の場合と同様に、Bアップストリームがに設定されているブランチ上でを実行すると、プッシュできるコミットやマージまたはリベースできるコミットがあるかどうかがすぐにわかります。origin/Bgit status

これはgit status実行するためです:

  • git rev-list --count @{u}..HEAD:コミットされBていないコミットはいくつありますか?origin/B
  • git rev-list --count HEAD..@{u}:コミットされていないコミットはいくつありますか?origin/BB

アップストリームを設定すると、これらすべてが得られます。

どうしてmaster既にアップストリームセットが存在するのですか?

いくつかのリモートから最初にクローンを作成するとき、次を使用します:

$ git clone git://some.host/path/to/repo.git

または同様に、Gitが行う最後のステップは、本質的にはgit checkout masterです。お近くの支店アウトこのチェックはmaster-onlyあなたはしていない持っているローカルブランチをmaster

一方、あなたはないリモート追跡ブランチは、名前の持っているorigin/masterあなたはそれをクローン化しているため、。

Gitは、「masterリモートトラッキングと同じコミットを指す新しいローカルを私に作成origin/masterし、その間にアップストリームをmasterに設定する」ことを意味していたと推測しますorigin/master

これは git checkoutまだ持っていないすべてのブランチでします。Gitはブランチ作成し、対応するリモート追跡ブランチを「追跡」(上流として機能)させます。

しかし、これは動作しません 新しいブランチ、つまりまだリモート追跡ブランチがないブランチでは機能しません

あなたが作成した場合 新しいブランチ:

$ git checkout -b solaris

まだありませんorigin/solaris。あなたの地元solaris origin/solaris存在しないため、リモート追跡ブランチを追跡できません。

新しいブランチを最初にプッシュしたとき:

$ git push origin solaris

作成 solarisされるoriginためorigin/solaris、独自のGitリポジトリにも作成されます。しかし、それは遅すぎる:あなたはすでにローカル持っているsolarisことを何の上流を持っていませんが

今のところ、Gitはそれを自動的にアップストリームとして設定すべきではありませんか?

恐らく。「正しく実装されていない」と脚注1を参照してください。は変更が難しい:数百万です。Gitを使用するスクリプト 4、現在の動作に依存するスクリプトもあります。動作を変更するには、新しいメジャーリリース、いくつかの構成フィールドを設定するように強制するnag-wareなどが必要です。つまり、Gitはそれ自体の成功の犠牲者です。Gitにあるどんな誤りでも、今日、変更がほとんど目に見えないか、明らかにはるかに優れているか、時間の経過とともにゆっくりと行われる場合にのみ修正できます。

実際には、あなたが使用中または中にない限り、それは今日ではありません--set-upstream-ugit push。それがメッセージが伝えていることです。

そのようにする必要はありません。さて、前述したように、それを行う必要はまったくありませんが、アップストリームが必要だとしましょう。あなたは既にブランチを作成したsolaris上でorigin、以前のプッシュを通じて、そしてあなたのようgit branch出力を示し、あなたはすでに持っています origin/solarisあなたのローカルリポジトリに。

あなたはそれを上流として設定していません solaris

最初のプッシュ時ではなく、今すぐ設定するには、を使用しますgit branch --set-upstream-to--set-upstream-toサブコマンドは、既存のブランチの名前を取り、などorigin/solaris、そしてそのほかのブランチに現在のブランチの上流を設定します。

それだけです—それだけです—しかし、上記のすべての影響があります。これは、追加の手間をかけずに、を実行しgit fetch、次に見回してから、git mergeまたは必要git rebaseに応じて、新しいコミットを作成して実行できることを意味しますgit push


1公平を期すために、当初は初期実装にエラーが発生しやすいことが明確ではありませんでした。それは、すべての新しいユーザーが毎回同じミスを犯したときにのみ明らかになりました。現在は「それほど貧しい」ではなく、「素晴らしい」とは言えません。

2「まったくない」は少し強いですが、Gitの初心者は、特にgit fetch実際に何をしたかを示し、次に何をするか、git mergeまたは何をするかgit rebaseを確認できるようにすると、ステップを分けるとかなり理解しやすくなります。

3 最初の git pushように実行する場合git push -u origin solaris、つまり-uフラグを追加するorigin/solaris場合、プッシュが成功した場合(かつその場合のみ)、Gitは現在のブランチの上流に設定されます。したがって-u最初のプッシュで供給する必要があります。実際、後のプッシュでそれを供給することができ、その時点でアップストリームを設定または変更します。でもgit branch --set-upstream-to、忘れた方が簡単だと思います。

4いずれにしても、オースティン・パワーズ/ドクター・イービルの「1つのMILLLL-YUN」とだけ言う方法で測定。


2
一般的なケースが{ブランチの作成/ブランチのプッシュ/ブランチの使用}である場合、新しいローカルブランチをリモートGitリポジトリプッシュし、それを追跡した結果も実際に機能するものではありませんか?そして、誰かが{ブランチを作成する/ブランチをプッシュする/ブランチを使用しない}ことを望むなら、彼らは特別な何かをしなければならないのではない--set-upstream /dev/nullでしょうか?なぜ一般的なケースに負担がかかるのですか?私はこれらのエンジニアリングとユーザビリティの決定のいくつかを本当に理解していません。
jww 2016年

1
@VonC:そうです、それがのポイントですgit push -uが、それは本当にgit push -uデフォルトであるようです、または少なくともアップストリームがまだない場合はデフォルトでありgit push --no-set-upstream現在アップストリームがなく、維持したい場合はaがあるはずですそのように(理解できない理由があれば:-))。
torek 2016年

2
「あなたはGitを「本当に不愉快な」ものとして書いたと思うので、あなたはこのような質問を続けます。」このような憶測はお控えください。私もこの種の質問をしているので、この質問に出くわしました。私は世界最高のUXデザイナーではありませんが、この特定のシナリオでのデフォルトの動作の方が優れていることもあります。
Steven Byks 2016年

4
@torek-ありがとう。そうでなければあなたの答えは素晴らしかった。よく考えられ、よく構造化されており、非常に有益です。:-)
Steven Byks 16

6
これは構成可能であることに注意してください。あなたが行う場合はgit config --add push.default current、必要に応じて、その後にgit pushは自動的にリモートレポにブランチを作成します。
Gogowitsch

31

違い
git push origin <branch>

git push --set-upstream origin <branch>
、あなたが違いに気づくことを引っ張るときにリモートリポジトリにうまく両方のプッシュが、それはだということです。

あなたがする場合:
git push origin <branch>
引っ張るとき、あなたはしなければなりません:
git pull origin <branch>

しかし、あなたがそうするならば:
git push --set-upstream origin <branch>
引っ張るとき、あなたはしなければならないだけです:
git pull

したがって、を追加すると、実行--set-upstreamするたびにどのブランチからプルするかを指定する必要がなくなりますgit pull


「git push」の2つのバージョンの違い。なぜそれらを使用したい、または使用する必要があるのか​​わかりません。無意味!
フランクパック

17

基本的に完全なコマンドはのようなものgit push <remote> <local_ref>:<remote_ref>です。だけを実行した場合git push、gitが決定を下すのに役立つ設定を行わない限り、gitは正確に何をすべきかわかりません。gitリポジトリでは、複数のリモートをセットアップできます。また、ローカル参照をリモート参照にプッシュすることもできます。完全なコマンドは、プッシュを行う最も簡単な方法です。入力する単語の数を減らしたい場合は、最初に--set-upstreamのように設定する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.