Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

branch

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?

like image 391
Frank Avatar asked Mar 16 '10 05:03

Frank


People also ask

What does it mean when your branch has diverged?

Follow. Occasionally, you or your team members may run into a diverged branch. A diverged branch means the data you're looking at locally isn't the same as what is currently stored on our servers.

How does master branch differ from origin master?

Master: This is a branch name where we first initiate git and then we use to make commits. And the changes in the master can pull/push into a remote. origin/master: This is a remote branch, which has a local branch named master on a remote named origin.

What does diverged mean in git?

A Git branch divergence consists of the difference between the current state of two branches and the list of changes (commits) performed in each branch from the common state to get the current divergence (commits ahead and behind).


2 Answers

You can review the differences with a:

git log HEAD..origin/master 

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


When you have a message like:

"Your branch and 'origin/master' 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/master (upstream work)                    \                     C  master (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 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/master 

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

... o ---- o ---- A ---- B  origin/master (upstream work)                    \      \                     C ---- M  master (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/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/master (upstream work)                           \                            C'  master (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.

Note that the history behind C' is still linear.
We have chosen (for now) to allow only linear history in cmake.org/cmake.git.
This approach preserves the CVS-based workflow used previously and may ease the transition.
An attempt to push C' into our repository will work (assuming you have permissions and no one has pushed while you were rebasing).

The git pull command provides a shorthand way to fetch from origin and rebase local work on it:

$ git pull --rebase 

This combines the above fetch and rebase steps into one command.

like image 177
VonC Avatar answered Oct 04 '22 22:10

VonC


I had this and am mystified as to what has caused it, even after reading the above responses. My solution was to do

git reset --hard origin/master 

Then that just resets my (local) copy of master (which I assume is screwed up) to the correct point, as represented by (remote) origin/master.

WARNING: You will lose all changes not yet pushed to origin/master.

like image 25
skiphoppy Avatar answered Oct 04 '22 21:10

skiphoppy