ここでの基本的な問題は、git の機能とその理由を誤解および/または誤解していることだと思います。
他のリポジトリのクローンを作成すると、git は「あそこ」にあるもののコピーを作成します。また、 などの「彼らの」ブランチ ラベルを取り、 git ツリーmaster
の「フル ネーム」が (通常) (ただし、あなたの場合は) であるラベルのコピーを作成します。ほとんどの場合、その部分も省略できるので、その元のコピーを として参照できます。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
これにより、現在のディレクトリを完全な名前が実際に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
その「追跡」という名前の新しいローカルブランチを作成します (この用語は人々を混乱させると思うのであまり好きではありませんが、それは 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」と一致させるのが慣習的ですが (つまり、彼らが持っている場合は、remotes/origin/mauve
あなたにも名前を付けmauve
ます)、「them」と入力して、「from them」から取得したコミットに名前を付けたり、表示したりすることができます。(「1 つのコミット」はソース ツリー全体であることを思い出してください。git show
たとえば、 1 つのコミットから 1 つの特定のファイルを選択できます。