简体   繁体   English

Git - 如何反复压缩合并到主分支

[英]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.合并后,我想继续使用我相同的个人分支,然后可以随意重新合并回 dev 分支。

With svn, this is fairly easy to do without ever getting any merge conflicts.使用 svn,这很容易做到,而不会发生任何合并冲突。

  1. commit multiple changes on personal branch在个人分支上提交多项更改
  2. Merge changes to dev branch, which will record a single commit message将更改合并到 dev 分支,该分支将记录单个提交消息
  3. Merge change from step 2 back to personal branch, but "only record merge info" so that it doesn't merge any content.将步骤 2 中的更改合并回个人分支,但“只记录合并信息”,这样它就不会合并任何内容。
  4. Repeat step 1.重复步骤 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.现在,dev 分支知道它从个人分支中获得了什么,而我的个人分支知道它拥有来自 master 分支的所有内容。

With git, I've tried using git merge --squash to go from personal branch to dev branch, which worked great the first time around.使用 git,我尝试使用git merge --squash到 go 从个人分支到开发分支,第一次效果很好。 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.由于merge --squash不会合并原始提交,而是进行与原始提交无关的新提交,因此 git 没有意识到我已经将一堆内容从我的个人分支合并到 dev 分支.

Is there any solution to this workflow in git? git 中的这个工作流程有什么解决方案吗? It seems like if I merge --squash a branch, I have to make a new branch for the next time around.似乎如果我merge --squash一个分支,我必须为下一次创建一个新分支。

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.首先要了解的是,您描述所需行为的方式(仅合并到目标记录 1 次提交)正是默认合并的工作方式。

The reason it may seem otherwise is that many git commands, by default, follow all of the branches that feed into a merge.看起来不是这样的原因是,默认情况下,许多 git 命令遵循所有进入合并的分支。 You can change that by giving the --first-parent option to the command您可以通过为命令提供--first-parent选项来更改它

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).常规合并和“squash 合并”都准确记录一个新提交并将其放置在目标分支上(即,当您发出命令时,分支已签出)。

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.不同之处在于 squash 合并假装他们没有编写合并 - 也就是说,新提交的唯一父级是目标分支的先前提示。 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 .例如,eftshift0 为您提供了一种方法,可以随时使dev与您的其他分支的尖端相匹配 - 这有点像合并而不管合并基础如何,只要您的分支对dev有贡献。 And if you search SO you can even find more general solutions.如果您搜索 SO,您甚至可以找到更通用的解决方案。

But what all of these solutions have in common is, they're working against the grain of how git is meant to work.但所有这些解决方案的共同点是,它们与 git 的工作原理背道而驰。 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 .按预期使用 git 确实要容易得多 - 即,当您想要进行这些更改时,只需将您的分支合并到 dev 中,如果您想要不遵循侧分支的 output 使用first-parent

After a git merge --squash , a branch should not be used for further merging.git merge --squash之后,不应使用分支进行进一步合并。

If you insist on using a squash merge, you can use this flow:如果你坚持使用 squash 合并,你可以使用这个流程:

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).每次压缩合并时都执行此操作(每次使用不同的标签)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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