1

私の職場では、10 年以上 Source Safe を使用した後、リビジョン管理のために Git に移行したばかりです (やった!)。私は今、エンジニアが新しいツールを学習するのをサポートしなければなりません。Windows で GitExtensions UI を使用していることに注意することが重要です。

数人の同僚が (UI から) 次のことを行いました。

  • 中央リポジトリのクローン ( origin )
  • メインの開発ブランチに基づいて、新しいローカル ブランチ ( A ) を作成します。
  • Aブランチでコミットを作成する
  • そのAブランチがまだチェックアウトされている間に、彼らは (誤って) メインの開発ブランチをAブランチにプルしました

プルを実行すると、GitExtensions の UI は次のようになります (残念ながら、仕事からスクリーン グラブを投稿することはできません)。

プル元:オリジン

ローカルブランチ: A

リモートブランチ:開発

マージ オプション:リモート ブランチを現在のブランチにマージする

(次にプルボタンを押します)

これは、GitExtensions のコマンド ログがプルに対して実行したことを示しています。

git pull --progress "origin" +refs/heads/develop:refs/remotes/origin/A

そのコマンドの後、ユーザーは、新しいorigin/Aリモート追跡ブランチが履歴に表示されるのを見ましたが、ブランチAが origin に存在しないことを確認しました。

何が起こったのかを理解するために git pull マニュアルを調べましたが、私たちが見ているのが GitExtensions のバグなのか、それとも git pull が何をすべきかについての私たちの誤解なのか、まだ理解できません。

ここで何が起こっているのかを理解するのを手伝ってくれる人はいますか?

前もって感謝します

編集

リモートの開発ブランチをローカルの Aブランチにプルしても意味がないことはわかっており、リモートの追跡ブランチを削除して状況を解決する方法も知っています。私が本当に望んでいるのは、オリジンにAブランチが存在しなかったため、最初に作成されたオリジン/Aリモート追跡ブランチの背後にあるロジックを理解することです。

ありがとう

4

2 に答える 2

2

これが GitExtensions のバグかどうかを判断するのは困難です。企業環境では、同じ名前のリモート ブランチ以外のものを取り込むことは非常にまれです (ほとんどの場合間違いです)。(その恐ろしいデザインのために使用するのは間違いだと思いますが、それは別の話です. )git pull

この+refs/heads/develop:refs/remotes/origin/A部分をrefspec (参照仕様) と呼びます。これは、リモート リポジトリの参照 (リモート リポジトリ内のブランチ) が現在指しているのと同じコミットを指すように、という名前のローカルの宛先参照refs/remotes/origin/A(省略形) を作成することを示しています。先頭のプラス ( ) は、宛先 ref をソース ref に早送りできない場合でも、ref を強制的に一致させることを示しています。origin/Arefs/heads/developdevelop+

したがって、pull言及したコマンドにより、Git は次のようになります。

  1. リモートリポジトリのdevelopブランチが指しているコミットを把握する
  2. そのコミットとその祖先のコミットをリモートリポジトリからダウンロードします(ローカルリポジトリに既にあるものを除く)
  3. ローカルrefs/remotes/origin/A参照がそのコミットを指すように強制する
  4. そのコミットを現在チェックアウトされているものにマージします

あなたが提供した UI モックアップに基づくと、これは私が予想していたものではありません。代わりに、GitExtensions が以下を実行することを期待していました。

git pull --progress origin refs/heads/develop

ローカル参照名 (コロンの後の部分) を省略することにより、Git は次のことを行います。

  1. リモートリポジトリのdevelopブランチが指しているコミットを把握する
  2. そのコミットとその祖先のコミットをリモートリポジトリからダウンロードします(ローカルリポジトリに既にあるものを除く)
  3. FETCH_HEADそのコミットを指すようにローカル一時参照を設定します
  4. そのコミットを現在チェックアウトされているものにマージします

ステップ 3 の違いに注目してください。

私は GitExtensions に詳しくありませんが、GitExtensions が行っていることは次のとおりです。特定のリモート ブランチを、特定のローカル ブランチの正式なアップストリーム ブランチとして指定することを想定しています。その前提でorigin/A、リモートのブランチのリモート追跡ブランチとして作成するdevelopことは、適度に理にかなっています。GitExtensions がremote.origin.fetchまたはbranch.A.merge構成設定も変更し.git/configて、指定を実際に公式にするかどうかを知りたいです。もしそうなら、それはユーザーインターフェースのデザインが悪いです。そうでない場合は、おそらくバグです。

于 2012-03-03T00:04:20.800 に答える
1

チェックアウトされたブランチのみをプルできます。これは、追跡が混乱した場所です。

何が起こっているかを確認する最も簡単な方法は、.git/conf ファイルを見ることです。どのブランチがどのリモート ブランチを追跡しているかがわかります。ファイルを直接編集するか、git ブランチの --set-upstream オプションを使用して、これを修正できます。

フェッチしてから、リモートの取得ブランチがどこにあるかを調べてから、変更をマージするか、それらをリベースしてローカル ブランチを更新することをお勧めします。リセットして強制的にプッシュすることで、変更を拒否することもできます。

また、コマンド ラインの使用を検討してください。コマンドの履歴やその他の利点が得られます。

于 2012-03-02T21:08:22.410 に答える