简体   繁体   中英

How to merge all commits from one branch to another?

I want to merge branch A to master but when I use "git merge A" on master it will merge the branches but will only record one commit on master where as I commited like 20 on branch A. I would like to merge all the commits from A to master. How can I do that?

You have cross-tagged this as both and , and the answers are different for these two different situations.

GitHub offers a single button labeled "Merge pull request", with a dropdown triangle. Clicking on the triangle offers more options (at least normally— the GitHub help page says that this "Depend[s] on the merge options enabled for your repository"):

  • Create a merge commit
  • Squash and merge
  • Rebase and merge

The Git command line is different, being simultaneously simpler and more complicated. You can run any of these commands:

  • git merge to get a default action that is situation-dependent;
  • git merge --ff-only to prevent merging, but allow a fast-forward action;
  • git merge --squash to force a squash action, without creating a merge;
  • git merge --no-ff to force a merge action; or
  • git rebase followed by git merge --ff-only to copy the commits such that fast-forwarding is possible—this is the default rebase action—and then to do a fast-forward action.

The first of the three GitHub actions, "Create a merge commit", is equivalent to the command-line git merge --no-ff , in terms of final result (the difference is that GitHub won't offer this option at all if there are merge conflicts, but see this page as well). The second of the three GitHub actions is equivalent to the command-line git merge --squash and is what you described in your question:

... will only record one commit on master where as I committed like 20 on branch A

Note that the new commit has the same effect as the other N commits, but is an ordinary, non-merge, single-parent commit (this is hard to see in the GitHub interface as it tries to hide the nonlinear nature of Git commit graphs). See this GitHub help page squash diagram . (Note that the plain-merge diagram on that page is rather poor, but the squash one is decent.) A real merge, made with --no-ff on the command line, has two parents: the first parent is the previous commit on the branch on which you performed the merge (ie, master ), and the second parent is the tip commit of the branch that was merged (branch A in your example). This means that all N separate commits remain separate: there is just one new commit added that represents the result of combining those separate commits.

In many ways, this is the best result: it allows you to view the feature addition as a single unit (the merge commit), or as a series of changes (the N separate commits on the side branch). But it does make for a more tangled history: if the fact that there was a merge is expected to be useless or distracting in the future, while the N separate commits are expected to be useful (for debugging, for instance), it may be better to use a fast-forward operation.

As I mentioned above, a fast-forward is not a merge at all. However, fast-forward is only possible if all the "new" commits to be merged are "ahead of" all the current commits. Visualizing whether this is the case is, as far as I can tell, impossible 1 on GitHub.

If fast-forward is possible, the command-line command git merge will do it by default. If it's possible, git merge --ff-only will succeed. So if you want to attempt a fast-forward, but not create an actual merge commit if it's not possible, you can simply use git merge --ff-only and observe whether it succeeds or fails.

If a fast-forward is currently not possible, you can use git rebase to make it become possible, after which you can use git merge (optionally with --ff-only , either as a safety check, or to override any configuration you set with git config merge.ff ). Rebasing is somewhat complex, at least when it goes wrong, so as others said you should read up on it first.


1 Or at least, too difficult to bother. If there's a clicky button that shows the actual commit graph, that might be interesting.

Sounds like rebasing into master is what you're looking for.

Try:

git checkout A
git rebase master

I suggest that you read about the difference between merging and rebasing here https://www.atlassian.com/git/tutorials/merging-vs-rebasing

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM