148

基本問題

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

git pull upstream master

アップストリームから取得してマージします (理論的には、削除されたコードは元に戻るはずです)。

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

すべてが確実に最新のものではありません。削除されたコードはすべて削除されたままです。

その他の関連情報

「マスター」と呼ばれるブランチが1つしかありません。

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

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

このコマンドは次のgit branch -vv結果をもたらします。

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

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

アップデート

当たり前だと思っていましたが、とにかくこれが私の目標です。

私のシステムで最新のコードを入手してください。

ここで怒りをお詫びしますが、なぜそのような単純な作業がそれほど難しくなければならないのですか?

4

7 に答える 7

245

ここでの基本的な問題は、git の機能とその理由を誤解および/または誤解していることだと思います。

他のリポジトリのクローンを作成すると、git は「あそこ」にあるもののコピーを作成します。また、 などの「彼らの」ブランチ ラベルを取り git ツリーmasterの「フル ネーム」が (通常) (ただし、あなたの場合は) であるラベルのコピーを作成します。ほとんどの場合、その部分も省略できるので、その元のコピーを として参照できます。remotes/origin/masterremotes/upstream/masterremotes/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 log7cfcb29は、永続的な (変更されない) 名前である数字の名前 (のようなもの) を見つけることができます。名前を付ける方法は他にもたくさんありますが、この場合は名前だけが必要です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 つの特定のファイルを選択できます。

于 2013-03-13T09:28:16.237 に答える
4

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

「すべてのファイルを削除する」のではなく、どのような結果を得たいかを説明すると、誰かが適切な行動方針を提案できるかもしれません.

アップデート:

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

あなたが理解していないように見えるのは、あなたがすでに最新のコードを持っているということです。master ブランチにある他の人の最新の作業を本当に見たい場合は、次のようにします。

git fetch upstream
git checkout upstream/master

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

于 2013-03-13T03:02:22.827 に答える
3

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

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
于 2013-03-13T03:20:08.280 に答える
0

git statusローカルにファイルがあり、github にないのに、

あなたのブランチは「オリジン/マスター」で最新です。コミットするものは何もありません。作業ツリーはきれいです

ファイルが.gitignore

実行してみてください

cat .gitignore 

これらのファイルがそこに表示されるかどうかを確認します。これで、git がそれらをリモートに移動したくない理由が説明できます。

于 2020-08-01T14:19:54.920 に答える