1

In git if I have an old feature, lets call it, feature/improvement branched from master master gets like 500 commits, and feature/improvement needs updating I see 3 options.

  1. Merge master onto feature/improvement
  2. Merge feature/improvement onto the commit pointed at by master, and changing the branchref of feature/improvement to point to the new merged commit.
  3. rebase?

2 seems to be the most straight forward option to me, it shows a merge commit, and it shows the old changes, being re-applied to the lastest master changes.

But tools and history get very confused, because it's 'backwards' or 'reversed'

Am I mis-understanding something fundamental? Is there an obvious downside I don't understand?

Why Rebase?

Edit:

As requested, I've created a demo repo of 'reverse merge' I'm sorry for the poor git commands / typo's.

306  touch demo.txt
  307  echo "1" > demo.txt
  308  git add demo.txt
  309  git commit "Master 1"
  310  git status
  311  git commit -m "Master 1"
  312  echo "2" > demo.txt
  313  git commit "Master 2"
  314  git add .
  315  git commit -m "Master 2"
  316  git status
  317  git log
  318  git branch feature
  319  git checkout feature
  320  echo "a" > demo.txt
  321  echo "b" > demo.txt
  322  echo "c" > demo.txt
  323  git commit -m "feature c"
  324  git add .
  325  git commit -m "feature c"
  326  echo "d" > demo.txt
  327  git commit -m "feature d"
  328  git add .
  329  git commit -m "feature d"
  330  git checkout master
  331  echo "3" > demo.txt
  332  git add .
  333  git commit -m "master 3"
  334  echo "4" > demo.txt
  335  git add .
  336  git commit -m "master 4"
  337  echo "5" > demo.txt
  338  git add .
  339  git commit -m "master 5"
  340  git branch feature2
  341  git checkout feature2
  342  git merge help
  343  git help merge
  344  git merge feature
  345  git add .
  // This is where I gave up, and Used Source Tree to use a GUI to reset feature to feature2's ref
  346  git status
  347  git commit
  348  git status
  349  echo "e" > demo.txt
  350  git add .
  351  git commit -m "feature e"
  352  checkout -b "master"
  353  git checkout master
  354  git commit -m "master 6"
  355  echo "6" > demo.txt
  356  git add .
  357  git commit -m "master 6"

Which results in enter image description here

1
  • 1
    Regardless of which option you choose, you could end up with massive merge conflicts if the two branches are really far out of date with each other. Given that master is your authoritative reference branch, I would vote for brining the feature branch up to date with master first. So, either merge master into the feature branch, or rebase the feature branch on master. Commented Aug 10, 2018 at 10:26

3 Answers 3

3

Merging will take all of the changes in master and try to merge them with the changes of feature/improvement. Please excuse the poor ascii diagrams...

master   -------------
feature  \----\--
         ^    ^
    Branch    Merge

A rebase will take all of the changes in feature/improvement, and actually move them as if they were committed after the changes of master were committed.

Before rebase:

master   -------------
feature  \------
         ^
    Branch

After rebase:

master   -------------
feature               \------
                      ^
                 Branch

In other words:

  • Merge: "Combine these two commits"
  • Rebase: "Rewrite history so as all of the changes in my commit are only applied after master"
Sign up to request clarification or add additional context in comments.

1 Comment

You are missing the other option, merge feature into the head of master, and point the feature branch at that point and work from there, which is what my question is truly about. I called it 'reverse merge' for lack of a better name.
2

@Jim Wright's answer is a good one. Some additional thoughts on $ git rebase:

In terms of the resulting source code, what's the difference between merging and rebase?

None. Both operations will produce the same source code upon completion.

Why rebase?

Git's rebase operation will keep the history of your project more linear, thus, easier to read.

Aren't commands which "re-write" commit history like git rebase bad?

I don't think rebase is bad. It's a very useful technique for keeping history readable. Clean and readable VCS history is helpful in understanding the evolution of your project. I recommend keeping it tidy even if a little extra effort is involved.

On the other hand, if you're working with a published topic branch, you should avoid operations which re-write history because it may affect other team members who have pulled the branch. That said, some teams (like mine) have permissive rules about re-writing history on topic branches. My team is small. I might very well rebase if I'm confident that no one else has pulled my branch. I will also routinely rebase out dated topic branches when I'm merging a pull request.

What's up with "re-writing" commits? I thought Git history was cryptographically sealed?

Git never overwrites any commits. It copies or replays commits for operations like rebase. In fact, for a period of time, the commits Git copied from will still be available via the reflog. They aren't destroyed automatically with a rebase operation and can be recovered if necessary.

2 Comments

You are missing the other option, merge feature into the head of master, and point the feature branch at that point and work from there, which is what my question is truly about. I called it 'reverse merge' for lack of a better name.
My apologies for having misunderstood your question. So I can better understand your concept of "Reverse Merge" would you share which branch you have checked out and the specific git commands you're using to do the merge operation / pointing? FWIW, I think the main difference between your reverse merge operation and a rebase will be the common ancestor shared by the two branches.
0

I do not know about reverse merge. But in this situation, we have two options. First, git rebase. Let's see what rebase does. Consider the following history: master : c1,c2,c3,c4 improvement: c1,c2,c5,c6,c7 got checkout improvement git rebase master Now, first all the commits that you did on yot branch will be removed and then the new commits from the master will be applied make your history same as master. After this, rebase will apply your work on the top of it.

Your history becomes: c1,c2,c3,c4,c5,c6,c7

This makes the things really sophisticated according to me but in case you have already pushed changes from improvement to remote, doing a rebase is not advisable because it may create duplicate commits.

Second, git merge,

It will apply the commits from your master branch on the improvement branch along with a merge commit. It is advised to use this if you have already pushed tour branch remotely.

Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.