強制プッシュを行わずにgit rebaseを使用するにはどうすればよいですか?


92

git nirvanaを達成するために、私は1日を費やして、現在マージしている状況でリベースを活用する方法を学びます。

私がgit 101フロー(以下で詳しく説明します)と見なすものを実行するpush --forceとき、変更を元に戻すときに実行する必要があります。

(参照私はこれが覆われた地面があることを知っている-私はだけでなく、一人12345)、と私は技術的な理由を理解し、なぜ力が必要です。私の問題は、リベースとどのようにそれが自分たちの生活を変えていますの賞賛を歌っ多くの(多くの)ブログエントリが(参照がある---これで1234の数を一覧表示する)、それらのどれもそれは言及していないpush --forceの一部です。彼らの流れ。ただし、既存のスタックオーバーフローの質問に対するほとんどすべての回答は、「ええ、リベースするつもりなら、使用しなければならない」のようなことを言っていますpush --force

リベースの支持者の数と信憑性を考えると、「push --force」の使用はリベースフローの本質的な部分ではなく、プッシュを強制する必要がある場合、何かが間違っていると私は信じる必要があります

push --forceある悪いこと

これが私の流れです。 力を使わずにどのようにして同じ結果を達成できますか?

簡単な例

2つのブランチ:

  • v1.0-リリースブランチ、パッチのみが含まれます
  • マスター -次のメジャーリリースのすべて。

パッチのコミットと次のリリースのコミットがいくつかあります。

プレマージ

パッチをマスターに組み込んで、次のリリースで失われないようにします。悟りを開く前に、

git checkout master
git merge v1.0

しかし、今私はやっています

git checkout master
git rebase v1.0

だから今私はここにいます:

ここに画像の説明を入力してください

時間:

git push

サイコロはありません。

回答:


43

リベースは素晴らしいツールですが、それを使用してトピックブランチのマスターへの早送りマージを作成するときに最適に機能します。たとえば、マスターに対してadd-new-widgetブランチをリベースする場合があります。

git checkout add-new-widget
git rebase -i master

ブランチをマスターに早送りマージする前。例えば:

git checkout master
git merge --ff-only add-new-widget

これの利点は、すべての変更がマージ前にマスターのヒントに基づいてリベースされるため、履歴に複雑なマージコミットやマージの競合があまりないことです。2番目の利点は、リベースしたgit push --forceことですが、masterブランチの履歴を壊していないので、使用する必要はありません。

確かに、これがリベースの唯一の使用例でも、唯一のワークフローでもありませんが、私が見た場合、それはその最も賢明な使用法の1つです。YMMV。


4
CGに感謝します。「それを使用して早送りマージを作成する」ことが鍵だと思います。上記の2つのライブブランチ(開発ブランチとリリースブランチ)がある場合には当てはまりませんが、限られた期間のみ必要な一時的なトピックブランチに非常によく適用され、マージされると削除されます。再度、感謝します。
ロイTruelove

1
私はこれを理解していますが、元の質問は残っています。実際の答えは@Fabien Quatravaux
IsmailS

4
まあ、それでも1.0ブランチを強制的にプッシュする必要がありますよね?少なくとも、それはいつも私にとって物事が判明する傾向がある方法です。ファビアン法はそれが起こらないようにするでしょう。
joerx

23

@CodeGnomeは正しいです。v1.0ブランチでマスターをリベースするのではなく、マスターでv1.0ブランチをリベースする必要があります。

git checkout -b integrate_patches v1.0
git rebase master
git checkout master
git merge integrate_patches

v1.0を指す新しいブランチを作成し、その新しいブランチをマスターの上に移動してから、新しいバージョンのV1.0パッチをマスターブランチに統合します。あなたは次のようなものになるでしょう:

o [master] [integrate_patches] Another patch on v1.0
o A patch on v1.0
o Another change for the next major release
o Working on the next major release
|  o [v1.0] Another path on v1.0
|  o A patch on v1.0
| /
o Time for the release

このリベースの使用方法は、公式のgitドキュメントで推奨されています

私はあなたが正しいと思いますgit push --force:あなたがミスをして、望まないものを押した場合にのみそれを使うべきです。


これはOPの特定の問題に対する最良の答えだと思います。一時的なマージブランチを作成し、それをリベースしてから、マスターにマージし、オリジンにプッシュします。一時的なブランチを元にプッシュする必要はありません。私が提供する唯一の追加のアドバイスは、マージまたはリベースされたコードを修飾できる開発またはqaブランチを持つことです。認定後、このコードはffのみでマスターにマージされます。これにより、認定プロセスに時間がかかりすぎる場合に簡単にホットフィックスを行うことができます。これは基本的に「git flow」プロセスです。
Javid Jamae 2015年

ファビアン、ありがとうございます。変更をに統合したいだけでmaster、機能ブランチ自体のマージを気にしない私たちにとっては、これは次のようにして行うことができますgit checkout my-branch; git rebase master; git checkout master; git merge my-branch
Siavas

17

あなたはリベース場合プッシュを強制する必要がある、あなたはすでに、右、変更内容を公開していますか?

私は束全体をリベースしますが、強制プッシュが問題にならないプライベートなもの(例:プルリクエストの一部としてのGitHub上の自分のクローン)に公開するか、初めてプッシュする前にリベースします。

これはリベースを使用するワークフローの中心ですが、プッシュを強制しないでください。準備ができるまで公開せず、プッシュ後にリベースしないでください。


ダンに感謝します。上記をどのように達成すべきかを教えていただけませんか?これはリベースが適用されるシナリオではないのですか?
Roy Truelove

2
すべての作業をトピックブランチに分離すると、リベースの適切なシナリオが設定されます。あなたはrebase、あなたは、あなたのトピックブランチに引き込ま変更を新しい、しかし、あなたはそのブランチの変更を完了したとき、mergeメインの開発ブランチに分岐バック。
redhotvengeance

1
問題は、ブランチを公開したことです。そのため、リポジトリに強制的にプッシュする必要があります。あなたは2つのうちの1つをあきらめる必要があります:あなたのやり方で出版すること、またはリベースすること。ごめんなさい。
Daniel Pittman

このシナリオでは、リベースのような音は機能しません。v1.0はトピックブランチではなく、リリースブランチなので、死ぬことはなく、公開する必要があります。
ロイTruelove

5

複数の場所(コンピューター)から機能ブランチを自分で作業するという誤ったプッシュの結果ではない、このrebase-then-force-pushパターンの良いユースケースがあると思います。私はこれを頻繁に行います。なぜなら、私は時々自分のデスクトップのオフィスで、そして時には自分のラップトップの自宅/顧客サイトから作業するからです。mainブランチに追いついたり、マージをよりクリーンにしたりするために時々リベースする必要がありますが、あるマシンを離れて別のマシンで作業するときは(強制的に)強制プッシュする必要もあります。ブランチで作業しているのが私だけであれば、魅力のように機能します。


2
私はこれと同じワークフローを持っています(複数のコンピューター/場所から作業します)。したがって、 'mytopic'というトピックブランチで作業していると仮定します。ローカルの使い捨てブランチ(mytopicの単なるブランチ)を常に「マスター」にリベースしてから、それをmytopicにマージする限り、プッシュを強制する必要はありません。OPのシナリオは少し異なるため、そのような場合は強制プッシュが必要になることがあります。しかし、私はOPが間違った方法でリベースしていると思います-彼が私が説明したようにそれをした場合、強制的なプッシュは必要ありません。
bwv549

3

これが私が使うものです(あなたのブランチ名がfoob​​arであると仮定します):

git checkout master              # switch to master
git rebase   foobar              # rebase with branch
git merge -s ours origin/master  # do a basic merge -- but this should be empty
git push origin master           # aaand this should work

2
リベースのマスターが奇妙に見えます。
エミールヴィクストロム2017

2
git個性がないわけではない
しのばせる

1
git merge -s ours origin/<branch>それは私たちのためにそれを修正したものでした
Max

0

tl; drは共有ブランチとマージし、個々のブランチでリベースします。--force-with-lease力のより安全な代替手段であり、力の破壊的な性質なしで上記のgit nirvanaを達成するのに役立つはずです。

さまざまなチームのワークフローでの作業を見てきた一般的な経験則はmerge、共有ブランチ(つまり、マスターまたは開発)で使用rebaseし、独自の機能ブランチで作業するときに使用することです。これは機能ブランチの典型的なライフサイクルです

git checkout master
git checkout -b new-feature
git commit -am "commit new work"
git push -u origin new-feature
# have code reviewed, run CI, etc.,
# meanwhile master has new commits
git checkout master
git pull
git rebase -i master # -i for interactive rebase allows you to squash intermediate commits
git push --force-with-lease
git merge master

ここで行ったことの簡単な英語バージョン:

  1. マスターから新しいブランチを作成しました
  2. ブランチで作業を行い、リモートにプッシュしました
  3. マスターからリベース
  4. 作業をリモートにプッシュ force-with-lease
  5. 非常にクリーンなgitログを使用してマスターにマージし、共有ブランチからの複数のマージによる混乱を減らして、ブランチを最新のマスター(共有ブランチ)に「追いつけ」ます

4番目のステップは本当に重要であり、リベースの使用を提唱し始めた主な理由の1つです。force-with-leaseリモートをチェックして、新しいコミットが追加されているかどうかを確認します。あなたgit pushが破壊的であることが証明された場合、それはプッシュされません!

これにより、誰かがrebaseを使用する自信が高まることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.