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
ベストアンサー1
要約:git branch --set-upstream-to origin/solaris
あなたが尋ねた質問(少し言い換えると「アップストリームを設定する必要がありますか」)に対する答えは、「いいえ、アップストリームを設定する必要はまったくありません」です。
ただし、現在のブランチにアップストリームがない場合、Git はgit push
、およびその他のコマンドに対する動作も変更します。
ここでのプッシュの完全なストーリーは長くて退屈で、Git バージョン 1.5 より前の履歴にまでさかのぼります。もっと短く言うと、はgit push
適切に実装されていませんでした。1 Git バージョン 2.0 の時点で、Git には と綴られた構成ノブがありpush.default
、デフォルトで になっsimple
ています。2.0 の前後のいくつかのバージョンの Git では、 を実行するたびに、Git は大量のノイズを吐き出して、黙らせるためだけにgit push
を設定するよう説得しようとしていました。push.default
git push
実行している Git のバージョンや を設定したかどうかについては言及されていないpush.default
ため、推測するしかありません。私の推測では、Git バージョン 2-point-something を使用していて、それを黙らせるために を に設定しているのでしょう。長くて退屈な歴史があるため、使用している Git のバージョンと、設定している場合のその内容はpush.default
重要ですが、結局のところ、Git からまた別の苦情を受けているという事実は、過去の間違いの 1 つを回避するように Git が設定されていることを示しています。simple
push.default
アップストリームとは何ですか?
アップストリームは、単に別のブランチ名であり、通常はリモート追跡ブランチであり、(通常のローカル)ブランチに関連付けられています。
すべてのブランチには、1 つのアップストリーム セットを持つオプションがあります。つまり、すべてのブランチにはアップストリームがあるか、アップストリームがないかのどちらかです。1 つのブランチに複数のアップストリームを持つことはできません。
アップストリームは有効なブランチである必要がありますが、そうである必要はありません ( のようなリモート追跡ブランチでも、 のようなローカル ブランチでも)。つまり、現在のブランチBにアップストリームUがある場合、は機能します。これが機能しない場合 (つまり、Uが存在しないというエラーが表示される場合)、Git のほとんどはアップストリームがまったく設定されていないかのように動作します。 などのいくつかのコマンドは、アップストリーム設定を表示しますが、それを「消失」としてマークします。origin/B
master
git rev-parse U
git branch -vv
アップストリームは何の役に立つのでしょうか?
がまたはpush.default
に設定されている場合、アップストリームの設定により、追加の引数なしで使用される が機能するようになります。simple
upstream
git push
以上です。 の場合、これがすべてです。しかし、 は単純なタイプミスが大きな問題を引き起こす場所の 1 つであるgit push
ため、これはかなり重要です。git push
が、、またはpush.default
に設定されている場合、アップストリームを設定しても には何も影響しません。nothing
matching
current
git push
(ここでは、Git のバージョンが少なくとも 2.0 であることを前提としています。)
上流の影響git fetch
git fetch
追加の引数なしで実行すると、Git は現在のブランチのアップストリームを参照して、どのリモートからフェッチするかを判断します。アップストリームがリモート追跡ブランチの場合、Git はそのリモートからフェッチします。(アップストリームが設定されていないか、ローカル ブランチの場合、Git は のフェッチを試みますorigin
。)
上流の影響git merge
もgit rebase
git merge
またはを追加の引数なしで実行するとgit rebase
、Git は現在のブランチのアップストリームを使用します。そのため、これら 2 つのコマンドの使用が短縮されます。
上流の影響git pull
とにかく2 は使用すべきではありませgit pull
んが、使用する場合は、git pull
アップストリーム設定を使用して、どのリモートからフェッチするかを判断し、どのブランチをマージまたはリベースするかを判断します。つまり、 はgit pull
と同じことを行いますgit fetch
(実際には が実行 されるため)。その後、またはgit fetch
と同じことを行います (実際にはまたはが実行されるため) 。git merge
git rebase
git merge
git rebase
(少なくとも、Git を十分に理解して、どちらかのステップが失敗したときに (最終的には失敗するでしょうが)、何が間違っていたのかを認識し、どう対処すればよいかがわかるようになるまでは、通常、これら 2 つのステップを手動で実行する必要があります。)
上流の影響git status
これは実際には最も重要かもしれません。アップストリームを設定したら、git status
コミットの観点から、現在のブランチとそのアップストリームの違いを報告できます。
通常の場合と同様に、B
アップストリームが に設定されているブランチにいるときに を実行すると、プッシュできるコミットや、マージまたはリベースできるコミットがあるかどうかがすぐに表示されます。origin/B
git status
これは、次の実行が原因ですgit status
。
git rev-list --count @{u}..HEAD
B
:にないコミットはいくつありますか?origin/B
git rev-list --count HEAD..@{u}
:にないコミットはいくつありますか?origin/B
B
アップストリームを設定すると、これらすべてが可能になります。
なぜmaster
すでにアップストリームセットがあるのですか?
最初にリモートからクローンを作成するときは、次のようにします。
$ git clone git://some.host/path/to/repo.git
または同様の場合、Git が行う最後のステップは、基本的に、 ですgit checkout master
。これにより、ローカル ブランチがチェックアウトされます。ただし、ローカル ブランチはありmaster
ません。master
一方、という名前のリモート追跡ブランチは存在します。origin/master
これは、クローンしたばかりだからです。
Git は、次のように意味していると推測します: 「master
remote-tracking と同じコミットを指す新しいローカルを作成しorigin/master
、ついでに、 のアップストリームを に設定しますmaster
。origin/master
」
これは、まだ作成していないすべてのブランチに対して発生しますgit checkout
。Git はブランチを作成し、対応するリモート追跡ブランチを「追跡」 (アップストリームとして作成) します。
しかし、これは新しいブランチ、つまりリモート追跡ブランチがまだないブランチでは機能しません。
新しいブランチを作成する場合:
$ git checkout -b solaris
現時点では、 はありませんorigin/solaris
。リモート追跡ブランチが存在しないため、ローカルでは追跡solaris
できません。origin/solaris
新しいブランチを初めてプッシュするとき:
$ git push origin solaris
は上に を作成し 、したがって自分の Git リポジトリにも を作成します。しかし、もう遅すぎます。すでにアップストリームのないローカル が存在します。3solaris
origin
origin/solaris
solaris
Git はそれを自動的にアップストリームとして設定するべきではないでしょうか?
おそらくそうです。「実装が不十分」と脚注 1 を参照してください。今変更するのは困難です。Git を使用するスクリプトは数百万4あり、その一部は Git の現在の動作に依存している可能性があります。動作を変更するには、新しいメジャー リリース、構成フィールドの設定を強制するナグウェアなどが必要です。つまり、Git は自身の成功の犠牲者です。現在 Git にどのような間違いがあっても、その修正は、変更がほとんど目に見えないか、明らかに大幅に改善されているか、時間をかけてゆっくりと行われるかのいずれかでなければできません。
実際のところ、中にまたは を使用しない限り、今日ではそうではありません。 これがメッセージが伝えている内容です。--set-upstream
-u
git 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 fetch
かがわかると、Git 初心者は物事をはるかgit merge
によく理解できると思います。git rebase
3最初の git push
asを実行する場合git push -u origin solaris
、つまりフラグを追加する場合、プッシュが成功した場合のみ、-u
Git は現在のブランチのアップストリームとして設定します。したがって、最初のプッシュで指定する必要があります。実際、それ以降のプッシュで指定することができ、その時点でアップストリームが設定または変更されます。ただし、忘れた場合は、その方が簡単だと思います。origin/solaris
-u
git branch --set-upstream-to
4とにかく、オースティン・パワーズ/ドクター・イービルの方法で測定すると、単に「1ミルル・ユン」と言うだけです。