Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git rebase already merged branch?

I created a feature branch from master branch. After that there is a commit [F1] from feature branch.

        [F1]            -- Feature Branch
       /
[M1]-[M2]               -- Master Branch

After that, feature branch is merged in master branch, and there are two more commits [M3] and [M4] in master branch.

        [F1]                   -- Feature Branch
       /    \
[M1]-[M2]-[F1]-[M3]-[M4]       -- Master Branch

Now I added two more commits to feature branch.

        [F1]-[F2]-[F3]         -- Feature Branch
       /   \
[M1]-[M2]-[F1]-[M3]-[M4]       -- Master Branch

At this time, should I first rebase the feature branch to master branch, so that feature branch has change of [M3] and [M4] commits, or should I do the git merge directly.

Also, if I do git rebase first, won't the [F1] commit be in both the branches:

                       [F1]-[F2]-[F3]       -- Feature Branch
                       /
[M1]-[M2]-[F1]-[M3]-[M4]                    -- Master Branch
like image 968
manish Avatar asked Jan 19 '16 09:01

manish


People also ask

Can we merge already merged branch?

Ideally, we would take all the changes in C*, apply them to master and resolve all conflicts. But because the branches have already been merged, git doesn't detect any changes and won't allow to merge again.

Can I reuse branch after merge?

You can always reuse that branch if you'd like or remove it. In Bitbucket Cloud we wont' remove the branch after a pull request is merged unless you use the "Close branch" checkbox during pull request creation.

Can I rebase again?

Yes, you can rebase more than once. After rebasing, you get a fresh set of commits. These commits are exactly like all other commits and hold no record of having been rebased. The main thing you need to be careful for is the possibility of rebase conflicts.


3 Answers

As correctly stated, no need for rebase.

For the last part of question:

"if I do git rebase first, won't the [F1] commit be in both the branches"

F1 commit would have been ommited if you proceeded with rebase.

According to https://git-scm.com/docs/git-rebase

If the upstream branch already contains a change you have made (e.g., because you mailed a patch which was applied upstream), then that commit will be skipped. For example, running git rebase master on the following history (in which A' and A introduce the same set of changes, but have different committer information):

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

will result in:

               B'---C' topic
              /
D---E---A'---F master
like image 90
Nikos Stais Avatar answered Sep 17 '22 22:09

Nikos Stais


So if you haven't made your changes to master and you don't mind rewriting history of master, there is a way to do this – but when you are rebasing you are rewriting history, so make sure you know what you are doing first.

If you are certain this is the direction you want to take your history, you should start by checking out the master branch and interactively rebasing it (git rebase -i) onto the commit where feature was cut from (in your case, [M2]).

Prior to your rebase, your history should look like this (as per your original problem):

        [F1]-[F2]-[F3]         -- Feature Branch
       /   \
[M1]-[M2]-[F1]-[M3]-[M4]       -- Master Branch

Once you start your interactive rebase, you should see the following actions:

pick hash_f1 [F1]
pick hash_m3 [M3]
pick hash_m4 [M4]

You will want to drop the first commit, the merged contents of feature prior to commits [F2] and [F3], so that master can replay the changes without [F1] in it. Note that you will not lose the [F1] commit, because it will still be in feature's history.

Rebasing should give you this history:

        [F1]-[F2]-[F3]         -- Feature Branch
       /
[M1]-[M2]-[M3]-[M4]            -- Master Branch

master has all M commits, and feature has all F commits, still cut from [M2]. From there it's a simple merge to get feature back into master:

git merge --no-ff feature

And voilà – you've got what you want:

        [F1]-[F2]-[F3]         -- Feature Branch
       /             \
[M1]-[M2]-[M3]-[M4]-[F*]       -- Master Branch

Again, be very careful that this is what you want to do, as rewriting history can be dangerous. That said, it is definitely worth it to do it locally.

Also, this process can be extended to any refs, not just a feature and master branch, so there are further cases where this may make more sense. In my opinion, a stable branch like master should typically not be able to have its history rewritten, but each Git environment and workflow is different, so really there are no rules which cannot be rewritten.

like image 27
Dykotomee Avatar answered Sep 18 '22 22:09

Dykotomee


You don't have to rebase. You can just do the merge. Rebasing creates a very clear history, but it is actually not a faithful representation of the history. Merging is safer, it is more straightforward, and it results in a true representation of the actions of developers.

People who come to git from other version control systems often dislike the complicated branching and merging history of git, so some of them are overusing the rebase feature. This takes extra effort, it fails more often than "merge", and it results in a false view of the history.

I'm not saying you should never use rebase, but as a rule of thumb I'd say the default should be to use "merge", and use rebase only when you really want to rewrite history.

One example of why rebase is useful is: Suppose you're making lots of incremental commits, and adding and reverting stuff on your local repository. Before you push to the global repository, you decide you want the other team members to see your contribution as a cleaner, single commit, taking out everything that's irrelevant. Then you use "interactive rebase" to consolidate your commits and improve the commit message, before pushing.

like image 31
Adi Levin Avatar answered Sep 18 '22 22:09

Adi Levin