web-dev-qa-db-ja.com

Gitがマスターブランチが「最新」であると言っているのはなぜですか?

基本的な問題

プロジェクトのファイルからすべてのコードを削除し、ローカルgitに変更をコミットしました(意図的に)。やった

git pull upstream master

アップストリームからフェッチしてマージします(したがって、理論的には、削除されたコードは元に戻る必要があります)。

Gitは、すべてが最新であることを教えてくれます。

すべてが最新のものではないことは間違いありません。削除されたコードはすべて削除されます。

その他の関連情報

「マスター」というブランチが1つしかありません。

私は最近、次のようにアップストリームを追跡する「マスター」を設定しました。

アップストリームからリモートブランチマスターを追跡するようにセットアップされたブランチマスター。

コマンドgit branch -vvの結果:

* master 7cfcb29 [upstream/master: ahead 9] deletion test

なぜこれが起こっているのですか?私はコードに加えた変更をプロジェクトマネージャーにメールで送信しようとしています。

更新

私はそれが明白だと思ったが、とにかくこれは私の目標です。

システム上の最新のコードを取得します。

ここで私の怒りを失礼しますが、なぜそのような単純なタスクがそれほど難しくなければならないのですか?

96
user1971506

ここでのあなたの基本的な問題は、あなたがgitが何をするのか、なぜそれを行うのかを誤解および/または誤解していることだと思います。

他のリポジトリのクローンを作成すると、gitは「あそこ」にあるもののコピーを作成します。また、masterなどの "their"ブランチラベルを取得し、your git treeの "フルネーム"が(通常)remotes/Origin/master(ただし、remotes/upstream/master)であるラベルのコピーを作成します。ほとんどの場合、remotes/部分も省略できるため、元のコピーをupstream/masterとして参照できます。

ここでいくつかのファイルに変更を加えてコミットすると、あなただけがそれらの変更を行います。一方、他の人は、元のリポジトリ(クローンの作成元)を使用して、他のクローンを作成し、それらのクローンを変更できます。もちろん、変更されたのはそれらだけです。しかし最終的には、誰かが元の所有者に変更を送信する可能性があります(「プッシュ」またはパッチなど)。

git pullコマンドは、ほとんどの場合、git fetchに続くgit mergeの短縮形です。これは、これら2つの操作が実際に行うことを理解する必要があることを意味するため、重要です。

git fetchコマンドは、どこからクローンを作成した(または他の場所からフェッチする場所として設定した)ところに戻り、「誰かが追加、変更、または削除した新しいもの」を見つけるように指示します。これらの変更はコピーされ、適用されます以前に取得したもののコピーにnotはあなた自身の作品に適用され、彼らの作品にのみ適用されます。

git mergeコマンドはより複雑で、問題が発生する場所です。少し単純化しすぎて、「コピーで変更した内容」と「誰か他の人から取得した変更が他人のコピーに追加された変更」と比較されます。変更とその変更が競合していないように見える場合、merge操作はそれらを一緒に押し付けて、開発と開発を結び付ける「マージコミット」を提供します(ただし、非常に一般的な「簡単な」場合があります)変更せずに「早送り」を取得します)。

今あなたが遭遇している状況は、あなたが変更を加え、それらをコミットした状況です。実際、9回、つまり「先の9」であり、彼らはnoを変更しました。したがって、fetchは忠実に何もフェッチせず、その後mergeは変更の欠如を取り、何も行いません。

あなたが望むのは、コードの「自分の」バージョンを見るか、「リセット」することです。

単に見たいだけなら、そのバージョンをチェックアウトするだけです:

git checkout upstream/master

これは、実際のフルネームがremotes/upstream/masterであるブランチに現在のディレクトリを移動することをgitに伝えます。 git fetchを最後に実行して最新のコードを取得したときのコードが表示されます。

abandon独自の変更をすべて行いたい場合は、ラベルmasterに名前を付ける必要があるリビジョンのgitのアイデアを変更する必要があります。現在、最新のコミットに名前を付けています。そのブランチに戻った場合:

git checkout master

その後、git resetコマンドを使用すると、「ラベルを移動」できます。残っている唯一の問題(自分がやったことすべてを放棄する準備ができていると仮定して)は、ラベルが指すべき場所を見つけることです。

git logを使用すると、7cfcb29などの永続的な(変更されない)名前の数値名を見つけることができます。また、名前を付ける他の方法はとんでもない数になりますが、この場合は名前upstream/masterだけが必要です。

ラベルを移動するには、独自の変更を消去します(コミットしたものは実際にかなり長い間回復可能ですが、この後はかなり難しくなりますのでvery sure):

git reset --hard upstream/master

--hardはgitに、実行していたことを消去し、現在のブランチラベルを移動してから、指定されたコミットをチェックアウトするように指示します。

reallygit reset --hardになり、大量の作業を一掃したいことはあまりありません。より安全な方法(結局、作業の一部が価値があると判断した場合にその作業を簡単に回復できるようにする)は、既存のブランチの名前を変更することです。

git branch -m master bunchofhacks

そして、「追跡」するmasterという名前の新しいローカルブランチを作成します(人々を混乱させると思うので、この用語はあまり好きではありませんが、それはgit用語です:-))Origin(またはアップストリーム)マスター:

git branch -t master upstream/master

それであなたは自分自身を得ることができます:

git checkout master

最後の3つのコマンド(コマンドを2つだけにするショートカットがあります)は、既存のラベルに貼り付けられた名前を変更し、新しいラベルを作成してからそれに切り替えることです。

何かをする前に:

C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "master"

git branch -mの後:

C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

git branch -t master upstream/masterの後:

C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

ここでC0は、git cloneを最初に実行したときに取得した最新のコミット(完全なソースツリー)です。 C1からC9はコミットです。

git checkout bunchofhacksを実行してからgit reset --hard HEAD^^を実行すると、最後の図が次のように変更されることに注意してください。

C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 -    "bunchofhacks"
                                                      \
                                                       \- C8 --- C9

その理由は、HEAD^^は現在のブランチの先頭から2つ上のリビジョン(リセットの直前はbunchofhacksになる)に名前を付け、reset --hardがラベルを移動するためです。コミットC8とC9は現在ほとんど不可視です(reflogやgit fsckなどを使用してそれらを見つけることができますが、それはもはや簡単ではありません)。ラベルは好きなように移動できます。 fetchコマンドは、remotes/で始まるものを処理します。 「yours」と「theirs」を一致させるのが一般的です(したがって、remotes/Origin/mauveがある場合は、自分のmauveにも名前を付けます)が、「theirs」から取得したコミットに名前を付け/確認したい場合は、「theirs」と入力できます。 (「1つのコミット」はソースツリー全体であることを思い出してください。必要に応じて、たとえばgit showを使用して、1つのコミットから特定のファイルを1つ選択できます。)

179
torek

私はあなたと同じ問題を抱えていました。

git statusgit fetchgit pullを実行しましたが、私のブランチはまだOriginの背後にありました。リモートにプッシュされたフォルダーとファイルがあり、ウェブ上でファイルを見ましたが、ローカルではそれらが見つかりませんでした。

最後に、これらのコマンドはローカル上のすべてのファイルとフォルダーを更新しました:

git fetch --all
git reset --hard Origin/master 

またはブランチが必要な場合

git checkout your_branch_name_here
git reset --hard Origin/your_branch_name_here
4
jturi

他の投稿者が言うように、プルは上流からの変更をリポジトリにマージします。リポジトリにあるものをアップストリームにあるものに置き換える場合、いくつかのオプションがあります。袖口から、私は一緒に行きます

git checkout HEAD^1  # Get off your repo's master.. doesn't matter where you go, so just go back one commit
git branch -d master  # Delete your repo's master branch
git checkout -t upstream/master  # Check out upstream's master into a local tracking branch of the same name
3
Paul

すべてのプロジェクトファイルの削除など、コミットした変更は、プル後もそのまま残ります。プルするのは、他の場所からの最新の変更を自分のブランチにマージすることです。ブランチがすべてを削除した場合、アップストリームの変更が削除したファイルに影響するときにせいぜいマージ競合が発生します。要するに、はい、すべてが最新です。

「すべてのファイルを削除する」のではなく、どのような結果を望んでいるのかを説明すると、誰かが適切な行動を提案することができます。

更新:

私のシステム上でコードの最新のものを入手する

あなたが理解していないように思われるのは、あなたがすでに最新のコードを持っているということです。本当に欲しいのが、マスターブランチ上にある他の誰かの作業の最新のものを見たい場合は、次のようにします:

git fetch upstream
git checkout upstream/master

これにより、すぐに自分の作業を開始(再開)できるようになるわけではありません。行ったことを取り消す方法や、自分や他の人が行った変更を元に戻す方法を知る必要がある場合は、詳細をお知らせください。また、バージョン管理の基本的な目的を誤解しているように見えるため、バージョン管理の目的を検討することも検討してください。

2
Ryan Stewart

与えられた情報の幅と深さの点で一番上の答えははるかに優れていますが、問題をほぼすぐに修正し、バージョン管理の基本原則のいくつかを踏むことを気にしないでください...

  1. マスターに切り替え

    $ git checkout upstream master
    
  2. 不要なブランチを削除します。 (注:ブランチはマスターよりも多くのコミットがあるため、通常の-dフラグの代わりに-Dが必要です。)

    $ git branch -d <branch_name>
    
  3. 新しいブランチを作成する

    $ git checkout -b <new_branch_name>
    
1
BrotherDonkey

私が間違っている場合は誰かが私を修正してください。しかし、これはあなたのブランチが上流のマスターブランチより9コミット先にあるためだと思います。リモートからプルを行うと、すでにそれらの変更があります。それは、9回のコミットでそれらに先んじているということです。すでに履歴にあり、9コミット先にある古い変更については、新しい変更を置き換えることは意味がありません。

リモートでのコミットがより新しいものだった場合、thenが現在のブランチにマージされます(デフォルトでは--rebaseを指定しない限り)。

ライアンが言ったように、誰かがあなたをより直接的に助けることができるように、あなたの目標が何であるかを正確に指定することをお勧めします。

1