Git merge hotfix branch into feature branch
Asked Answered
Q

11

1355

Let’s say we have the following situation in Git:

  1. A created repository:

    mkdir GitTest2
    cd GitTest2
    git init
    
  2. Some modifications in the master take place and get committed:

    echo "On Master" > file
    git commit -a -m "Initial commit"
    
  3. Feature1 branched off master and some work is done:

    git branch feature1
    git checkout feature1
    echo "Feature1" > featureFile
    git commit -a -m "Commit for feature1"
    
  4. Meanwhile, a bug is discovered in the master-code and a hotfix-branch is established:

    git checkout master
    git branch hotfix1
    git checkout hotfix1
    
  5. The bug is fixed in the hotfix branch and merged back into the master (perhaps after a pull request/code review):

    echo "Bugfix" > bugfixFile
    git commit -a -m "Bugfix Commit"
    git checkout master
    git merge --no-ff hotfix1
    
  6. Development on feature1 continues:

    git checkout feature1
    

Say I need the hotfix in my feature branch, maybe because the bug also occurs there. How can I achieve this without duplicating the commits into my feature branch?

I want to prevent to get two new commits on my feature branch which have no relation to the feature implementation. This especially seems important for me if I use pull requests: All these commits will also be included in the pull request and have to be reviewed although this has already been done (as the hotfix is already in the master).

I can not do a git merge master --ff-only: "fatal: Not possible to fast-forward, aborting.", but I am not sure if this helped me.

Quentinquercetin answered 6/6, 2013 at 7:18 Comment(14)
If branch feature1 is completely local, have a look at git rebase.Diakinesis
Thanks, as a git beginner, git rebase seems like black magic for me....Quentinquercetin
if the branch is feature-only the bug fix should not occur there (at least if is not a blocking bug) since the aim of this branch is to show a new feature. The bug will be fixed when merged with the master where the commit with the fix is present.Iridectomy
@Quentinquercetin 1.5 years later, I'm finding myself with the same question as you. Did you ever find a satisfactory approach to accomplish what you wanted?Durst
Probably worth noting for beginners that in 3. git branch feature1 and git checkout feature1 could be combined into git checkout -b feature1 and 4. could be entirely reduced to git checkout -b hotfix1 masterMinestrone
@Iridectomy there may be some scenarios. probably the feature depends on some other part which was fixed by the hotfix. Also, I had the case that I branched at a moment when a test was broken. It is annoying to have someone elses failed tests polluting the own test results.Robins
@Omnifarious, it would be helpful if you could identify which answer you thought is/was awful. At this point the accepted answer might have changed, so one doesn't know which one is to be avoided. Thanks. (Although I admit that the accepted answer at this moment, by David Sulc, looks very unappealing to me, even if it works and would be helpful in some situations. rebase should be a last resort, imo, and "manage all conflicts that arise" ... well.)Oligosaccharide
@Oligosaccharide - I should've specified. I meant this answer: https://mcmap.net/q/45349/-git-merge-hotfix-branch-into-feature-branchAstrodome
@Oligosaccharide and to be clear, that's the answer I think should be accepted.Astrodome
git fetch && git rebase -i origin/master is definitely the way to go if your feature branch is local... I'm having the same issue only, the feature branch is in the cloud and several developers are working on it.Greg
In steps 2, 3, and 5, the -a flag of git commit doesn't do what you are implying it does. For new files that are not already known to the repo, you need to manually git add. Once they have been committed once, future changes can be automatically added at commit time with git commit -aReceptive
Please consider accepting the "correct" answer, rather than one that is potentially misleading at best, and horribly misleading at worst.Acclimatize
A good gist article for reference- gist.github.com/digitaljhelms/4287848Wundt
This is a well structured question @theomega. This just fits to the scenario that brought me here. if questions were asked like this, answering would be easier.Bever
T
1630

How do we merge the master branch into the feature branch? Easy:

git checkout feature1
git merge master

There is no point in forcing a fast forward merge here, as it cannot be done. You committed both into the feature branch and the master branch. Fast forward is impossible now.

Have a look at GitFlow. It is a branching model for git that can be followed, and you unconsciously already did. It also is an extension to Git which adds some commands for the new workflow steps that do things automatically which you would otherwise need to do manually.

So what did you do right in your workflow? You have two branches to work with, your feature1 branch is basically the "develop" branch in the GitFlow model.

You created a hotfix branch from master and merged it back. And now you are stuck.

The GitFlow model asks you to merge the hotfix also to the development branch, which is "feature1" in your case.

So the real answer would be:

git checkout feature1
git merge --no-ff hotfix1

This adds all the changes that were made inside the hotfix to the feature branch, but only those changes. They might conflict with other development changes in the branch, but they will not conflict with the master branch should you merge the feature branch back to master eventually.

Be very careful with rebasing. Only rebase if the changes you did stayed local to your repository, e.g. you did not push any branches to some other repository. Rebasing is a great tool for you to arrange your local commits into a useful order before pushing it out into the world, but rebasing afterwards will mess up things for the git beginners like you.

Transpolar answered 6/6, 2013 at 8:42 Comment(10)
Doesn't this workflow lead into many unnecessary and duplicate commits? The commit from the hotfix-branch is copied into my feature branch and later merged back into the master. Doesn't this lead to the fact that the commit appears two times in the commit log?Quentinquercetin
No. The commit fixing the bug appears only once in the hotfix branch, even though the branch name gets deleted once it got merged into the master and devel branches. The merge commit only shows the changes introduced by the merge, which looks like a duplicate commit. But this is how git works: Branch and merge back. The real development work only takes place in non-merge commits, and the merge only is accepted if the result is working software.Transpolar
This should be the accepted answer. It works well with GitHub's pull request feature too.Bonesetter
I think it's worth noting that a git merge master will merge from your local copy of master, so even if you've done a git pull in your feature branch after someone else merged a different branch into master, you'll need to git checkout master, then git pull, then git checkout feature1 again and THEN git merge master.Psalmbook
@Psalmbook Or just git fetch and git merge origin/masterKannada
@Psalmbook @yngvar-kristiansen git pull origin master will automatically merge orgin/master to the current branchMammon
If I merge master into a feature, all the changes in my feature branch gets overriden (which is technically the right behaviour). However, I want to preserve the changes on feature and just get the updated code from master. How do I achieve this? I've made a new branch from master (dev actually which will also have the same code as master) and then merged my feature into this new branch (say feature_copy). But even that is not working.Basutoland
@Basutoland Merging \master into a \feature branch doesn't override \feature changes; they get merged together. If there are changes that the merge can not figure out, then it becomes a conflict, which you resolve manually (this is the only time \feature changes could get wiped).Sinclair
Is the git checkout feature1 cmd executed at the branch local folder?Vindicable
@Basutoland did you find a way to fix your problem? I am having the same issue. If I have a local branch and I do git merge master, it merges just fine. But If I have a remote branch linked to my local, it shows all the master changes in my branch as well.Postprandial
O
666

You should be able to rebase your branch on master:

git checkout feature1
git rebase master

Manage all conflicts that arise. When you get to the commits with the bugfixes (already in master), Git will say that there were no changes and that maybe they were already applied. You then continue the rebase (while skipping the commits already in master) with

git rebase --skip

If you perform a git log on your feature branch, you'll see the bugfix commit appear only once, and in the master portion.

For a more detailed discussion, take a look at the Git book documentation on git rebase (https://git-scm.com/docs/git-rebase) which cover this exact use case.

================ Edit for additional context ====================

This answer was provided specifically for the question asked by @theomega, taking his particular situation into account. Note this part:

I want to prevent [...] commits on my feature branch which have no relation to the feature implementation.

Rebasing his private branch on master is exactly what will yield that result. In contrast, merging master into his branch would precisely do what he specifically does not want to happen: adding a commit that is not related to the feature implementation he is working on via his branch.

To address the users that read the question title, skip over the actual content and context of the question, and then only read the top answer blindly assuming it will always apply to their (different) use case, allow me to elaborate:

  • only rebase private branches (i.e. that only exist in your local repository and haven't been shared with others). Rebasing shared branches would "break" the copies other people may have.
  • if you want to integrate changes from a branch (whether it's master or another branch) into a branch that is public (e.g. you've pushed the branch to open a pull request, but there are now conflicts with master, and you need to update your branch to resolve those conflicts) you'll need to merge them in (e.g. with git merge master as in @Sven's answer).
  • you can also merge branches into your local private branches if that's your preference, but be aware that it will result in "foreign" commits in your branch.

Finally, if you're unhappy with the fact that this answer is not the best fit for your situation even though it was for @theomega, adding a comment below won't be particularly helpful: I don't control which answer is selected, only @theomega does.

Obligee answered 6/6, 2013 at 7:24 Comment(19)
Okay, let's assume I already pushed the branch to github for a pull request (in a branch of the main repository). Is it still save to do the git rebase (maybe assuming that no-one has checked out my branch)?Quentinquercetin
No, it's not safe: if you rebase, you're changing the branch's history, which will affect the developers that pulled the branch. inf act, git won't let you push a rebased branch by default: you need to force the update with -f when pushing to overwrite the branch with the rebased version. Be careful!Obligee
How do professional teams using git handle this issue? Do the just pay attention, think carefully and then do a -f? Or is my complete workflow flawed because I need a -f?Quentinquercetin
Well, I'd venture the "sacred" rule is you don't rebase (or otherwise change commit history) on code that has been shared: it's only for your local code. Basically, you should rebase your changes to "clean up" before sharing it. In your case, you can push a new rebased branch (with a different name), and ask colleagues to base their changes off that branch (i.e. by rebase their local branch off the new one, as above). Then, delete feature1 from Github.Obligee
Most of the professional teams I've worked on almost never use rebase - they just merge everything by default, so that no history modification ever happens. This is my preferred way of working. On the other hand, some teams use rebase to 'clean up' commits before they push them (but never after pushing.)Sailboat
Yes, you should NEVER rebase public branches. However, OP's question seemed to deal with integrating new commits made on master into a private branch (he mentions "his" local branch). In that case, rebase is fine and is the same use case as the "cleaning up" you mention.Obligee
This is a terrible idea. rebase is the wrong way to handle this, it's almost always the wrong way to handle things. It's for people who've made a mistake, or for people who don't understand how DVCSes work.Astrodome
It would be great if you could expand on why you think it's a terrible idea: the git docs specifically give these as examples uses of rebase git-scm.com/docs/git-rebase It's clear you shouldn't rebase a public/shared branch, but using it to rewrite/clean up history on your private branch (including updating it to branch off master) is fine: that's precisely why private branches exist. Saying the rebase command is for people who made mistakes or don't understand DVCS seems a bit misguided to me.Obligee
@DavidSulc - It's a terrible idea because it destroys the development history.. Depending on what you rebase on, it looks like your feature started with code it didn't start with, and that might be nonsensical. When I see a repository with no branches I know that repository is lying to me.Astrodome
@Astrodome if I created a branch and then made some commits on master, is rebase an acceptable option, as no development has been made on the new branch?Joshia
@DineiRockenbach - Yes, it's fine then. You're just rebasing your local directory then.Astrodome
Rebasing rewinds the head and then replays your work on top of it. It's perfect for applying work that was done in master over to your feature branch as if it happened before the branch. Obviously be careful if you've made a bunch of commits to your feature branch, because the commits from master will be placed before all commits in the feature branch.Brittenybrittingham
@Quentinquercetin "Assume I already pushed the branch to github for a pull request. Is it still safe to do the git rebase assuming that no-one has checked out my branch." If no one checked it out, then it is safe in that it won't cause problems for others. This is a common pattern if your branch is far behind master. You still have to be careful since rebase is not reversible. If you do not properly fix merge conflicts and force push, those commits are destroyed and new ones are committed.Scharaga
This is very unsafe, as I found it out after blindly typing this in. I would be glad seeing this answer unaccepted.Bumf
@Bumf If your branch had no conflicts with master, then you would have ended up with the same code base as merging master into your branch. It's more likely that after "blindly typing stuff in" you resolved merge conflicts incorrectly (i.e. introduced errors). Unfortunately, this (the incorrect merging) would have caused the same issues in your code when merging master into your branch.Obligee
Why is this the accepteid answer, this isn't an acceptable solution.Summand
+1 to other comments that this is an unacceptable solution. This is not the right answer. Is it not possible to "edit" this post in a way to modify the accepted answer?Acclimatize
how to merge master branch to local branchIndamine
Please, Sven's answer is the right one, not this one. You should not rebase in this scenario.Magnifico
I
91

git merge

you can follow below steps

1. merge origin/master branch to feature branch

# step1: change branch to master, and pull to update all commits
$ git checkout master
$ git pull

# step2: change branch to target, and pull to update commits
$ git checkout feature
$ git pull

# step3: merge master to feature(⚠️ current is feature branch)
$ git merge master


2. merge feature branch to origin/master branch

origin/master is the remote master branch, while master is the local master branch

$ git checkout master
$ git pull origin/master

$ git merge feature
$ git push origin/master

Indamine answered 12/11, 2019 at 7:38 Comment(6)
ref #5602431Indamine
ref #18137675Indamine
Feels like rebase is hyped! Good old merge :) !Battiste
Tried git merge master from another answers and get Already up to date. Your answer helps understand I have old master locally. Thank you!Deepset
I do the 1. git merge master on my branch. My branch is local and remote. But after git merge master, I always see all the new changes/commits from master in my branch. When I create a PR, it shows all the files = my changes + others changes from the master. Am I doing something wrong?Postprandial
@NikitaP if you want to make a PR, I think you should use solution 2. The following articles may help you. docs.github.com/en/pull-requests/… atlassian.com/git/tutorials/making-a-pull-requestIndamine
H
76

Based on this article, you should:

  • create new branch which is based upon new version of master

    git branch -b newmaster

  • merge your old feature branch into new one

    git checkout newmaster

  • resolve conflict on new feature branch

The first two commands can be combined to git checkout -b newmaster.

This way your history stays clear because you don't need back merges. And you don't need to be so super cautious since you don't need to do a Git rebase.

Harumscarum answered 9/6, 2014 at 14:16 Comment(3)
would be nice if you make the related git command follow each point. Otherwise it seems to me that this is indeed the more safe and clean option.Crenelation
@Harumscarum What's about if we have a remote branch? Will we recreate new update feature branch again? Or can we just set remote-upstream?Cambridgeshire
@Crenelation I've just posted my own answer with more details, including the related git commands.Chadburn
W
37

I add my answer, similar to others but maybe it will be the quickest one to read and implement.

NOTE: Rebase is not needed in this case.

Assume I have a repo1 and two branches master and dev-user.

dev-user is a branch done at a certain state of master.

Now assume that both dev-user and master advance.

At some point I want dev-user to get all the commits made in master.

How do I do it?

I go first in my repository root folder

cd name_of_the_repository

then

git checkout master 
git pull 
git checkout dev-user
git pull
git merge master 
git push 

I hope this helps someone else in the same situation.

Witticism answered 8/7, 2020 at 11:42 Comment(2)
from which folder do you execute the git checkout master? from the branch folder?Vindicable
@JoseCabreraZuniga, I do it from the root folder of your repository.Witticism
C
30

Zimi's answer describes this process generally. Here are the specifics:

  1. Create and switch to a new branch. Make sure the new branch is based on master so it will include the recent hotfixes.

    git checkout master
    git branch feature1_new
    git checkout feature1_new
    
    # Or, combined into one command:
    git checkout -b feature1_new master
    
  2. After switching to the new branch, merge the changes from your existing feature branch. This will add your commits without duplicating the hotfix commits.

    git merge feature1
    
  3. On the new branch, resolve any conflicts between your feature and the master branch.

Done! Now use the new branch to continue to develop your feature.

Chadburn answered 8/3, 2017 at 8:56 Comment(3)
The problem with this is that a developer wastes time constantly spawning new branches when they need to update against master. We would be making lots and lots of branches, probably 3 times per day during active work. You should write instructions about cleanjng up all of the local trash branches, and how to get rid of them on remote too. We also need advice on naming all these branches so we dont get confused. Without that bit, this will turn a branch system into chaos.Threegaited
You're right, this shouldn't be done all the time. Only when (1) the changes on master are necessary for your feature, or (2) you're about to merge your branch with master and there might be conflicts. And to avoid clutter, you can delete your branch after it's merged.Chadburn
This approach does not work well if you already submitted a pull request on the feature branch and the PR is in-progress, code review would have been done again on the new feature branch with unnecessary work.Acotyledon
G
13

Here is a script you can use to merge your master branch into your current branch.

The script does the following:

  • Switches to the master branch
  • Pulls the master branch
  • Switches back to your current branch
  • Merges the master branch into your current branch

Save this code as a batch file (.bat) and place the script anywhere in your repository. Then click on it to run it and you are set.

:: This batch file pulls current master and merges into current branch

@echo off

:: Option to use the batch file outside the repo and pass the repo path as an arg
set repoPath=%1
cd %repoPath%

FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)

echo current branch is %currentBranch%
echo switching to master
git checkout master
echo.
echo pulling origin master
git pull origin master
echo.
echo switching back to %currentBranch%
git checkout %currentBranch%
echo.
echo attemting merge master into %currentBranch%
git merge master
echo.
echo script finished successfully
PAUSE
Gasper answered 13/11, 2018 at 11:59 Comment(0)
E
10

You might be able to do a "cherry-pick" to pull the exact commit(s) that you need in to your feature branch.

Do a git checkout hotfix1 to get on the hotfix1 branch. Then do a git log to get the SHA-1 hash (big sequence of random letters and numbers that uniquely identifies a commit) of the commit in question. Copy that (or the first 10 or so characters).

Then, git checkout feature1 to get back onto your feature branch.

Then, git cherry-pick <the SHA-1 hash that you just copied>

That will pull that commit, and only that commit, into your feature branch. That change will be in the branch - you just "cherry-picked" it in. Then, resume work, edit, commit, push, etc. to your heart's content.

When, eventually, you perform another merge from one branch into your feature branch (or vice-versa), Git will recognize that you've already merged in that particular commit, know that it doesn't have to make it again, and just "skip over" it.

Evolutionary answered 2/10, 2013 at 5:39 Comment(2)
I don't consider this a good idea. Then, IMO, the hotfix commit will really show up in your feature branch's history, which you basically do not want.Replicate
“When, eventually, you perform another merge from one branch into your feature branch (or vice-versa), git will recognize that you've already merged [...]” — is that how it actually works? I don’t think that git merge works in this “replay commits”-way that you seem to be hinting to (“and just skip over it”). Mixing cherry picking and merging can apparently lead to problems; see: news.ycombinator.com/item?id=3947950Typewriter
G
5

Complementing the existing answers, as these commands are recurrent we can do it in a row. Given we are in the feature branch:

git checkout master && git pull && git checkout - && git merge -

Or add them in an alias:

alias merge_with_master="git checkout master && git pull && git checkout - && git merge -"
Greenhead answered 13/11, 2020 at 16:59 Comment(0)
C
0

I am on the feature branch and made refactorings. I want to merge the master changes now to my feature branch. I am far behind. Note I do not want to pull the master changes to my local because my feature branch have modules moved from one place to another. I found just performing below without pull does not work. it says "Already up to date."

 //below does not get the latest from remote master to my local feature branch without git pull
    git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge master

This below works, note use git merge origin/master:

 git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge origin/master
Catalan answered 15/5, 2020 at 1:12 Comment(0)
U
-3
In Eclipse -

1)Checkout master branch

Git Repositories ->Click on your repository -> click on Local ->double click master branch
->Click on yes for check out

2)Pull master branch

Right click on project ->click on Team -> Click on Pull

3)Checkout your feature branch(follow same steps mentioned in 1 point)

4)Merge master into feature

Git Repositories ->Click on your repository -> click on Local ->Right Click on your selected feature branch ->Click on merge ->Click on Local ->Click on Master ->Click on Merge.

5)Now you will get all changes of Master branch in feature branch. Remove conflict if any.

For conflict if any exists ,follow this -
Changes mentioned as Head(<<<<<< HEAD) is your change, Changes mentioned in branch(>>>>>>> branch) is other person change, you can update file accordingly.

Note - You need to do add to index for conflicts files

6)commit and push your changes in feature branch.

Right click on project ->click on Team -> Click on commit -> Commit and Push.

OR

Git Repositories ->Click on your repository -> click on Local ->Right Click on your selected feature branch ->Click on Push Branch ->Preview ->Push
Untenable answered 3/8, 2020 at 4:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.