強制更新後のGitプル


333

私はいくつかのコミットを押しつぶしてgit rebasegit push --force(それは悪です、私は知っています)をやっただけです。

現在、他のソフトウェアエンジニアは異なる歴史を持っていgit pullます。彼らがを行うと、Gitがマージされます。これを修正する方法はありrm my-repo; git clone git@example.org:my-repo.gitますか?

の反対のようなものが必要ですgit push --forcegit pull --force、意図した結果が得られませんでした。


16
彼らは彼らのブランチを削除し、全体のレポを削除しなくても、あまりにもそれを再作成することができますgit checkout master && git branch -D test && git checkout -b test origin/test
フロリアン・クライン


回答:


511

新しいコミットを受け取るには

git fetch

リセット

を使用して、ローカルブランチのコミットをリセットできgit resetます。

ローカルブランチのコミットを変更するには:

git reset origin/master --hard

ただし、ドキュメントには次のように記載されています。

インデックスと作業ツリーをリセットします。<commit>以降の作業ツリー内の追跡ファイルへの変更は破棄されます。

ローカルで行った変更を実際に保持したい場合は、--soft代わりにリセットを行ってください。これにより、ブランチのコミット履歴が更新されますが、作業ディレクトリ内のファイルは変更されません(その後、それらをコミットできます)。

リベース

次を使用して、他のコミット/ブランチの上にローカルコミットを再生できますgit rebase

git rebase -i origin/master

これにより、インタラクティブモードでリベースが呼び出され、リベースしている履歴にない個々のコミットを適用する方法を選択できます。

(を使用してgit push -f)削除したコミットがすでにローカル履歴にプルされている場合、それらは再適用されるコミットとして一覧表示されます-リベースの一部として削除する必要があります。そうしないと、単に履歴に再び含まれます。ブランチの場合-次のプッシュでリモート履歴に再表示されます。

git command --help上記の(またはその他の)コマンドの詳細と例については、ヘルプを使用してください。


2
@iblueは、すべての変更を失うか、コミット履歴を削除してファイルの変更を維持するか、または各コミットを新しいヘッドの上に適用するかを選択します。最も単純なオプションは、おそらくソフトリセットです。
AD7six 2012年

1
@iblue同僚が「git reabse origin / master」を使用しているときに、以前にすでにコミットされていた場合、gitはコミットをそのコミットの背後に書き込みます。
Tim

6
これが別のブランチ用である場合、言及する価値があるかもしれません:git reset origin/otherbranch --hard
bmaupin

だから、明確にするために、これはどちらかのオプション1: reset --hardまたはオプション2:reset --soft+ rebase、右?
PlasmaBinturong

2
@PlasmaBinturong No. git reset --soft origin/masterは、コミット履歴を変更して、リモートとステージの違いをリモートに一致させてから、コミットします。コミット履歴に違いがないため、このシナリオではリベースする必要はありません(変更がコミットされていないため、そうすることができません)。2つのオプションはリセットまたはリベースです-両方の組み合わせではありません。してください質問をするあなたのシナリオでは、私がここで答えてきたものとは異なる場合。
AD7six

16

これにより、不要なコードが既に含まれているブランチは修正されません(その方法については以下を参照してください)。 origin / some-branch)次に、単純に:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

注:&&を間に置くことで、これらすべてを組み合わせることができます

注2:フロリアンはこれをコメントで述べましたが、答えを探すときに誰がコメントを読むのですか?

注3:ブランチが汚染されている場合は、新しい「ダムブランチ」に基づいて新しいブランチを作成し、チェリーピックのみでコミットできます。

例:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

今、機能新機能は、余分な(おそらく悪い)コミットのないブランチです!


これは私が本当に欲しかったものです。誰かがマスターブランチをリベースしましたが(神はどのような理由か知っています)、コミットしたいローカルな変更はありませんでした。だから私がしなければならなかったすべては私のローカルマスターブランチ(本当に変に感じた)を削除してもう一度チェックアウトをすることでした。ありがとう!
Danilo Carvalho

@ピーター・モーテンセン編集はに従ってかなりあるべきstackoverflow.com/help/editing
トムPratsの

最後のステップでは、以下git checkout -b base-branch origin/base-branchと一緒に使用することもできますgit checkout --track origin/base-branch
bluesmonk

2

リベースでプル

通常のプルはフェッチ+マージですが、必要なのはフェッチ+リベースです。これはpull次のコマンドのオプションです。

git pull --rebase

私はこれを常に使用して、履歴内のマージコミットをすべて行わずに、masterから私の機能ブランチに最新のコードを取得します。
ヘルマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.