web-dev-qa-db-ja.com

git rebaseの基本

最近git rebaseの使用を開始しましたが、それを100%確実に行っているとは限りません。質問のために、Originにはmasternextから分岐したmasterの2つのブランチがあります。

2つの間の最後の同期以降、masterには2つのコミットがあり、next 6がありました。

$ git log --oneline Origin/next..Origin/master
59b5552 master commit #2
485a811 master commit #1

$ git log --oneline Origin/master..Origin/next
4ebf401 next commit #6
e9b6586 next commit #5
197ada0 next commit #4
4a2c3c6 next commit #3
040a055 next commit #2
84537bf next commit #1

nextをチェックアウトしてgit rebase -i Origin/masterを実行すると、次の結果が得られます。

$ git status
# On branch next
# Your branch and 'Origin/next' have diverged,
# and have 8 and 6 different commits each, respectively.

そして最後にgit pull --rebaseを実行した後、masterからの2つのコミットはnextにあります:

$ git log --oneline Origin/next..next 
8741d09 master commit #2
485a811 master commit #1

質問:

  1. これは正しいアプローチですか?
  2. 8 and 6が実行されるまでpull --rebase異なるコミットがあるのはなぜですか?
  3. フローを単純化することは可能ですか?

とても感謝しております :)

43
David Kuridža

最初から始めましょう。元の状態の図を次に示します。

 A-B-C(マスター、オリジン/マスター)
\
 D-E-F-G-H-I(次、オリジン/次)

nextをチェックアウトし、nextOrigin/masterにリベースすると、すでにOrigin/masterにある2つの後に6つの新しいコミットが作成されました。これらの新しいコミットは、Origin/masterOrigin/nextが分岐した元の祖先ではなく、祖先として「マスターコミット#2」(図ではC)を持っています(図ではA )、それらのハッシュは異なります。これが、nextOrigin/nextから8つの異なるコミットを持っていることがわかる理由だと思います:Origin/masterからの2つとOrigin/nextにあった6つの「再ハッシュ」コミット。

git checkout next ; git rebase -i Origin/masterの後、これが必要です:

 ABC(マスター、オリジン/マスター)
\\ 
\D'-E'-F'-G'-H'-I '(次)
\
 DEFGHI(起源/次)

nextにはOrigin/nextにない8つのコミットがあり、Origin/nextにはnextにない6つのコミットがあることがわかります。これは、コミットのSHA-1ハッシュに基づいているだけです。 git diff Origin/next nextの場合、実際のコンテンツは非常に密接に一致する必要があります-diffはBおよびCからの変更のみを表示する必要があります(図にラベルが付いています)。

nextのままgit pull --rebaseを実行すると、ソース(リモートOrigin/next)から変更をフェッチし、現在のブランチ(next)をそのリモートにリベースします。これにより、nextにあった変更が、新しいnextブランチのOrigin/nextの後にOrigin/nextの-​​notに表示されます。次のようになります。

 ABC(マスター、オリジン/マスター)
\
 DEFGHI(オリジン/次)
\
 B'-C '(次)

これが履歴グラフを希望するものであれば、成功しました。

ただし、特にnextがプロジェクトの次の部分で作業している機能ブランチであり、masterが安定したコードで小規模な場合は、真ん中の図のように見えることを本当に望んでいたと思いますバグの修正。その場合は、git Pushの代わりにgit pull --rebaseを実行して、リモートが履歴のバージョンを反映するようにします(他の方法ではなく)。

54
Mike Seplowitz

マスターを使用してブランチをリベースするための非常に簡単な手順から始めます。名前;

git-rebase

あらすじ。

git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        [<upstream>] [<branch>]
git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
git rebase --continue | --skip | --abort | --edit-todo

説明;次の履歴が存在し、現在のブランチが「サンプル」であると仮定します。

 A---B---C sample
         /
    D---E---F---G master

この時点から、次のいずれかのコマンドの結果:

git rebase master
git rebase master sample

だろう:

A'--B'--C' sample
                 /
    D---E---F---G master

[〜#〜] note [〜#〜]:後者の形式は、git checkout sampleに続くgit rebase masterの省略形です。 rebaseが終了すると、サンプルはチェックアウトされたブランチのままになります。

アップストリームブランチに行った変更が既に含まれている場合(たとえば、アップストリームに適用されたパッチを郵送したため)、そのコミットはスキップされます。たとえば、次の履歴で「git rebase master」を実行します(AとAは同じ変更セットを導入しますが、コミッター情報は異なります)。

A---B---C sample
         /
    D---E---A'---F master

結果は次のとおりです。

 B'---C' sample
              /
D---E---A'---F master

これらはすべて、リベースプロセスの図式的な理解でした。 git rebase masterと入力した後に見つかった競合を解決したら、競合を解決し、git add -uと入力して、変更したコードをリポジトリに追加します。その後、コマンドgit rebase --continueを実行し、競合の解決を続け、コマンドを繰り返します。

git add -u 

そして

git rebase --continue 

競合が検出されなくなるまで。最後のコマンドは最終的に、

git Push --force Origin sample(your branch name)
0
Sam