简体   繁体   中英

Git - How to recurringly squash merge to a master branch

I have two branches:

  1. a personal branch that I commit to several times a day.
  2. a "dev" branch, that I occasionally want to merge my personal branch changes to, but with squashed commit messages.

After merging, I want to continue using my same personal branch, and then be able to re-merge back to the dev branch at will.

With svn, this is fairly easy to do without ever getting any merge conflicts.

  1. commit multiple changes on personal branch
  2. Merge changes to dev branch, which will record a single commit message
  3. Merge change from step 2 back to personal branch, but "only record merge info" so that it doesn't merge any content.
  4. Repeat step 1.

Now by dev branch knows what it has from the personal branch, and my personal branch knows that it has everything from the master branch.

With git, I've tried using git merge --squash to go from personal branch to dev branch, which worked great the first time around. But the second time around I get a bunch of conflicts. Since the merge --squash doesn't merge the original commits, but makes a new commit that is unrelated to the original commits, git doesn't realize that I've already merged a bunch of content from my personal branch to the dev branch.

Is there any solution to this workflow in git? It seems like if I merge --squash a branch, I have to make a new branch for the next time around.

Do you want the squashed revisions to be on the side of dev? Like, one squash revision after the other? If that's the case, you could do:

git checkout --detach my-branch
git reset --soft the-previous-squash-commit
git commit -m "A new squash operation that covers revisions x, y and z"
git checkout dev
git merge -m "Merging a new squash commit" HEAD@{1} # given that I didn't have a branch set up for the squashed revision

I think there should not be any conflicts there.

The first thing to understand is that the way you describe the desired behavior (merge to the target recording only 1 commit) is exactly how default merges work.

The reason it may seem otherwise is that many git commands, by default, follow all of the branches that feed into a merge. You can change that by giving the --first-parent option to the command

git log --first-parent

Both regular merges and "squash merges" record exactly one new commit and place it on the target branch (ie the branch checked out when you issue the command).

The difference is that squash merges pretend they aren't writing a merge - that is, the only parent of the new commit is the target branch's previous tip. A normal merge has a 2nd parent - whatever branch you merge in - and as you've noticed, that is needed if you want a subsequent merge to work properly.

You can jump through hoops to reinvent the wheel. For example eftshift0 has given you a way to, at any time, make dev match the tip of your other branch - which is kind of like merging irrespective of merge base, so long as there's nowhere except your branch that ever contributes to dev . And if you search SO you can even find more general solutions.

But what all of these solutions have in common is, they're working against the grain of how git is meant to work. It's really much easier to use git as intended - ie just merge your branch into dev when you want to carry those changes, and if you want output that doesn't follow the side-branch use first-parent .

After a git merge --squash , a branch should not be used for further merging.

If you insist on using a squash merge, you can use this flow:

git checkout dev
git merge --squash personal
git tag personal_1_0 personal  #optional to save old personal branch
git checkout -B personal

In effect, you create a new personal branch from the current dev, and you can squash merge from it, later. Do this every time you squash merge (using a different tag each time).

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