1. ホーム
  2. git

[解決済み] git pull *after* git rebase?

2023-02-25 06:11:41

質問

featureブランチとmasterブランチがあります。

masterブランチは進化しており、それらのアップデートはmasterブランチとできるだけ乖離しないようにすることを意図しています。

そこで私は git pull を両方のブランチで実行します。 git checkout feature/branch となり、最後に git rebase master .

さて、ここで私はすべてがスムーズに動くことを期待します または コンフリクトが発生し、feature ブランチにすべての master コミットが再適用されるまでリベースを続ける前に解決しなければなりません。

さて、私のケースで実際に起こったことは、私が理解していないことです。

$>git rebase master
First, rewinding head to replay your work on top of it...
Applying: myFirstCommitDoneOnTheBranch
Applying: myOtherCommitDoneOnTheBranch
$>git status
On branch feature/branch
Your branch and 'origin/feature/feature' have diverged,
and have 27 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$>git pull
*load of conflicts*

さて、プル後のコンフリクトの負荷については理解できるのですが、プルの必要性については理解できません。論理的には、ブランチした時点で master にロールバックし、ブランチでのコミットを保存し、master の最新のコミットにフォワードし、保存したコミットを適用する必要があります。

をどのように使うのか理解できません。 Applying メッセージは何を指しているのでしょうか: 何がどのバージョンにコミットを適用しているのでしょうか?

どのように解決するのですか?

tl;dr の両方を更新する必要があります。 masterfeaturegit pullgit pull --rebase 以前 リベース feature の上に master . をする必要はありません。 git pull の後に をリベースしています。 feature ブランチの上に master .

現在のワークフローでは、なぜ git status が教えてくれています。

あなたのブランチと 'origin/feature' は分岐しています。 それぞれ 27 と 2 の異なるコミットを持っています。

は、リベースされた feature ブランチに 25 から到達できない新しいコミットがあります。 origin/feature (にリベースされたものであるため)。 master にリベースされたものであるため)、さらに 2 は、以下のようにコミットします。 から到達可能な origin/feature から到達可能ですが、異なるコミット ID を持っています。これらのコミットには同じ変更が含まれています (つまり、これらのコミットは パッチと同等 の異なるコミットを元にしているため、SHA-1 ハッシュが異なります。 origin/feature の異なるコミットに基づいているため、SHA-1 ハッシュが異なります。

ここに例があります。これがあなたの履歴であるとします 以前 する git pullmaster :

A - B - C (master)
         \
          D - E (feature)

その後 git pull , master コミットを取得 F :

A - B - C - F (master, origin/master)
         \
          D - E (feature)

この時点で、リベース feature の上に master というように が適用されます。 D そして E :

A - B - C - F (master, origin/master)
             \
              D - E (feature)

一方、リモートブランチの origin/feature はまだコミット C :

A - B - C - F (master, origin/master)
         \   \
          \   D' - E' (feature)
           \
             D - E (origin/feature)

もしあなたが git statusfeature の場合、Git はあなたの feature ブランチから分岐したことを知らせます。 origin/feature とは 3 ( F , D' , E' ) と 2 ( D , E ) にそれぞれコミットしてください。

以下のことに注意してください。 D'E' と同じ変更を含みます。 DE の上にリベースされているため、コミットIDが異なります。 F .

解決策としては git pull の両方で masterfeature 以前 リベース featuremaster . しかし feature にまだプッシュしていないコミットがあるかもしれません。 origin にまだプッシュしていないものは、プッシュしておきたいものです。

git checkout feature && git pull --rebase

を作らないようにするため マージコミット の間に origin/feature とローカルの feature .

リベースの結果について更新しました。

を踏まえて このコメント , 分岐を拡大解釈してみました。その理由は git status が報告するのは featureorigin/feature 発散する は、リベースによって新しいコミットが feature に新しいコミットがもたらされ、さらに を書き換えます。 にプッシュされていたコミットを書き換えます。 origin/feature .

という状況を考えてみましょう。 引きはあるが をリベースします。

A - B - C - F (master)
         \
          D - E (feature, origin/feature)

この時点で featureorigin/feature は同じコミットを指しています E -言い換えれば、それらは " にあります。 同期 となります。リベース後 feature の上に master の上に置くと、履歴はこのようになります。

A - B - C - F (master)
         \   \
          \   D' - E' (feature)
           \
             D - E (origin/feature)

ご覧のように featureorigin/feature 分岐する 共通の祖先はコミット C . これは feature には新しいコミット F から master プラス D' そして E' (" と読みます。 Dプライム "および" Eプライム ")であり、これらはコミット DE の上に適用される F . 同じ変更を含んでいても、コミット ID が異なるため、Git はこれらを別物とみなします。一方 origin/feature はまだ DE .

この時点で、あなたは 歴史を書き換えた リベースによって既存のコミットを変更し、効果的に "新しい" を作成したことになります。

では、もしあなたが git pull を実行すると feature というようになります。

A - B - C - F (master)
         \   \
          \   D' - E'- M (feature)
           \         /
             D - E - (origin/feature)

以降 git pullgit fetch + git merge この場合、マージコミットが作成されます。 M が作成され、その親は E' であり E .

もし、代わりに git pull --rebase (を実行したとします(つまり git fetch + git rebase ) であれば、Git はそうなります。

  1. 移動 feature をコミットする C (の共通の祖先)。 featureorigin/feature )
  2. 適用 DE から origin/feature
  3. 適用 F , D'E'

しかし D'E' と同じ変更を含みます。 DE を含む場合、Git はそれらを単に破棄し、結果として以下のような履歴になります。

A - B - C - F (master)
         \   
          D - E - F' (feature)
              ^
             (origin/feature)

コミット F から到達可能であったものが feature の上に適用されました。 origin/feature となり F' . この時点で git status はこのように教えてくれるでしょう。

あなたのブランチは 'origin/feature' よりも 1 コミット分進んでいます。

そのコミットとは、もちろん F' .