How do I safely merge a Git branch into master?
Asked Answered
K

17

2636

A new branch from master is created, we call it test.

There are several developers who either commit to master or create other branches and later merge into master.

Let's say work on test is taking several days and you want to continuously keep test updated with commits inside master.

I would do git pull origin master from test.

Question 1: Is this the right approach? Other developers could have easily worked on same files as I have worked btw.


My work on test is done and I am ready to merge it back to master. Here are the two ways I can think of:

A:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B:

git checkout test
git pull origin master
git checkout master
git merge test

I am not using --rebase because from my understanding, rebase will get the changes from master and stack mine on top of that hence it could overwrite changes other people made.

Question 2: Which one of these two methods is right? What is the difference there?

The goal in all of this is to keep my test branch updated with the things happening in master and later I could merge them back into master hoping to keep the timeline as linear as possible.

Kist answered 9/4, 2011 at 0:1 Comment(3)
no.. rebase never overwrite, it just trying to achieve a cleaner history. by reattach(or fake) the history to the late point of the masterEncroach
rebase doesn't overwrite your commits. It undoes your commits, applies the commits in the master branch to your test branch, then applies your commits back to test.Octosyllable
What if we don't have write access to master? Any way to fix conflicts pre-emptively on the feature branch? Probably not I guess, since the histories have probably divergedWhiz
D
3637

How I would do this

git checkout master
git pull origin master
git merge test
git push origin master

If I have a local branch from a remote one, I don't feel comfortable with merging other branches than this one with the remote. Also I would not push my changes, until I'm happy with what I want to push and also I wouldn't push things at all, that are only for me and my local repository. In your description it seems, that test is only for you? So no reason to publish it.

git always tries to respect yours and others changes, and so will --rebase. I don't think I can explain it appropriately, so have a look at the Git book - Rebasing or git-ready: Intro into rebasing for a little description. It's a quite cool feature

Donne answered 9/4, 2011 at 0:45 Comment(14)
git merge test gives me fatal: 'test' does not point to a commit. I have to look in git log for the commit point on the test branch, switch back to master branch then do git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234.Fawne
@Fawne Well, of course the branch test must exist. Sure, you can use the commit hash instead, but it's usually easier to use the branch name. Internally it just retrieves the hash of HEAD of the branch.Donne
@shanyangqu To get the latest changes from the remote. If you work alone and only with one system ever there is no problem. But when there are changes pushed from a different system (probably from a different developer) you'll see a conflict as soon as you try to push your merge back (the 4th step). The only solution now is to merge your local master into the remotes master, which ends up in a pretty ugly "merged master into origin/master" merge commit. So it's always a good idea to make a pull before the mergeDonne
You might want to push test if it will only be backed up when it is on your central git server. This is especially fine if you are working on your own fork.Aliment
this shows the commits to the fb (test branch) as if committed straight into master, as opposed to showing the commits on their original fb, and just the merge into master (as seen with gitk, or on gitlab "network")Acetum
Is it not safer to merge origin/master into test first before before merging test into master? Wouldn't the above make test out of date?Consulate
@Consulate Well... It depends. On the workflow. For example many only commit features and bug-fixes into develop and only hotfixes (and maybe important bugfixes) into master. Then they forward-port the hotfixes from develop into master (that's technically what you said). However, if there is no hotfix (which is always good :)), then develop is always in front of master. So yeah, you are right, but depending on the workflow it is maybe simply not necessary. (I used develop here, because it's more common than test).Donne
" In your description it seems, that test is only for you? So no reason to publish it." You might want to push your local branch up to a server if, for example, that server provides a backup against your local drive failing or if you don't have another means to do a backup.Hornpipe
"...Also I would not push my changes, until I'm happy with what I want to push..." why not pushing for the sake of having your code backed up, in case your local machines dies and days of efforts are gone?Brent
This answer seems wrong to me. The OP is asking how to keep the test branch updated with the master - and this answer is only showing how to merge the test into master.Laudianism
If git merge test gives fatal: refusing to merge unrelated histories then git merge test --allow-unrelated-histories work.Structural
One more thing .. new git are using "main" and not "master"Stoppage
@RichSteinmetz Because git is not a backup system, it's version control. The purpose of version control is to sync code to a repo and/or optionally other developers, and as such every push to the repo should be in a complete working state, not there just because it needed to be backed up. Your code should be backed up in the same way that everything else on your computer should be - using a proper backup solution.Parahydrogen
@HashimAziz that would be ideal, I agree. However, the biggest issue here could be highly asynchronous team setups with longer living feature branches (which, in my experience, is the norm). In those teams, if a developer is hit by the bus factor after even a couple of days of work, or even weeks, this might harm the team unless you have backup systems in the Cloud that can be accessed by the company (which is not the norm).Brent
C
533

This is a very practical question, but all the answers above are not practical.

Like

git checkout master
git pull origin master
git merge test
git push origin master

This approach has two issues:

  1. It's unsafe, because we don't know if there are any conflicts between test branch and master branch.

  2. It would "squeeze" all test commits into one merge commit on master; that is to say on master branch, we can't see the all change logs of test branch.

So, when we suspect there would some conflicts, we can have following git operations:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Test merge before commit, avoid a fast-forward commit by --no-ff,

If conflict is encountered, we can run git status to check details about the conflicts and try to solve

git status

Once we solve the conflicts, or if there is no conflict, we commit and push them

git commit -m 'merge test branch'
git push

But this way will lose the changes history logged in test branch, and it would make master branch to be hard for other developers to understand the history of the project.

So the best method is we have to use rebase instead of merge (suppose, when in this time, we have solved the branch conflicts).

Following is one simple sample, for advanced operations, please refer to http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Yep, when you have uppers done, all the Test branch's commits will be moved onto the head of Master branch. The major benefit of rebasing is that you get a linear and much cleaner project history.

The only thing you need to avoid is: never use rebase on public branch, like master branch.

Never do operations like the following:

git checkout master
git rebase -i test

Details for https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

appendix:

Colburn answered 14/3, 2015 at 12:13 Comment(8)
if you are not sure the rebase operation, please refer to: git-scm.com/book/en/v2/Git-Branching-RebasingColburn
I agree rebasing the test branch for later merging into master is the way to go. Even the other answers are correct this will keep history of changes of branch test in the head of master as the auther mention "you get a liner and much cleaner project" which is the purpose of version control system.Diarist
The statement "it's not one safety way, cause we don't know is there any conflicts between test branch and master branch" is not true: one can always abort the merge. And even if there are no conflicts you can always undo the last local commit as long as it is not pushed. Without correct understanding of git some things may seem a bit scary or unclear, but "unsafe" is just incorrect in any way. Please be careful not to confuse others with incorrect information.Langston
agree with @PaulvanLeeuwen, when you git merge the test branch into master, you will be notified about conflicts, and thats where you'll step in and merge the changes. Once you're done, you will commit the merge and push back. If you regret or cant seem to merge it correctly, you can always discard your work and pull from master again. So it is definitely not unsafe..Medley
why rebase -i ?Aun
Rebasing is inherently more unsafe than merging. Proposing rebasing as a more safer option to merging is wrong. Rebasing is a valid strategy, but comes with more caveats that the user should beware of.Esterify
Seems like git rebase -i master overwrite into the branch with what master has, is it normal?Externality
Why do you say "But this way will lose the changes history logged in test branch". Following the merge of the test branch into master all individual commits of the test branch will still be visible (and not squashed or anything). Am I missing something?Lyckman
B
102

Neither a rebase nor a merge should overwrite anyone's changes (unless you choose to do so when resolving a conflict).

The usual approach while developing is

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

When you're ready to merge back into master,

git checkout master
git log ..test # if you're curious
git merge test
git push

If you're worried about breaking something on the merge, git merge --abort is there for you.

Using push and then pull as a means of merging is silly. I'm also not sure why you're pushing test to origin.

Blastomere answered 10/4, 2011 at 0:17 Comment(7)
This process will increase number of commits, every time you switch between branches, you have to commit your branch.Backspin
What? Are you saying it will increase the number of commits every time you switch branches? Or are you saying that every time you switch branches, you have to "commit your branch"? The first is untrue and I'm not sure what the second means.Blastomere
before checkout, you have to commit branch. that is what i am sayingBackspin
You don't: that's (one of the things) git stash is for.Schoolgirl
I'd recommend git checkout test; git pull instead of git merge origin/test. Even better is git pull --rebase. Anyway, you forgot to pull the changes, so before git merge origin/test you should git fetch origin test (git fetch .. && git merge .. is exactly, what git pull .. does :))Donne
In theory, if test is at a different remote than master, yes. But since you generally only have one remote, pulling once updates both and then you can just merge (or rebase).Blastomere
Or you could ammend your last commit (in local branch) and make it the perfect one before pushing.Halation
C
54

I would first make the to-be-merged branch as clean as possible. Run your tests, make sure the state is as you want it. Clean up the new commits by git squash.

Besides KingCrunches answer, I suggest to use

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

You might have made many commits in the other branch, which should only be one commit in the master branch. To keep the commit history as clean as possible, you might want to squash all your commits from the test branch into one commit in the master branch (see also: Git: To squash or not to squash?). Then you can also rewrite the commit message to something very expressive. Something that is easy to read and understand, without digging into the code.

edit: You might be interested in

So on GitHub, I end up doing the following for a feature branch mybranch:

Get the latest from origin

$ git checkout master
$ git pull origin master

Find the merge base hash:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Now make sure only the first is pick, the rest is s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Next choose a very good commit message and push to GitHub. Make the pull request then.

After the merge of the pull request, you can delete it locally:

$ git branch -d mybranch

and on GitHub

$ git push origin :mybranch
Cairistiona answered 21/4, 2016 at 8:18 Comment(3)
"which should only be one commit in the master branch", well not necessarily; you may wekk want to keep the historyAili
Sure. But then simply don't squash the commitsCairistiona
I think --first-parent seems to be the best solution. davidchudzicki.com/posts/first-parentBlumenthal
V
27

Old thread, but I haven't found my way of doing it. It might be valuable for someone who works with rebase and wants to merge all the commits from a (feature) branch on top of master. If there is a conflict on the way, you can resolve them for every commit. You keep full control during the process and can abort any time.

Get Master and Branch up-to-date:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

Merge Branch on top of Master:

git checkout <branch_name>
git rebase master

Optional: If you run into Conflicts during the Rebase:

First, resolve conflict in file. Then:

git add .
git rebase --continue

You could abort the rebase anytime with:

git rebase --abort

Push your rebased Branch:

git push origin <branch_name>

If you have this branch pushed before, you need to override it with a force push:

git push origin -f <branch_name>

Before doing so, check always whether your current local branch matches your expectations, because the force push overrides the old one in the remote repository.

Now you've got two options:

  • A) Create a PR (e.g. on GitHub) and merge it there via the UI
  • B) Go back on the command line and merge the branch into master
git checkout master
git merge --no-ff <branch_name>
git push origin master

Done.

Vacant answered 31/10, 2018 at 4:14 Comment(0)
C
7

This is the workflow that I use at my job with the team. The scenario is as you described. First, when I'm done working on test I rebase with master to pull in whatever has been added to master during the time I've been working on the test branch.

git pull -r upstream master

This will pull the changes to master since you forked the test branch and apply them, and then apply the changes you've made to test "on top of" the current state of master. There may be conflicts here, if the other people have made changes to the same files that you've edited in test. If there are, you will have to fix them manually, and commit. Once you've done that, you'll be good to switch to the master branch and merge test in with no problems.

Cavuoto answered 16/3, 2016 at 22:27 Comment(0)
F
6

I would use the rebase method. Mostly because it perfectly reflects your case semantically, ie. what you want to do is to refresh the state of your current branch and "pretend" as if it was based on the latest.

So, without even checking out master, I would:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

Of course, just fetching from origin does not refresh the local state of your master (as it does not perform a merge), but it is perfectly ok for our purpose - we want to avoid switching around, for the sake of saving time.

Frausto answered 13/9, 2018 at 7:13 Comment(0)
P
5
git checkout master
git pull origin master
# Merge branch test into master
git merge test

After merging, if the file is changed, then when you merge it will through error of "Resolve Conflict"

So then you need to first resolve all your conflicts then, you have to again commit all your changes and then push

git push origin master

This is better do who has done changes in test branch, because he knew what changes he has done.

Particiaparticipant answered 7/4, 2015 at 8:55 Comment(0)
A
5

@KingCrunch's answer should work in many cases. One issue that can arise is you may be on a different machine that needs to pull the latest from test. So, I recommend pulling test first. The revision looks like this:

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master
Aldis answered 28/2, 2020 at 2:21 Comment(0)
B
5

I'll answer as per develop and feature branches,

if you're on feature branch and need to update it with develop use the below commands:

git checkout develop
git pull
git checkout feature/xyz
git merge develop

Now your feature/xyz is updated with develop branch and you can push your changes to remote feature/xyz.

Brycebryn answered 20/5, 2020 at 14:52 Comment(0)
K
3

As the title says "Best way", I think it's a good idea to consider the patience merge strategy.

From: https://git-scm.com/docs/merge-strategies

With this option, 'merge-recursive' spends a little extra time to avoid mismerges that sometimes occur due to unimportant matching lines (e.g., braces from distinct functions). Use this when the branches to be merged have diverged wildly. See also git-diff[1] --patience.

Usage:

git fetch
git merge -s recursive -X patience origin/master

Git Alias

I use always an alias for this, e.g. run once:

 git config --global alias.pmerge 'merge -s recursive -X patience'

Now you could do:

git fetch
git pmerge origin/master
Korns answered 16/11, 2019 at 1:15 Comment(0)
L
3

I always get merge conflicts when doing just git merge feature-branch. This seems to work for me:

git checkout -b feature-branch

Do a bunch of code changes...

git merge -s ours master 

git checkout master

git merge feature-branch

or

git checkout -b feature-branch

Do a bunch of code changes...

git checkout master

git merge -X theirs feature-branch
Leaguer answered 27/9, 2020 at 7:49 Comment(0)
M
1

Disclaimer: I am a junoir in using git. This answer is based mainly on recommendations given to me by my senior colleagues. If the answer is flawed, please let me know, and I will adjust it.

To expand on KingCrunch's answer, if you want to be EXTRA SAFE and sure that you will not mess up your master branch or your new-feature branch, you can use the following steps. Using these steps you keep both the master branch as well as the new-feature branch unchanged until you are sure that everything will work after the merge.

First, update your master branch from remote repository:

git switch master
git pull origin master

Next, create a copy of your new-feature branch (in order to keep your new-feature branch safe):

git switch new-feature
git branch new-feature-copy

Now, switch to the copied branch (new-feature-copy) and merge the master branch to this branch. In this step, you can resolve any conflicts. After the merge, test that everything works as intended:

git switch new-feature-copy
git merge master

Finally, switch to master branch and merge it with the new-feature-copy branch. As the new-feature-copy branch already has the commits from master branch, the merge should be conflict-free:

git switch master
git merge new-feature-copy
Mainz answered 9/5, 2023 at 19:11 Comment(1)
Kudos for the disclaimer and sharing the senior's habits. Thank you.Ceuta
L
0

You have to have the branch checked out to pull, since pulling means merging into master, and you need a work tree to merge in.

git checkout master
git pull

No need to check out first; rebase does the right thing with two arguments

git rebase master test  

git checkout master
git merge test

git push by default pushes all branches that exist here and on the remote

git push
git checkout test
Like answered 15/11, 2019 at 11:35 Comment(0)
A
0

This is from GitLab: Just follow the instructions:

enter image description here

Abampere answered 5/12, 2019 at 8:18 Comment(3)
In step-1, you are checking out some feature branch and then in step-2 you are again checking out the master branch. I am confused, why to check out the feature branch in the first place ?? Please explainUnger
It's because that in this scenario it's first made fetch from origin (remote) "feature" branch. after that in order to merge "feature" to "master" you need to checkout "master" and merge "feature" to it.Abampere
Then in first case, git fetch origin feature shouldn't be second command after checking out remote feature branch to sync local with remote feature?Unger
I
0

There are a lot of good answers here already. I am just adding the steps that I do.

git fetch -p
git checkout master
git rebase origin/master
git checkout test
git rebase master

Explanation

git fetch -p will retrieve any changes that have been made since your last fetch, and the -p prunes your branches, deleting any outdated branches.

git checkout master checkout the master branch

git rebase origin/master updates the master branch. doing a pull here will give you the same result.

git checkout test checkout the branch you have made changes on

git rebase master updates the test branch with changes on master. This merge any changed files, and if there are conflicts on any of your commits you will have to resolve them and then do a git rebase --continue or git rebase --abort

Inlay answered 23/9, 2021 at 13:36 Comment(0)
U
-2

git pull //will get the latest changes git checkout //to checkout the required branch git log //to check for the logs recently commited

git checkout test git log --since="last month" git pull origin master git status git merge test git status git commit -m " " git push

Utricle answered 17/11, 2023 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.