简体   繁体   English

如何将3次提交与主服务器的一次合并重新定为一次提交?

[英]How can I rebase 3 commits with one merge of master into one commit?

I always seem to stumble and completely mess up git commits when I run into this scenario. 当我遇到这种情况时,我似乎总是迷迷糊糊,完全弄乱了git commits。 I'm hoping to avoid it this time around. 我希望这次能避免这种情况。 Here is my scenario. 这是我的情况。 I have the following 4 commits in my PR: 我的PR中有以下4个提交:

Commit 1: Remove unused routes for the projects controller
Commit 2: Add PR request changes and modify similar_by_tags_route
Commit 3: Merge Master and resolve git merge conflicts
Commit 4: Reinsert rubocop disablement for project.rb

I need these commits rebased into one commit. 我需要将这些提交重新构建为一个提交。 Now I can't just do a rebase -i HEAD~4 because of the pesky merge from master. 现在,由于主控器的讨厌合并,我不能只是重新设置rebase -i HEAD~4 Is there a way where I can simply remove commit 3 and just merge commits 1, 2, and 4? 有没有一种方法我可以简单地删除提交3并仅合并提交1、2和4? I would really like some help on this because I always seem to make a HUGE mess when it comes to tricky merges like this. 我真的希望对此有所帮助,因为在进行此类棘手的合并时,我似乎总是一团糟。

You can try doing an interactive rebase of your branch and just remove the line containing the merge commit. 您可以尝试对分支进行交互式的变基,而只需删除包含合并提交的行即可。 Running git rebase -i HEAD~4 should bring up a list of commits looking something like the following: 运行git rebase -i HEAD~4应该会显示一系列提交,如下所示:

pick Commit 1: Remove unused routes for the projects controller
pick Commit 2: Add PR request changes and modify similar_by_tags_route
pick Commit 3: Merge Master and resolve git merge conflicts
pick Commit 4: Reinsert rubocop disablement for project.rb

Delete the line containing the merge commit, leaving you with this: 删除包含合并提交的行,剩下的就是:

pick Commit 1: Remove unused routes for the projects controller
pick Commit 2: Add PR request changes and modify similar_by_tags_route
pick Commit 4: Reinsert rubocop disablement for project.rb

Now change the 2nd and 4th commit to squash , to tell Git to combine these commits into the single first commit: 现在将第2次和第4次提交更改为squash ,以告诉Git将这些提交合并为单个第一次提交:

pick Commit 1: Remove unused routes for the projects controller
squash Commit 2: Add PR request changes and modify similar_by_tags_route
squash Commit 4: Reinsert rubocop disablement for project.rb

Complete the rebase and you should be left with what you want. 完成变基,您应该随心所欲。 Note that rebasing like this means rewriting the history of your branch. 请注意,像这样重新定基础意味着重写分支的历史记录。 As such, you should take precaution if this branch is publicly shared by other people. 因此,如果此分支由其他人公开共享,则应采取预防措施。

If you haven't pushed to remote yet simply rebase: git rebase -i HEAD~4 then pick first commit, drop the third one and squash the others. 如果您还没有推送到远程,只是简单地重新设置了基准: git rebase -i HEAD~4然后pick第一个提交, drop第三个提交,然后squash其他提交。

Here is some example I did in my console: 这是我在控制台中所做的一些示例:

例

Note the commands that are available also, maybe you can choose something more appropriate now than you see all of them. 请注意也可用的命令,也许您现在可以选择比看到的所有命令更合适的命令。

However, if you pushed to remote I'd suggest you just revert third commit and leave the others because rebase rewrites history and can be devastating for people that already pulled your commits so I'd rather not play with history of git. 但是,如果您推送到远程位置,我建议您只还原第三个提交,然后再离开其他提交,因为重新编写基础会重写历史记录,并且对于已经撤消提交的人来说可能是毁灭性的,因此我宁愿不要使用git的历史记录。

Assume your 4 commits are on Branch B1 and that's the name of the branch that was used to create the PR. 假设您的4个提交位于分支B1上,这就是用于创建PR的分支的名称。

  1. Create a local branch B2 (identical to B1) 创建本地分支B2(与B1相同)
  2. Delete local branch B1 删除本地分支B1
  3. Create local branch B1 from origin/master 从来源/母版创建本地分支B1
  4. Cherry-pick commits 1, 2, 4 (in order) onto branch B1 by looking at their hashes in B2. Cherry-pick通过查看分支B1中的哈希将1,2,4,(按顺序)提交到分支B1上。
  5. Squash them (interactive rebase) 压扁它们(交互式变基)
  6. Force push B1 to origin 强制将B1推到原点
  7. Delete local branch B2 删除本地分支B2

Squash several Git commits into a single commit 将多个Git提交压缩为一个提交

This note shows how to merge an ugly feature branch with multiple dirty WIP commits back into the master as one pretty commit. 此注释显示了如何将具有多个脏WIP提交的丑陋功能分支作为一个漂亮的提交合并回主服务器。

Easy mode: Reset your feature branch to the master state 简易模式:将功能分支重置为主状态

The easiest way to turn multiple commits in a feature branch into a single commit is to reset the feature branch changes in the master and commit everything again. 将功能分支中的多个提交转换为单个提交的最简单方法是重置主节点中的功能分支更改,然后再次提交所有内容。

# Switch to the master branch and make sure you are up to date.

git checkout master

git fetch # this may be necessary (depending on your git config) to receive updates on origin/master

git pull

# Merge the feature branch into the master branch.

git merge feature_branch
# Reset the master branch to origin's state.

git reset origin/master

Git now considers all changes as unstaged changes. Git现在将所有更改视为未分段的更改。

# We can add these changes as one commit.

# Adding . will also add untracked files.

git add --all

git commit

Note that this is not touching the feature branch at all. 请注意,这根本不涉及功能分支。 If you would merge the feature branch into the master again at a later stage all of its commits would reappear in the log. 如果稍后将功能分支再次合并到母版中,则其所有提交将重新出现在日志中。

You may also do it the other way round (merging master into the branch and resetting to the master state) but this will destroy your commits in the feature branch, meaning you can not push it to origin. 您也可以反过来进行操作(将master合并到分支中并重置为master状态),但这会破坏您在feature分支中的提交,这意味着您无法将其推送到原始位置。

Hard mode: Squash commits 硬模式:壁球提交

This method is harder than using the get reset method above. 此方法比使用上面的get reset方法更难。 Also it doesn't work well if you merged the master into the feature branch previously (you'll need to resolve all conflicts again). 另外,如果您先前将母版合并到功能分支中,则效果也不佳(您需要再次解决所有冲突)。

What we are describing here will destroy commit history and can go wrong. 我们在这里描述的内容将破坏提交历史,并且可能出错。 For this reason, do the squashing on a separate branch: 因此,请在单独的分支上进行压缩:

git checkout -b squashed_feature

This way, if you screw up, you can go back to your original branch, make another branch for squashing and try again. 这样,如果您搞砸了,则可以返回到原始分支,再创建另一个分支以进行压缩,然后重试。

To squash all commits since you branched away from master, do 要压缩自从master分支以来的所有提交,请执行

git rebase -i master

Note that rebasing to the master does not work if you merged the master into your feature branch while you were working on the new feature. 请注意,如果您在使用新功能时将母版合并到功能分支中,则无法使用母版重新建立基础。 If you did this you will need to find the original branch point and call git rebase with a SHA1 revision. 如果这样做,您将需要找到原始分支点,并使用SHA1修订版调用git rebase。

Your editor will open with a file like 您的编辑器将打开一个类似

pick fda59df commit 1

pick x536897 commit 2

pick c01a668 commit 3

Each line represents a commit (in chronological order, the latest commit will be at the bottom). 每行代表一次提交(按时间顺序,最后一次提交将在底部)。

To transform all these commits into a single one, change the file to this: 要将所有这些提交转换为一个提交,请将文件更改为此:

pick fda59df commit 1

squash x536897 commit 2

squash c01a668 commit 3

This means, you take the first commit, and squash the following onto it. 这意味着,您进行第一次提交,然后压缩下一次提交。 If you remove a line, the corresponding commit is actually really lost. 如果删除一行,则实际上会丢失相应的提交。 Don't bother changing the commit messages because they are ignored. 不要理会更改提交消息,因为它们会被忽略。 After saving the squash settings, your editor will open once more to ask for a commit message for the squashed commit. 保存了壁球设置后,编辑器将再次打开,以请求有关壁球提交的提交消息。

You can now merge your feature as a single commit into the master: 现在,您可以将功能作为一次提交合并到母版中:

git checkout master

git merge squashed_feature

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

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