How do I safely merge a Git branch into master?
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 develo开发者_StackOverflow社区pers 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.
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
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:
It's unsafe, because we don't know if there are any conflicts between test branch and master branch.
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:
- if you are not sure about rebasing operations, please refer to: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
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.
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
- In git, what is the difference between merge --squash and rebase?
- Merging vs. Rebasing
- How to Rebase a Pull Request
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
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.
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.
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.
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.
@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
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
.
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
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
This is from GitLab: Just follow the instructions:
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
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
精彩评论