master branch and 'origin/master' have diverged, how to 'undiverge' branches'? Ask Question

master branch and 'origin/master' have diverged, how to 'undiverge' branches'? Ask Question

Somehow my master and my origin/master branch have diverged.
I actually don't want them to diverge.

How can I view these differences and merge them?

ベストアンサー1

You can review the differences with a:

git log HEAD..origin/main

# old repositories
git log HEAD..origin/master

before pulling it (fetch + merge) (see also "How do you get git to always pull from a specific branch?")

Note: since Git 2.28 (Q3 2020), the default branch is configurable, and now (2021+) set to main, no longer master.
The rest of the answer reflects that more recent convention.


When you have a message like:

"Your branch and 'origin/main' have diverged, # and have 1 and 1 different commit(s) each, respectively."

Check if you need to update origin.
If origin is up-to-date, then some commits have been pushed to origin from another repo while you made your own commits locally.

... o ---- o ---- A ---- B  origin/main (upstream work)
                   \
                    C  main(your work)

You based commit C on commit A because that was the latest work you had fetched from upstream at the time.

However, before you tried to push back to origin, someone else pushed the commit B.
Development history has diverged into separate paths.

You can then merge or rebase. See Pro Git: Git Branching - Rebasing for details.

Merge

Use the git merge command:

$ git merge origin/main

# old repositories
$ git merge origin/master

This tells Git to integrate the changes from origin/main into your work and create a merge commit.
The graph of history now looks like this:

... o ---- o ---- A ---- B  origin/main (upstream work)
                   \      \
                    C ---- M  main (your work)

The new merge, commit M, has two parents, each representing one path of development that led to the content stored in that commit.

Note that the history behind M is now non-linear.

Rebase

Use the git rebase command:

$ git rebase origin/main

# old repositories
$ git rebase origin/master

This tells Git to replay commit C (your work) as if you had based it on commit B instead of A.
CVS and Subversion users routinely rebase their local changes on top of upstream work when they update before commit.
Git just adds explicit separation between the commit and rebase steps.

The graph of history now looks like this:

... o ---- o ---- A ---- B  origin/main (upstream work)
                          \
                           C'  main (your work)

Commit C' is a new commit created by the git rebase command.
It is different from C in two ways:

  1. It has a different history: B instead of A.
  2. Its content accounts for changes in both B and C; it is the same as M from the merge example.

背後の履歴はC'依然として線形であることに注意してください。
では (今のところ) 線形履歴のみを許可することを選択しましたcmake.org/cmake.git
このアプローチにより、以前使用されていた CVS ベースのワークフローが保持され、移行が容易になる可能性があります。リポジトリへの
プッシュを試みることC'は可能です (権限があり、リベース中に誰もプッシュしていないことを前提としています)。

このコマンドは、からの取得ローカルでの作業をgit pull簡単に行う方法を提供します。fetchoriginrebase

$ git pull --rebase

これにより、上記fetchrebase手順が 1 つのコマンドに結合されます。

おすすめ記事