436

これは実際にどのようにして起こりますか?

現在、私は1つのリポジトリで作業しているので、これが私のワークフローです。

  1. ファイルを変更する
  2. 専念
  3. 満足するまで1-2を繰り返します
  4. マスターにプッシュ

次に、aを実行するgit statusと、ブランチがXコミット(おそらく、私が行ったのと同じ数のコミット)だけ進んでいることがわかります。コードをプッシュしても、ローカルにキャッシュされたファイル(.gitフォルダー内)が実際には更新されないためですか?git pullこの奇妙なメッセージを「修正」しているようですが、なぜそれが発生するのかまだ興味があります。おそらくgitを間違って使用していますか?


メッセージに出力されるブランチを含む

私の地元の支店はマスターよりも進んでいます

現在のブランチをどこにプッシュ/プルしますか

私はGitHubにプッシュし、その時点で作業しているコンピューターをプルします。ローカルコピーは、作業しているのは私だけなので、常に完全に最新です。

実際にはリモートリポジトリをチェックしません

それが私が思ったものであり、私はそれについての私の理解が正しいことを確認するだろうと思いました。

あなたはそれにいくつかの余分な議論を渡していますか?

私が見ることができるものではありません、多分私の側で起こっているいくつかの面白い設定がありますか?

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
4

21 に答える 21

527

を実行した後にこのメッセージが表示された場合はgit pull remote branch、フォローアップしてみてくださいgit fetch。(オプションでgit fetch -p、リポジトリから削除されたブランチを整理するために実行します)

Fetchは、リモートブランチのローカル表現を更新するようです。これは、を実行したときに必ずしも発生するわけではありませんgit pull remote branch

于 2010-07-24T05:26:11.887 に答える
177

使用する

git pull --rebase

--rebaseオプションは、gitがローカルコミットを脇に移動し、リモートと同期してから、新しい状態からコミットを適用しようとすることを意味します。

于 2014-03-13T15:19:52.257 に答える
121

これらの3つの簡単なコマンドを使用します

ステップ1git checkout <branch_name>

ステップ2git pull -s recursive -X theirs

ステップ3git reset --hard origin/<branch_name>

詳細:https ://stackoverflow.com/a/39698570/2439715

楽しみ。

于 2016-09-26T08:59:58.120 に答える
52

私はあなたがメッセージを誤解していると思います—あなたのブランチは先を行っていませんmaster、それ masterです。これは、最後の、、、またはからのリモートリポジトリのステータスを記録するリモート追跡ブランチorigin/masterであるの前にあります。それはあなたがしたことを正確に伝えています。あなたはリモートの前に出て、それはあなたにプッシュすることを思い出させます。pushpullfetch

于 2010-03-12T19:54:30.393 に答える
40

これは私のために働いた

git reset --hard origin/master

出力は次のようになります。

On branch dev HEAD is now at ae1xc41z Last commit message

于 2019-05-29T07:25:42.687 に答える
27

誰かがあなたがあなたのメッセージを誤解しているかもしれないと言いました、あなたはそうではありません。この問題は実際には<project>/.git/configファイルに関係しています。これに似たセクションがあります:

[remote "origin"]
    url = <url>
    fetch = +refs/heads/*:refs/remotes/origin/*

プロジェクトの.git/configファイルからフェッチ行を削除すると、「ブランチはNコミットによって「origin/master」よりも進んでいます」を停止します。発生からの迷惑。

またはそう願っています。:)

于 2010-12-04T02:44:29.310 に答える
25

プルのみを行うステージサーバーでこの問題が発生しました。また、ハードリセットを使用すると、HEADをリモートと同じようにクリーンアップできました。

git reset --hard origin/master

だから今、私は再び持っています:

On branch master
Your branch is up-to-date with 'origin/master'.
于 2016-09-06T09:28:03.127 に答える
12

私はこのページのすべての解決策を調べましたが、幸いなことに@ anatolii-pazhynは、彼の解決策がうまくいったのでコメントしました。残念ながら、私は彼を賛成するのに十分な評判がありませんが、最初に彼の解決策を試すことをお勧めします:

git reset --hard origin/master

それは私に与えました:

HEAD is now at 900000b Comment from my last git commit here

私もお勧めします:

git rev-list origin..HEAD
# to see if the local repository is ahead, push needed

git rev-list HEAD..origin
# to see if the local repository is behind, pull needed

次のものも使用できます。

git rev-list --count --left-right origin/master...HEAD
# if you have numbers for both, then the two repositories have diverged

幸運を祈ります

于 2016-12-06T08:31:52.817 に答える
12

私の場合は、を使用してマスターに切り替えたためです

 git checkout -B master

代わりに新しいバージョンをプルするだけです

 git checkout master

最初のコマンドは、マスターのヘッドを最新のコミットにリセットします

使用しました

git reset --hard origin/master

それを修正するには

于 2016-12-15T07:03:26.803 に答える
8

注:この特定の質問は、私がこの回答を書いている時点では、かなり古いものです。これらの問題の多くを修正したバージョンのGitが最初にリリースされる3年前に投稿されました。 ただし、説明者と一緒に最新の回答を追加する価値があるようです。 既存の受け入れられた回答git fetch -pは、実行することを示唆しています。1これは良い考えですが、最近はあまり必要とされていません。Gitバージョン1.8.2がリリースされる前に、それははるかに必要でした。そのGitは最初の質問から3年後にリリースされました。


1-p or--pruneオプションは必須ではなく、リンクされた回答で括弧内にのみ提案されています。それが何をするかについては、以下のより長いセクションを参照してください。


これは実際にどのようにして起こりますか?

元の質問は次のとおりです。

これは実際にどのようにして起こりますか?

問題のこれは、後git push origin masterにOPが実行されgit status、メッセージが表示されたOn branch masterYour branch is ahead of 'origin/master' by 1 commit. 、質問に適切に回答するには、それを細かく分割する必要があるという事実です。

まず、各(ローカル)ブランチにはアップストリーム設定があります

この主張は実際には少し強すぎます。独自のGitリポジトリ内の各ローカルブランチは、 Gitがアップストリームを呼び出す1つの設定を持つことができます。または、そのブランチにアップストリームを含めることはできません。古いバージョンのGitは、これをアップストリーム設定と呼ぶことについてあまり一貫性がありませんでしたが、最新のGitでは、より一貫性があります。また、アップストリームを設定またはクリアするための機能もあります。git branch --set-upstream-togit branch --unset-upstream

これらは、現在のブランチ--set-upstream-to--unset-upstream影響します。現在のブランチは、あなたが言っているとき、またはそれが何を言っているときでも、あなたがいるブランチです。このブランチは、または(Git 2.23以降)<code>gitスイッチを使用して選択します。2 チェックアウトしたブランチが何であれ、それが現在のブランチです。3ongit statuson branch xyzzygit checkout

を使用する--unset-upstreamと、現在のブランチのアップストリームが削除されます。アップストリームがない場合、これにより、先行または遅延、または分岐に関するメッセージが停止します。ただし、このメッセージは役立つことを目的としているため、アップストリームを削除して、発生を停止させるべきではありません。(メッセージが役に立たない場合は、メッセージを無視してください。結局のところ、エラーではありません。)

を実行するgit branch --set-upstream-to=origin/xyzzyと、現在のブランチのアップストリームがに設定されorigin/xyzzyます。という名前のブランチの場合xyzzy、これが一般的な正しい設定になります。ブランチを作成する動作には、(通常は正しい)アップストリームが自動的に設定されるものと、そうでないものがあります。したがって、正しいアップストリームを自動的に設定するブランチ作成操作を使用した場合は、何もする必要はありません。別のアップストリームが必要な場合、またはアップストリームを設定しないブランチ作成操作を使用した場合は、これを使用してアップストリームを変更できます。

アップストリームに設定できるものは次のとおりです。

  • 別の独自の(ローカル)ブランチ:現在のブランチの上流にgit branch --set-upstream-to=experiment独自のローカルを作成します。experimentまた
  • またはなどのリモートトラッキング名のいずれか。これらは、によって出力される名前です。Gitはこれらのリモートトラッキングブランチ名を呼び出します(ここに「ブランチ」という単語をドロップするのが好きです)。これについては後で詳しく説明します。origin/mainorigin/masterorigin/xyzzygit branch -r

印刷される前、後ろ、最新、または分岐したメッセージgit statusは、やや魔法のように見えるコマンドを実行することから派生します。

git rev-list --count --left-right $branch...$upstream

ここ$branchで、は現在のブランチ名であり、$upstreamはそのアップストリーム設定(git branch --set-upstream-to上から)からの文字列です。ここでは、2つの名前の間に3つのドットがあり--count、2つの数字を吐き出すには、、、、--left-rightおよび3つのドットがすべて必要です。git rev-list


2 Git 2.23以降を使用している場合は、これまで初心者をトラブルに巻き込んだ(場合によってはGitの専門家をつまずかせた)git switchトリッキーな動作を回避できるため、移行することをお勧めします。git checkoutただし、慣れている場合はgit checkout、引き続きサポートされているので、好きなだけ使い続けることができます。本当の問題は、基本的にそれgit checkoutが過度に強力であり、予期せずに作業を破壊する可能性があることです。新しいgit switchものは意図的にそれほど強力ではなく、それを行いません。「意図的に自分の作業を破棄する」操作はに移動されましgit restoreた。

3 GitがデタッチドHEADモードと呼んでいる場合、ブランチがない可能性があります。使用すると、突然このモードになる可能性があります(ただし、大きな恐ろしい警告が出力されるため、恐ろしい警告が表示されない場合は表示されません)が、使用する場合は、分離を許可する必要があります-HEADを使用したモード。このモードには何の問題もありません。新しいコミットを失わないように、このモードに入ったら注意する必要があります。注意しないと簡単に紛失してしまいます。通常モードでは、Gitはこのような新しいコミットを失うことはありません。git checkoutgit switchgit switch --detach

デタッチドHEADモードの場合、ブランチがないため、定義上、アップストリームはありません。また、この質問の内容はいずれも当てはまりません。


到達可能性

この部分は少し技術的であり、その多くをWebサイトThink Like(a)Gitにアウトソーシングします。ここでは、次のように要約します。ブランチ名mainまたはxyzzy)とリモートトラッキング名origin/mainorigin/xyzzy)は、Gitがコミットを見つける方法です。Gitはすべてコミットに関するものです。ブランチ名は、コミットを見つけるためにのみ重要です。もちろん、それらが見つからない場合は問題が発生しているため、ブランチ名は重要です。しかし、重要なのは到達可能性です。これは専門用語です。

Gitリポジトリ内の各コミットには番号が付けられ、文字と数字の大きな醜い16進文字列が使用されます。これはコミットのハッシュIDであり、Gitが実際にコミットを見つける方法です。

各コミットには2つのものが含まれます:すべてのソースファイルの完全なスナップショット(特別な、圧縮された、Git化された、および重複排除された形式)、およびコミット自体に関するいくつかの情報:誰が、いつ、そしてなぜそれを作成したかを示すメタデータ(たとえば、ログメッセージ)。メタデータでは、各コミットは以前のコミットのコミット番号を保持します。これは、あるコミットが別の(以前の)コミットを見つけることができることを意味します。

Think Like(a)Gitが指摘しているように、これは鉄道列車に少し似ています。電車に乗ったら、それは素晴らしいことです。この場合、以前のすべての電車の停車駅まで自動的に後方に移動します。しかし、最初にあなたは駅への道を見つけなければなりません。Gitブランチ名はそれを行います:それはあなたのブランチの最新のコミットのハッシュIDを保持します。

このように描くことができます:

... <-F <-G <-H   <--branch

ブランチ名は、最新のコミットbranchのハッシュIDを保持します。名前はコミットを指していると言います。実際の大きな醜いハッシュIDが何であれ、ここではその代わりに文字を使用しました。H

Hは実際のコミットであるため、保存されたスナップショット(ファイル)といくつかのメタデータがあります。メタデータでは、Gitは以前のコミットのハッシュIDを保存しました。これを以前のコミットと呼びますGH それはを指して いると言いGます。Gitはブランチ名ポインターで見つけることができH、メタデータを含むコミットへのアクセスをGitに与えるため、Gitは以前のコミットのハッシュIDを持ちますG

Gもちろん、実際のコミットでもあります。保存されたスナップショットといくつかのメタデータがあります。のメタデータでG、Gitは以前のコミットのハッシュIDを保存しましたFGこれはを指していると言いますが、Gitはこの保存されたハッシュIDを使用してF見つけることができます。F

これは、最初のコミットに到達するまで、永遠に繰り返されます。そのコミット(おそらくここではそれを呼びAます)は、以前のコミットがないため、以前のコミットを逆方向に指すことはありません

この到達可能性の概念は、基本的に、Hブランチ名branchで検出されたコミットで開始し、逆方向に作業した場合に何が起こるかをまとめたものです。commitHに到達し、commitに到達し、commitにG到達し、に到達Fします。

ブランチ名とリモートトラッキング名

先ほど述べたように、ブランチ名はコミットの生のハッシュIDを保持します。これにより、Gitはそのコミットを見つけることができます。ただし、ブランチ名にはもう1つの特別な機能があります。

git checkoutまたはgit switchを使用てブランチにアクセスし、新しいコミットを行うと、Gitはブランチ名に保存されているハッシュIDを自動的に更新します。つまり、次のような一連のコミットがあるとします。

...--F--G--H   <-- xyzzy (HEAD)

私たちは「オン」ブランチxyzzyにいます。これは、特別な名前を付けることで示したいと思いHEADます。これは、図に複数のブランチ名がある場合に役立ちます。Hこれは、現時点では最新のコミットであることに注意してください。しかし、今度は通常の方法で別のものを作成します。

この新しいコミットは、他のコミットと同じように、新しい、一意の、大きな醜い16進ハッシュIDを取得します。Gitは、新しいコミットがコミットを逆方向に指していることを確認します。これは、新しいコミットを作成するためHに使用したコミットだからです。この新しいコミットを表すために文字を使用します。それを描きましょう:I

...--F--G--H   <-- xyzzy (HEAD)
            \
             I

この写真は実際にはコミットの途中です。Gitは作成Iしましたが、git commitアクションはまだ完了していません。この質問を自問してください:後でどのようにコミットを見つけますか?IハッシュIDが必要になります。ハッシュIDはどこに保存できますか?

あなたが言った場合:ブランチ名で、あなたは正しいです。実際、Gitに関する限り、正しいブランチ名は、現在「オン」になっている名前です。これはHEAD、この図で添付したものです。だから今、の最後の部分としてgit commit、GitはのIハッシュIDを名前に書き込みますxyzzy。これによりI、次のようにコミットすることがポイントになります。

...--F--G--H
            \
             I   <-- xyzzy (HEAD)

そして今、図面にねじれの理由がないので、それをまっすぐにすることができます:

...--F--G--H--I   <-- xyzzy (HEAD)

これがブランチ名の仕組みです。結局のところ、これは非常に単純です。一度にいくつかのことを頭に入れておく必要があります。名前はコミットを見つけます。最新のコミットを検索します。そこから、各コミットが以前のコミットを見つけるため、Gitは逆方向に機能します。

リモートトラッキング名はどうですか?ここでの秘訣は、Gitが他のGitと通信することです。 各Gitには独自のブランチ名があります。 あなたはあなたの masterまたはを持っていますmain; 彼らは彼らのものを持っています。あなたはあなたの xyzzyブランチを持っています、そして彼らも彼らのものを持つことができます。

あなたのGitは、いつでも、いつでもGit呼び出して、ブランチ名について尋ねることができます。ただし、これはあまり効率的ではなく、インターネットから切断されている場合は機能しません。4 いずれにせよ、Gitはそれを行いません。代わりに、GitがGitを呼び出して、すべてのブランチ名とハッシュIDのリストを取得すると、Gitはそれらの名前とハッシュIDを取得して、リポジトリに保存します。これは、を実行すると発生しますgit fetch5

しかし、問題があります。それらのmainor master、またはそれらがxyzzyある場合は、必ずしもあなたのorまたは。と同じコミットを意味するわけではありません。ただし、解決策は簡単です。Gitはブランチ名を取得し、それをリモートトラッキング名に変換します。 mainmasterxyzzy

origin'smainまたはmasterorが移動した場合は、単にorxyzzyを実行します。おそらく。を使用します。あなたのGitは彼らのGitを呼び出します。ブランチ名をリストし、ハッシュIDをコミットします。あなたのGitは、必要に応じて、彼らから新しいコミットを取得します。彼らが持っているコミットと、あなたが持っていないコミットです。次に、Gitはブランチ名をリモートトラッキング名に変換し、リモートトラッキング名を作成または更新して、これを実行した時点でブランチ名が指しいる場所を記憶します。git fetchgit fetch origin--prunegit fetch

を使用すると、ブランチ名が削除され--pruneた場合に対応します。。という名前のブランチがあったとしましょう。あなたは以前にそれを手に入れたので、あなたはあなたのリモートトラッキング名を持っています。それから彼らは削除したので、今回は...もう持っていません。がないと、Gitはこれを無視します。あなたは今死んでいるのに あなたの古いものを保ちます。を使用すると、Gitは次のように言います。ああ、これは今は死んでいるように見え、それを削除します。Git内の、ブランチ名の1つに対応しないリモート追跡名は、削除されるだけです。oldstufforigin/oldstuff oldstuff--pruneorigin/oldstuff --prune

プルーンオプションはおそらく常にデフォルトであるはずでしたが、そうではなかったため、現在はできません。6 ただし、これをデフォルトに設定しfetch.prune設定するtrueことできます。


4これは、2010年に比べて2021年にはあまり一般的ではありません。Gitが最初にリリースされた2005年にはかなり一般的でした。たとえば、Linux会議への航空会社のフライトでは、どのような価格でもインターネットにアクセスできませんでした。

5どの名前をとるか、いつそれらをとるかの選択は、実際にはここでの答えの一部です。さまざまな制約がありますが、Gitでは時間の経過とともに変化し、まだ少し変化しています。ただし、詳細については説明しません。

6 Gitは通常、下位互換性を非常に重要視しています。たとえば、push.defaultデフォルト設定をからmatchingに変更するには、1.xから2.0への切り替えが必要でした。simple


git rev-list2つの数字を取得する方法

以前、私は、印刷される前、後ろ、最新、または分岐したメッセージがgit status実行から派生していることを指摘しました。

git rev-list --count --left-right $branch...$upstream

ここで行うのgit rev-list、到達可能なコミットのカウントですgitrevisionsのドキュメントで説明されている3ドットの構文は、集合論で対称差と呼ばれるものを生成します。ただし、数学以外の専門用語では、これを2つのコミット到達可能性テストを実行するものと考えることができます。これは次のように描画できます。

          I--J   <-- xyzzy (HEAD)
         /
...--G--H
         \
          K   <-- origin/xyzzy

ここでは、名前がそこを指しているため、commitJはブランチ名から到達可能です。xyzzyコミットIはコミットから到達可能でJあるため、同様にカウントされます。これはコミットに戻りHます—グラフからわかるように、これは少し特別です。

同時に、コミットKはリモートトラッキング名から到達可能origin/xyzzyです。コミットHはから到達可能ですK。コミットHからバックまで、コミットGなどFもすべて到達可能です。しかし、2つの「線路」はcommit :commitで結合し、以前のすべてのcommitは両方の名前から到達可能です。HH

これにより、コミットはI-J*名前からのみ到達可能であるという点で特別にxyzzyなり、 *名前からのみ到達可能であるという点で特別になります。3ドット表記は、これらのコミットを検出します。一方の名前からのみ到達可能なコミット、またはもう一方の名前からのみ到達可能なコミットです。Korigin/xyzzy

ブランチ名を左側に、そのアップストリームを右側に配置し、3ドット表記を使用すると、この場合のこれら3つのコミットすべてが見つかります。を使用--countすると、次の数値が出力されます。3 git rev-list.使用すると、よりスマートになります。ただし、左側の名前(現在のブランチ名)のためにカウントされているコミットの数と、右側の名前(右側の名前)のためにカウントされているコミットの数をカウントする必要があります。上流の。したがって、両方のオプションと3つのドットを使用すると、次のようになります。--left-rightgit rev-list

2       1

出力として、オンになっていない2つのコミットがあり、オンにxyzzyなっていないorigin/xyzzy1つのコミットがあることを示しorigin/xyzzyますxyzzy。これらはそれぞれcommits J-and- I(on xyzzy)とK(on origin/xyzzy)です。

--countオプションがないと、接頭辞(左)または(右)の記号git rev-listが付いたハッシュIDが一覧表示されます。次のように、の代わりに使用します。<>git loggit rev-list

git log --left-right xyzzy...origin/xyzzy

(ここでも3つのドットに注意してください。gitrevisionsを参照して対称差を検索してください)3つのコミットが表示され、接頭辞<または必要に応じて追加>されます。

これは、ブランチにあるコミットとアップストリームにあるコミットを確認する簡単な方法です。 通常は、、、およびを使用するとより便利になり--decorateます(場合によっては追加することもできます)。--oneline--graph--boundary

前、後ろ、分岐、または最新

したがって、実行したとします。

git rev-list --count --left-right $branch...$upstream

(または、ここで再びgitrevisions$branch@{upstream}を参照してください)、2つのカウントを取得しました。これらは次のようになります。

  • 0および0:ブランチ名とリモートトラッキング名(またはアップストリームにあるもの)は同じコミットを指します。誰も前にも後ろにもいません。git statusコマンドは言うでしょうYour branch is up to date with '<upstream>'

  • ゼロ以外、ゼロ:現在のブランチにはアップストリームにないコミットがあります。現在のブランチにないアップストリームにはコミットはありません。したがって、私たちのブランチはアップストリームよりも進んでいます。

  • ゼロ、非ゼロ:アップストリームにない現在のブランチにはコミットはありませんが、現在のブランチにないアップストリームにはコミットがあります。これは、ブランチがアップストリームの背後にあることを意味します。

  • 非ゼロ、非ゼロ:これは私が上に描いた図のようなものです。現在のブランチとそのアップストリームの両方が同時に前後にあります。コマンドはgit status単語を使用しますdiverged

これから、元の質問に戻ります。現在のブランチのアップストレマがリモートトラッキング名であると仮定しましょう。 取得したカウントgit rev-listは、リモート追跡ブランチ名の内容に基づいていることに注意してください。

これは実際にどのようにして起こりますか?

OPのシナリオでは、1人の人だけが新しいコミットを作成し、それらをで送信していgit pushます。私が1人の場合、git cloneGitHubから何かを作成してから、新しいコミットを1つか2つ作成しgit push origin masterます。

現代のGitでは、git status私は最新の状態にあると教えてくれます。非常に古いバージョンのGitでは、git status私のmaster方が進んで origin/masterいることがわかります。 理由は単純です。昔は、git push 更新に失敗していましorigin/masterた。実行中git fetch origin、または単にgit fetch、独自のGitがGitHubでGitを呼び出し、その情報を読んで、自分が機能したことを認識しgit pushました。

を実行するgit pushと、Gitに他のGitを呼び出させることができます。次に、Gitは他のGitに、あなたが持っている新しいコミットを提供しますが、そうではなく、完了する必要がありますgit push。彼らはそれらのコミットを取り、どこかに置きます。7 次に、GitはGitに質問します(デフォルトでは丁寧に質問します)。よろしければ、ブランチ名に表示されているように、ハッシュIDで最新のコミットを参照するようにブランチ名を設定して ください。ここでは、リモート追跡機能はありません。使用しているのと同じ名前を設定するように依頼しているだけです。

原則として、リポジトリに新しいコミットを追加するだけの場合、この種の丁寧なリクエストは成功します。いくつかのコミットを「失う」ように依頼すると失敗します。これが「早送りではない」という苦情があります。新しいコミットを送信するのがあなただけの場合、この方法で失うものは決してないはずなので、これは常に機能するはずです。8

プッシュが失敗した場合は、Gitでリモートトラッキング名を変更しないでおくのが適切です。あなたのGitは、あなたのGitがそれを更新できるような情報をGitから取得することはありませんでした。しかし、プッシュが成功した場合...まあ、彼らはブランチ名をあなたのGitが彼らに使用するように頼んだハッシュIDに設定するだけです。これで、Gitはブランチ名がどこを指しているかを認識します。Gitはリモートトラッキング名を更新する必要があります。

古いGitバージョンでは、Gitはこれを気にしませんでした。Gitバージョン1.8.2では、Gitの作成者が最終的にこれを修正しました。成功git pushすると、Gitが提供する更新に同意したという事実に基づいて、Gitがリモートトラッキング名を更新します。したがって、この種のことはもうそれほど起こりません。


7古き良き時代には、彼らはそれらを直接リポジトリに入れました。最新のGitでは、それらを検疫エリアに配置し、実際に新しいコミットを受け入れた場合にのみリポジトリに移行します。

8もちろん、GitHubのような場所には、保護されたブランチなどの機能もあります。たとえば、すべてのプッシュにノーと言います。また、複数のコンピューターがあり、コンピューターAを介して新しいコミットを作成してプッシュしたことを忘れて、コンピューターBからプッシュしようとする場合など、より洗練されたシナリオを考案することもできます。


あなただけがやっていない場合はどうなりますかgit push

アリスとボブの両方がGitHubリポジトリのクローンを作成したとします。このリポジトリでの開発は、ブランチで行われますdev(開発用)。だからアリスは彼女devから彼女自身を作りますorigin/dev

...--G--H   <-- dev (HEAD), origin/dev  [Alice's computer]

ボブも同様に、自分で作成しdevます。

...--G--H   <-- dev (HEAD), origin/dev  [Bob's computer]

GitHubリポジトリもdevで終了しHます。(彼らにはありませんorigin/dev:GitHubリポジトリはリモートトラッキング名を気にしません。)

アリスは新しいコミットを作成します。これをと呼びI、アリスのコンピューターで次のように描画します。

          I   <-- dev (HEAD)
         /
...--G--H   <-- origin/dev

その間、ボブは新しいコミットを行います。これを次のように呼び出しますJ

...--G--H   <-- origin/dev
         \
          J   <-- dev (HEAD)

今、アリスとボブの両方がしようとしgit push origin devます。そのうちの1人が最初にそこに着きます—おそらくアリス:

...--G--H--I   <-- dev  [GitHub's systems]

ボブはcommitを送信しますJ。これはGitHubに次のようになります。

          I   <-- dev
         /
...--G--H
         \
          J   ... polite request to set dev to J

IGitHubがそれを行う場合、Gitは名前から開始して逆方向に作業することでコミットを検出するため、これはAliceのコミットを「失います」 。したがって、彼らは「早送りではない」という苦情でプッシュを拒否します。

Iボブは、GitHubからボブ自身のリポジトリにコミットをヤンクする必要があります。これにより、ボブは次のことを確認できます。

          I   <-- origin/dev
         /
...--G--H
         \
          J   <-- dev (HEAD)  [Bob's computer]

ボブは、git fetchまたはgit fetch origin、おそらく--prune(またはにfetch.prune設定してtrue)でこれを行う必要があります。 ボブが実行すると、「発散した」メッセージが表示されますgit status

プッシュレースの敗者であるボブが、自分の作業(コミットJ)とアリスの作業(コミット)を組み合わせる方法を理解するのは、今やボブ次第Iです。仕事を組み合わせるにはさまざまな方法があります。2つの主要なものはgit mergegit rebaseです。ここでは、誰が、いつ、なぜ何をすべきかについては説明しません。これは、他のGitよりも厳密に進んでいると思ったときに、これが「発散」状態に陥る可能性がある別の方法であるという事実だけです。

于 2021-04-07T07:52:30.363 に答える
4

Windowsマシンでも同じ問題が発生しました。コマンドを実行するgit pull origin masterと、「Xコミットによる「origin/master」の先行」警告が表示されます。git pull origin代わりに実行してブランチを指定しなかった場合、警告を受け取らなくなることがわかりました。

于 2013-09-11T18:30:01.547 に答える
3

git fetchあなたのためにこれを解決します

私の理解が正しければ、ローカル(キャッシュ)origin/masterは古くなっています。このコマンドは、サーバーからリポジトリの状態を更新します。

于 2018-08-25T03:55:17.440 に答える
2

現在のブランチと現在のトラックを実行するブランチの違いを思い出させるだけです。メッセージに出力されるブランチや、現在のブランチをどこにプッシュ/プルするかなど、詳細情報を提供してください。

于 2010-03-12T12:21:02.843 に答える
2

TortiseGITでスイッチ/チェックアウトを行っていたときに、実際にこれが発生しました。

私の問題は、別のローカルブランチに基づいてブランチを作成したことでした。/.git/config次のような「マージ」エントリが作成されました。

[branch "web"]
    merge = refs/heads/develop
    remote = gitserver

「web」ブランチに切り替えると、開発の前に100以上のコミットがあったと言われていました。まあ、私はもはや開発にコミットしていなかったので、それは本当でした。このエントリを削除するだけで、期待どおりに機能しているようです。開発ブランチの背後にいることについて文句を言うのではなく、リモート参照で適切に追跡しています。

Vikramが言ったように、このStack Overflowスレッドは、この問題を検索するときにGoogleで最高の結果になるので、自分の状況と解決策を共有したいと思いました。

于 2013-09-10T18:57:22.420 に答える
2

上記の@MarianZburliaが述べたのと同じことを繰り返します。それは私のために働き、他の人にも同じことを示唆するでしょう。

git pull origin develop

の後に。を続ける必要があり$ git pull --rebaseます。

$ git statusこれにより、最新のプルの後に表示されるコメントが削除されます。

于 2017-11-20T16:29:42.623 に答える
2

次に、gitステータスを実行すると、ブランチがXコミット(おそらく、私が行ったのと同じ数のコミット)だけ進んでいることがわかります。

私の経験は、多くの支店があるチーム環境です。私たちは(ローカルクローンで)独自の機能ブランチで作業しており、それはgit status私が11コミット先にあることを示したものの1つでした。質問の作者のように、私の作業上の仮定は、+11は私自身のコミットからのものであるというものでした。

develop何週間も前に、共通ブランチから機能ブランチに変更を加えていたことが判明しましたが、忘れてしまいました。今日、ローカル機能のブランチを再訪してgit pull origin develop、数を増やしたとき、その数は+41コミットに跳ね上がりました。多くの作業が行われていたため、私のローカル機能ブランチは、リポジトリdevelopの機能ブランチよりもさらに進んでいました。origin

したがって、このメッセージが表示された場合は、アクセスできる他のブランチ(自分自身または他のブランチ)から行った可能性のあるプル/マージを思い出してください。このメッセージは、同期をとるために、ローカルリポジトリからリポジトリ(「トラッキングブランチ」)に変更を戻す必要があることを通知するだけですgit pushpullorigin

于 2019-02-20T20:14:00.190 に答える
1

この質問は少し古いですが...私は同じような状況にあり、ここでの私の答えは私が持っていた同様の問題を修正するのに役立ちました

最初に試してみるpush -fか、オプションを強制します

それが機能しなかった場合は、(私の場合のように)リモートリポジトリ(またはに表示されるリモートリポジトリへの参照git remote -v)が更新されない可能性があります。

上記の結果は、ローカル/ブランチをリモート/ブランチとプッシュ同期しましたが、ローカルリポジトリのキャッシュには、以前のコミット(ローカル/ブランチの...単一のコミットのみがプッシュされた場合)がHEADとして表示されます。

上記を確認するには、リポジトリを別の場所に複製し、ローカル/ブランチHEADとリモート/ブランチHEADを比較してみてください。それらが両方とも同じである場合、あなたはおそらく私がした問題に直面しています。

解決:

$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
$ git remote add origin git://github.com/pjhyett/hw.git
$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
origin  git://github.com/pjhyett/hw.git (fetch)
origin  git://github.com/pjhyett/hw.git (push)
$ git remote rm origin
$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)

push -f次のようにします

git push -f github master ###コマンドにoriginもう含まれていないことに注意してください!

git pull今すぐ やるgit pull github master

git status受信時に

# On branch master

nothing to commit (working directory clean)

ビューの数が非常に多いため、このエラーを検索するとほとんどの場合、このスレッドが一番上に表示されるため、これが誰かに役立つことを願っています

詳細については、 gitrefも参照してください

于 2013-07-10T21:43:06.690 に答える
1

git pull示唆する、またはgit fetch正しい答え。と(など)の違いを確認すると、
メッセージが生成されます。 git status.git/FETCH_HEAD.git/refs/remotes/<repository>/<branch>.git/refs/remotes/origin/master

後者のファイルは、最後のフェッチからのHEADを記録します(リポジトリ/ブランチ用)。git fetch実行すると、両方のファイルがブランチの現在のHEADに更新されます。
もちろん、フェッチするものがない場合(ローカルリポジトリがすでに最新であるため)、.git/FETCH_HEAD変更されません。

于 2014-01-22T16:55:27.870 に答える
1

私は実際の質問に関連する以下を取得していましたYour branch is ahead of 'origin/testing/KB-200' by 17 commits

理由:先週レビュー用のPRを作成し、プロジェクトを終了しました。それから今日、私は同じブランチでわずかな変更を加えるためにプロジェクトを開き、最初(testing/KB-200)に実行しましgit pullた。このプルには、プロジェクトに取り組んでいる他の開発者による18の新しいコミットが含まれていました。これにより、これらのコミットによってローカルブランチがリモートブランチよりも先になり、そのメッセージが表示されました。したがって、次のコマンドを実行する必要がありました。

git push origin testing/KB-200

そして、それはすべて同期され、最新でした。[On branch testing/KB-200 Your branch is up to date with 'origin/testing/KB-200']

于 2021-06-30T11:20:52.220 に答える
0

コミットを実行した後にこのメッセージが表示された場合は、ブランチ内のファイルを追跡解除するために、任意のファイルに変更を加えてコミットを実行してみてください。どうやら、以前に追跡されたファイルの追跡解除のみを含む単一のコミットを行うことはできません。最後に、この投稿は私が問題全体を解決するのに役立ちましたhttps://help.github.com/articles/removing-files-from-a-repository-s-history/。リポジトリの履歴からファイルを削除する必要がありました。

于 2018-03-26T06:25:07.317 に答える
0

私に起こったことを共有するだけです。

たくさんのファイルをコミットし、コミットしたくないファイルがあることに気付いたので、VSコードを使用しundo last commitてファイルを削除し、gitignoreに追加してから、コミットを再度強制的にプッシュしました。

これにより、gitは、ファイルが何らかの方法でローカルにコミットされたため、まだリモートにコミットする必要があると考えたようです。

undo last commit現在gitignoreにあるファイルによって解決され、ステージングが解除されます

于 2021-06-16T16:44:58.020 に答える