ここでのあなたの基本的な問題は、あなたがgitが何をするのか、なぜgitがそれをするのかを誤解している、または誤解していることだと思います。
他のリポジトリのクローンを作成すると、gitは「あそこ」にあるもののコピーを作成します。また、「」などの「自分の」ブランチラベルを取得master
し、 gitツリーの「フルネーム」が(通常は)であるremotes/origin/master
(ただし、この場合はremotes/upstream/master
)ラベルのコピーを作成します。ほとんどの場合、そのremotes/
部分も省略できるので、元のコピーをとして参照できますupstream/master
。
ここで、いくつかの変更を行っていくつかのファイルにコミットした場合、その変更を加えたのはあなただけです。その間、他の人は他のクローンを作成し、それらのクローンを変更するために(クローンを作成した元の)リポジトリを使用する場合があります。もちろん、変更されたのは彼らだけです。しかし最終的には、誰かが(「プッシュ」またはパッチなどを介して)元の所有者に送り返す変更を持っている可能性があります。
git pull
コマンドは、ほとんどただの省略形ですgit fetch
が続きますgit merge
。これは、これらの2つの操作が実際に行うことを理解する必要があることを意味するため、重要です。
このgit fetch
コマンドは、クローン元(またはフェッチする場所として設定されている場所)に戻り、「他の誰かが追加、変更、または削除した新しいもの」を見つけるように指示しています。これらの変更はコピーされ、以前にそれらから取得したもののコピーに適用されます。それらはあなた自身の仕事には適用されず、彼らの仕事にのみ適用されます。
git merge
コマンドは、より複雑であり、あなたがゆがんで行っているところです。少し単純化しすぎますが、「コピーで変更したもの」を「誰か他の人からフェッチして、自分のコピーに追加した変更」と比較します。変更とそれらの変更が競合していないように見える場合は、merge
操作によってそれらがまとめられ、開発とそれらの開発を結び付ける「マージコミット」が提供されます(非常に一般的な「簡単な」ケースでは、変更すると、「早送り」されます)。
現在発生している状況は、変更を加えてコミットした状況であり、実際には9回、したがって「9つ前」ですが、変更はありません。したがって、fetch
忠実に何もフェッチせず、merge
変更の欠如を取り、何もしません。
あなたが望むのは、コードの「彼らの」バージョンを見ること、あるいは多分「リセット」することです。
見たいだけの場合は、そのバージョンを確認するだけです。
git checkout upstream/master
これは、現在のディレクトリを、フルネームが実際にあるブランチに移動することをgitに伝えますremotes/upstream/master
。最後に実行しgit fetch
て最新のコードを取得した時点でのコードが表示されます。
自分の変更をすべて破棄したい場合は、ラベルのmaster
名前を変更するというgitの考えを変更する必要があります。現在、最新のコミットを示しています。そのブランチに戻った場合:
git checkout master
次に、このgit reset
コマンドを使用すると、「ラベルを移動」することができます。残っている唯一の問題(あなたが本当にしたことをすべて放棄する準備ができていると仮定した場合)は、ラベルが指すべき場所を見つけることです。
git log
数値の名前を見つけることができます—これら7cfcb29
は永続的な(決して変更されない)名前であり、名前を付ける他の方法はとんでもない数がありますが、この場合は名前だけが必要ですupstream/master
。
独自の変更を一掃、ラベルを移動するには(あなたが犯したすべてのことを非常にしばらくの間、実際に回復可能ですが、それはそうでは多くの困難、この後だ非常に確認してください):
git reset --hard upstream/master
--hard
、あなたがやっているものを一掃し、現在のブランチラベルを移動し、コミット与えをチェックアウトするのgitに指示します。
本当にgit reset --hard
たくさんの仕事をしたい、一掃したいというのは、あまり一般的ではありません。より安全な方法(結局のところ、その作業の一部に価値があると判断した場合、その作業を簡単に回復できるようにする)は、既存のブランチの名前を変更することです。
git branch -m master bunchofhacks
そして、master
「tracks」という名前の新しいローカルブランチを作成します(この用語は人を混乱させると思うので、私はあまり好きではありませんが、それはgit用語です:-))オリジン(またはアップストリーム)マスター:
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」を一致させるのが一般的ですが、「yours」とremotes/origin/mauve
名前を付けたいmauve
場合はいつでも「theirs」と入力して「コミット」を表示できます。(「1つのコミット」はソースツリー全体であることを思い出してください。git show
たとえば、次のようにして、1つのコミットから1つの特定のファイルを選択できます。