なぜgit branch --unset-upstreamを呼び出して修正するのですか?


161

gitの高度な操作に関しては、私は初心者です。私はブログフレームワークOctopressを使用してブログを管理しています。Octopressは2011年以降開発されていませんが、それは私の目的を十分に果たしているので、今のところ何も変更することは考えていません。

ちなみに、私のブログはGithubページでホストされています。

今日、新しい投稿の作成中にgit status、次のメッセージが表示されました:

On branch source
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

同じメッセージのような、すべての後続のコマンドについて繰り返しgit add .git commit -m 'message'そしてgit push origin source

  • メッセージはどういう意味ですか?
  • 何かが壊れていますか?
  • はいの場合、何ですか?
  • 修正する必要がありますか?

できれば、pdf / webの記事を参照してください。この記事を読んで理解できるので、今後の参考にしてください。

詳細:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/origin/source

さらに情報が必要な場合はお知らせください。ありがとう。

回答:


197

TL; DRバージョン:origin/master以前はリモートトラッキングブランチが存在していましたが、現在は存在しないため、ローカルブランチsourceは存在しないものを追跡しているため、疑わしいだけです。 Gitはそれについて警告しています。「アップストリームトラッキング」機能が意図したとおりに機能することなく問題なく進んでいるため、何かを変更するかどうかはあなた次第です。

アップストリーム設定の別の方法については、なぜ「git push --set-upstream origin <branch>」を実行する必要があるのか​​を参照してください


この警告はGitの新しいもので、Git 1.8.5で最初に登場しました。リリースノートには、短い箇条書きが1つだけ含まれています。

  • 「git branch -v -v」(および「git status」)は、他のブランチに基づいていないブランチ、上流のブランチと同期しているブランチ、および上流で設定されているブランチを区別しませんでした存在しないブランチ。

それが何を意味するかを説明するには、まず「リモート」、「リモート追跡ブランチ」、およびGitが「アップストリームの追跡」を処理する方法について知る必要があります。(リモートトラッキングブランチはひどく欠陥のある用語です。代わりにリモートトラッキング名を使い始めましたが、これは少し改善されたと思います。ただし、以下では、Gitのドキュメントとの整合性を保つために「リモートトラッキングブランチ」を使用します。 )

それぞれ、「リモート」のように、単に名前であるoriginか、octopressこのケースでは。それらの目的は、あなたgit fetchまたはgit pull更新元の場所の完全なURLなどを記録することです。1を使用すると、Gitは(保存されたURLを使用して)そのリモートにアクセスし、適切な一連の更新を引き継ぎます。また、「リモート追跡ブランチ」を使用して更新を記録します。git fetch remote,

「リモート追跡ブランチ」(またはリモート追跡名)は、単に「リモート」で最後に見たブランチ名の記録です。各リモートはそれ自体がGitリポジトリであるため、ブランチがあります。リモートの "origin"のブランチは、のローカルリポジトリに記録されますremotes/origin/。あなたが示したテキストは、名前付きブランチがあることを言うsourceにはorigin、名前付きの支店2.1linklogなどにoctopress

(もちろん、「通常」または「ローカル」ブランチは、自分のリポジトリに作成したブランチ名にすぎません。)

最後に、(ローカル)ブランチを設定して、「リモートトラッキングブランチ」を「追跡」することができます。ローカルブランチLがリモートトラッキングブランチを追跡するように設定されるとR、GitはRその「アップストリーム」を呼び出して、(コミットに関して)アップストリームの「先」または「後ろ」のどちらであるかを通知します。これは、ローカルブランチのために(でもお勧め可能な)普通のことだとリモート追跡の枝のように、(リモートプレフィックス部分を除く)と同じ名前を使用するsourceorigin/source、それは実際には必要ありません。

そしてこの場合、それは起こっていません。sourceリモート追跡ブランチを追跡するローカルブランチがありorigin/masterます。

Gitがリモートブランチを追跡するためにローカルブランチをセットアップする方法の正確なメカニズムを知っている必要はありませんが、それらは以下に関連するので、これがどのように機能するかを示します。まず、ローカルブランチ名から始めますsource。この名前を使用する2つの構成エントリー、spelled branch.source.remoteおよびがありbranch.source.mergeます。表示された出力から、両方が設定されていることが明らかであるため、指定されたコマンドを実行すると、次のように表示されます。

$ git config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master

これらをまとめると、2これは、ブランチsourceが「リモート追跡ブランチ」を追跡することをGitに伝えますorigin/master

しかし、今度はの出力を見git branch -aてください。これは、リポジトリ内のすべてのローカルおよびリモート追跡ブランチ名を示しています。リモートトラッキング名はremotes/...にリストされ、はありませんremotes/origin/master。おそらく一度はあったと思われますが、今はなくなっています。

Gitは、を使用て追跡情報を削除できることを通知しています--unset-upstream。これは、両方をクリアしますbranch.source.originbranch.source.merge、警告を停止します。

しかし、あなたが望むのは、追跡から別のものの追跡に切り替えるorigin/masterことです。おそらくorigin/sourceoctopress/名前の1つです。

これはgit branch --set-upstream-to3で実行できます。例:

$ git branch --set-upstream-to=origin/source

(もしあなたがまだブランチ「ソース」origin/sourceにいて、それがあなたが望むアップストリームであると仮定します-でも、もしあれば、実際にあなたが望むものを私が知る方法はありません)。

既存のGitブランチをリモートブランチに追跡させる方法も参照してください

ここにたどり着いた方法は、最初にを作成したgit cloneときに、クローン元からブランチにブランチがあったことだと思いますmastermaster追跡するように設定されたブランチもありましたorigin/master(これはgitの通常の標準セットアップです)。これは、あなたが持っていた意味branch.master.remotebranch.master.mergeセットにoriginしてrefs/heads/master。しかし、その後、originリモコンの名前がからmasterに変更されましたsource。一致するように、あなたのローカル名もからmasterに変更したと思いますsource。これにより、設定の名前branch.master.remoteto branch.source.remoteとfrom branch.master.mergeからbranch.source.merge...に変更されましたが、古いが残っているため、branch.source.merge間違っていました。

「上流」のリンケージが壊れたのはこの時点でしたが、1.8.5より古いGitバージョンでは、Gitは壊れた設定に気づくことはありませんでした。1.8.5ができたので、これが指摘されています。


これはほとんどの質問をカバーしますが、「修正する必要があるか」という質問はカバーしません。(例えば)を実行することにより、何年にもわたって壊れやすさを回避している可能性があります。それを続ければ、問題は回避されます。つまり、いいえ、それを修正する必要ありません。必要に応じて、を使用してアップストリームを削除し、苦情を停止できます。ローカルブランチにアップストリームがないとマークされていなくてもかまいません。git pull remote branchgit pull origin source--unset-upstreamsource

アップストリームを持つことのポイントは、さまざまな操作をより便利にすることです。たとえば、アップストリームが正しく設定されている場合、通常、「git fetchフォローするgit merge」は「正しいことを行います」。git statusその後git fetch、そのブランチのリポジトリがアップストリームのリポジトリと一致するかどうかを通知します。

便利にしたい場合は、アップストリームを再設定してください。


1git pullはを使用しgit fetch、Git 1.8.4以降、これは(ついに!)「リモート追跡ブランチ」情報も更新します。古いバージョンのGitでは、更新はgit pullでのみリモート追跡ブランチに記録されませんでしたgit fetch。Gitは少なくともバージョン1.8.5でなければならないため、これは問題ではありません。

2さて、これに加えて、私が故意に無視している構成行は、の下にありremote.origin.fetchます。Gitは「マージ」名をマッピングして、リモートブランチの完全なローカル名がであることを理解する必要がありrefs/remotes/origin/masterます。それは予測可能ですので、マッピングは、ほとんど常に、しかし、ちょうどこのように動作しますmasterになりますorigin/master

3それとも、とgit config。アップストリームorigin/sourceを変更する必要がある唯一の部分に設定したい場合はbranch.source.merge、それgit config branch.source.merge refs/heads/source を行います。しかし--set-upstream-to言うあなたがそうそれは「より良い方法」だというあなたは手動でそれを自分で行う行く作るよりも、行って欲しいです。


3
+1「必要に応じて、-unset-upstreamを使用して、ローカルブランチにアップストリームがまったくないとしてマークを付けることができます。」
BeatriceThalo

157

torekの答えはおそらく完璧ですが、元の質問で説明されたものとは異なる別のケースを記録に記載したかっただけですが、同じエラーが表示される場合があります(同様の問題を抱えている他の人を助けるため)。

git init --bareサーバーの1つを使用して空の(新しい)リポジトリを作成しました。次にgit clone、自分のPCのローカルワークスペースに移動しました。

ローカルリポジトリで単一のバージョンをコミットした後、を呼び出しgit statusた後にそのエラーが発生しました。

トレックの答えに続いて、ローカルの作業ディレクトリリポジトリの最初のコミットが「マスター」ブランチを作成したことが起こったことを理解しています。しかし、リモートリポジトリ(サーバー上)には何もないため、「マスター」(リモート/オリジン/マスター)ブランチさえありませんでした。

git push origin masterローカルリポジトリから実行した後、リモートリポジトリにマスターブランチが作成されました。これにより、エラーが表示されなくなりました。

結論として、「master」を含むブランチがないため、コミットがゼロの新しい新しいリモートリポジトリでは、このようなエラーが発生する可能性があります。


6
これは現在、このエラーメッセージのnr 1の結果でOn branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)あり、主観的ではありますが、空のリポジトリを複製して、ここで代替の回答を得ることができることが原因である可能性が高くなります。
Bella

2
それが空のファイルであっても、README.mdファイルで新しいリポジトリを初期化することは常に良い考えである理由だと思います
Ahmed Hussein

8

これで問題が解決する可能性があります。

変更を行った後、コミットしてから

git remote add origin https://(address of your repo) it can be https or ssh
then
git push -u origin master

それがあなたのために働くことを願っています。

ありがとう


1
これは確かに役立ちます-理由は私の答えに詳しく記載されています(要するに-これにより、リモートリポジトリに不足しているマスターブランチが作成されます)。
ElazarR 2016

7

私にとって、.git/refs/origin/master腐っていました。

私は次のことを行いましたが、問題は解決しました。

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master

0

実際、トレックは、私ができるよりもはるかに優れたツールの使用方法をすでに説明しています。ただし、この場合、http://octopress.org/docs/deploying/github/のガイドラインに従っている場合は、特異な点を指摘することが重要だと思います。つまり、セットアップ複数のgithubリポジトリがあることになります。まず第一にあなたのウェブサイトのすべてのソースコードを含むもの、たとえばディレクトリ$WEBSITE、次にそこにある静的生成ファイルのみを含むもの$WEBSITE/_deployです。セットアップの面白い点は、このセットアップが実際に機能するよう.gitignore$WEBSITEディレクトリにファイルがあることです。

十分な紹介。この場合、エラーはのリポジトリからも発生する可能性があります_deploy

cd _deploy

git branch -a
* master
remotes/origin/master
remotes/origin/source

では.git/configあなたは、通常、このような何かを見つける必要があります。

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

しかし、あなたの場合、ブランチマスターにはリモートがありません。

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*

次の方法で解決できます。

cd _deploy
git branch --set-upstream-to=origin/master

したがって、すべてはtorekが言ったとおりですが、これは_deployWebサイトのルートではなくディレクトリに関係している可能性があることを指摘することが重要な場合があります。

PS:次のようなシェルを使用する価値があるかもしれないzshgit、将来的にこの事に刺されないようにするプラグイン。_deploy別のリポジトリに関係していることがすぐにわかります。


0

私はこの質問を2回受けましたが、それは常に私のローカルブランチのgitキャッシュファイルの破損が原因でした。不足しているコミットハッシュをそのファイルに書き込むことで修正しました。サーバーから適切なコミットハッシュを取得し、次のコマンドをローカルで実行しました。

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch

0

問題:あなたのブランチは 'origin / master'に基づいていますが、上流はなくなっています。

解決策:git branch --unset-upstream


3
Stackoverflowへようこそ。問題は、エラーをどのように修正できるかではなく、このエラーが発生する理由と、何かエラーを修正する必要があるかどうかを知りたいと考えています。回答でこれに対処してください。
cronoik

0

次のコマンドでローカルブランチを削除します

git branch -d branch_name

あなたもできる

git branch -D branch_name 

基本的に削除を強制します(ローカルがソースにマージされていない場合でも)

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