Git合并热修复补丁分支到功能分支

假设我们在Git中遇到以下情况:

  1. 创建的存储库:

    mkdir GitTest2cd GitTest2git init
  2. Some modifications in the master take place and get committed:

    echo "On Master" > filegit commit -a -m "Initial commit"
  3. Feature1 branched off master and some work is done:

    git branch feature1git checkout feature1echo "Feature1" > featureFilegit commit -a -m "Commit for feature1"
  4. Meanwhile, a bug is discovered in the master-code and a hotfix-branch is established:

    git checkout mastergit branch hotfix1git checkout hotfix1
  5. The bug is fixed in the hotfix branch and merged back into the master (perhaps after a pull request/code review):

    echo "Bugfix" > bugfixFilegit commit -a -m "Bugfix Commit"git checkout mastergit merge --no-ff hotfix1
  6. Development on feature1 continues:

    git checkout feature1

Say I need the hotfix in my feature branch, maybe because the bug also occurs there. How can I achieve this without duplicating the commits into my feature branch?

I want to prevent to get two new commits on my feature branch which have no relation to the feature implementation. This especially seems important for me if I use pull requests: All these commits will also be included in the pull request and have to be reviewed although this has already been done (as the hotfix is already in the master).

I can not do a git merge master --ff-only: "fatal: Not possible to fast-forward, aborting.", but I am not sure if this helped me.

1880924 次浏览

您应该能够将分支重新基于master:

git checkout feature1git rebase master

管理所有出现的冲突。当你使用错误修复(已经在master中)提交时,Git会说没有任何更改,也许它们已经应用了。然后,你继续rebase(同时跳过已经在master中的提交)

git rebase --skip

如果您在功能分支上执行git log,您将看到错误修复提交仅出现一次,并且在主部分中。

有关更详细的讨论,请查看git rebasehttps://git-scm.com/docs/git-rebase)上的Git书留档,其中涵盖了这个确切的用例。

================编辑额外的上下文====================

这个答案是专门针对@theomega提出的问题提供的,考虑到他的特殊情况。

我想防止[…]在我的功能分支上提交与功能实现无关的内容。

将他的私有分支重新基于master正是会产生这种结果的。相比之下,将master合并到他的分支中恰恰会做他特别不想发生所做的事情:添加一个与他正在通过他的分支进行的功能实现无关的提交。

为了解决阅读问题标题的用户,跳过问题的实际内容和上下文,然后只盲目地阅读顶部的答案假设它总是适用于他们的(不同的)用例,请允许我详细说明:

  • 仅重设私有分支(即只存在于本地存储库中且未与他人共享的分支)。重设共享分支会“破坏”其他人可能拥有的副本。
  • 如果您想将分支(无论是master还是其他分支)的更改集成到公共分支中(例如,您已经推送分支以打开拉取请求,但现在与master发生冲突,您需要更新您的分支以解决这些冲突),您需要将它们合并(例如,在@Sven的回答中使用git merge master)。
  • 如果您喜欢,您还可以将分支合并到本地私有分支中,但请注意,这将导致分支中的“外部”提交。

最后,如果你不满意这个答案不适合你的情况,即使它是@theomega,在下面添加评论不会特别有帮助:我不控制选择哪个答案,只有@theomega可以。

我们如何将主分支合并到功能分支中?简单:

git checkout feature1git merge master

在这里强制快进合并是没有意义的,因为它无法完成。您同时提交了功能分支和主分支。快进现在是不可能的。

看看GitFlow。它是一个可以遵循的git分支模型,你已经不知不觉地做到了。它也是Git的扩展,它为新的工作流步骤添加了一些命令,这些步骤可以自动完成你需要手动完成的事情。

那么你在工作流中做对了什么?你有两个分支可以使用,你的功能1分支基本上是GitFlow模型中的“开发”分支。

您从master创建了一个热修复补丁分支并将其合并回来。现在您被卡住了。

GitFlow模型要求您将热修复补丁也合并到开发分支,在您的情况下是“功能1”。

所以真正的答案应该是:

git checkout feature1git merge --no-ff hotfix1

这会将热修复补丁中的所有更改添加到功能分支,但只有这些更改。它们可能会与分支中的其他开发更改冲突,但如果您最终将功能分支合并回master,它们不会与master分支冲突。

rebase时要非常小心。只有在你所做的更改保持在本地存储库的情况下才会rebase,例如你没有将任何分支推送到其他存储库。rebase是一个很好的工具,可以让你在将本地提交推送到世界之前将其排列成有用的顺序,但是事后rebase会把像你这样的git初学者的事情搞砸。

你可以做一个“樱桃选择”来拉取你需要的确切提交到你的功能分支。

执行git checkout hotfix1以获取hotFix1分支。然后执行git log以获取有关提交的SHA-1哈希(随机字母和数字的大序列,唯一标识提交)。复制它(或前10个左右字符)。

然后,git checkout feature1返回到您的功能分支。

然后,git cherry-pick <the SHA-1 hash that you just copied>

这将把该提交和只有该提交拉到您的功能分支中。该更改将在分支中-您只需“挑选”它。然后,恢复工作、编辑、提交、推送等。

当您最终从一个分支执行另一个合并到您的功能分支时(反之亦然),Git将识别出您已经合并到该特定提交中,知道它不必再次进行合并,只需“跳过”它。

基于这篇文章,您应该:

  • 创建基于新版本master的新分支

    git branch -b newmaster

  • 将您的旧功能分支合并到新分支中

    git checkout newmaster

  • 解决新功能分支冲突

前两个命令可以组合为git checkout -b newmaster

通过这种方式,您的历史记录保持清晰,因为您不需要返回合并。而且您不需要如此谨慎,因为您不需要进行Git rebase。

齐米的回答大致描述了这个过程。具体如下:

  1. 创建并切换到一个新分支。确保新分支基于master,因此它将包括最近的修补程序。

    git checkout mastergit branch feature1_newgit checkout feature1_new
    # Or, combined into one command:git checkout -b feature1_new master
  2. After switching to the new branch, merge the changes from your existing feature branch. This will add your commits without duplicating the hotfix commits.

    git merge feature1
  3. On the new branch, resolve any conflicts between your feature and the master branch.

Done! Now use the new branch to continue to develop your feature.

这是一个脚本,您可以使用它将主分支合并到当前分支中。

该脚本执行以下操作:

  • 切换到主分支
  • 拉出主分支
  • 切换回当前分支
  • 将主分支合并到当前分支

将此代码另存为批处理文件(. bat)并将脚本放在存储库的任何位置。然后单击它以运行它,您就设置好了。

:: This batch file pulls current master and merges into current branch
@echo off
:: Option to use the batch file outside the repo and pass the repo path as an argset repoPath=%1cd %repoPath%
FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)
echo current branch is %currentBranch%echo switching to mastergit checkout masterecho.echo pulling origin mastergit pull origin masterecho.echo switching back to %currentBranch%git checkout %currentBranch%echo.echo attemting merge master into %currentBranch%git merge masterecho.echo script finished successfullyPAUSE

git merge

您可以按照以下步骤

1.合并origin/master分支到feature分支

# step1: change branch to master, and pull to update all commits$ git checkout master$ git pull
# step2: change branch to target, and pull to update commits$ git checkout feature$ git pull
# step3: merge master to feature(⚠️ current is feature branch)$ git merge master

2.合并feature分支到origin/master分支

origin/master是远程主分支,而master是本地主分支

$ git checkout master$ git pull origin/master
$ git merge feature$ git push origin/master

我在功能分支上并进行了重构。我想现在将主更改合并到我的功能分支。我远远落后了。注意我不想将主更改拉取到我的本地因为我的功能分支有模块从一个地方移动到另一个地方。我发现只是在下面执行而没有拉是行不通的。它说“已更新”。

 //below does not get the latest from remote master to my local feature branch without git pullgit checkout mastergit fetchgit checkout my-feature-branchgit merge master

这下面的作品,注意使用git合并起源/主:

 git checkout mastergit fetchgit checkout my-feature-branchgit merge origin/master

我补充我的答案,类似于其他人,但也许这将是最快的阅读和实施。

注意:在这种情况下不需要Rebase。

假设我有一个repo1和两个分支masterdev-user

dev-user是在master的某个状态下完成的分支。

现在假设dev-usermaster都前进。

在某些时候,我希望dev-user获得master中的所有提交。

我该怎么做?

我首先进入我的存储库根文件夹

cd name_of_the_repository

然后

git checkout mastergit pullgit checkout dev-usergit pullgit merge mastergit push

我希望这对处于同样情况的其他人有所帮助。

In Eclipse -

1)Checkout master分支

Git Repositories ->Click on your repository -> click on Local ->double click master branch->Click on yes for check out

2)拉主分支

Right click on project ->click on Team -> Click on Pull

3)检查您的功能分支(遵循1点中提到的相同步骤)

4)将master合并到功能中

Git Repositories ->Click on your repository -> click on Local ->Right Click on your selected feature branch ->Click on merge ->Click on Local ->Click on Master ->Click on Merge.

5)现在您将在功能分支中获得Master分支的所有更改。删除冲突(如果有)。

For conflict if any exists ,follow this -Changes mentioned as Head(<<<<<< HEAD) is your change, Changes mentioned in branch(>>>>>>> branch) is other person change, you can update file accordingly.

注意-您需要为冲突文件添加索引

6)提交并推送您在功能分支中的更改。

Right click on project ->click on Team -> Click on commit -> Commit and Push.

Git Repositories ->Click on your repository -> click on Local ->Right Click on your selected feature branch ->Click on Push Branch ->Preview ->Push

补充现有的答案,因为这些命令是循环的,我们可以连续执行。给定我们在特征分支中:

git checkout master && git pull && git checkout - && git merge -

或者将它们添加到别名中:

alias merge_with_master="git checkout master && git pull && git checkout - && git merge -"