假设我们在 Git 中有以下情况:
-
创建的存储库:
mkdir GitTest2 cd GitTest2 git init
-
在主节点中进行一些修改并提交:
echo "On Master" > file git commit -a -m "Initial commit"
-
功能1分支主控,完成一些工作:
git branch feature1 git checkout feature1 echo "Feature1" > featureFile git commit -a -m "Commit for feature1"
同时,在 主代码中发现了一个错误,并建立了一个修补程序分支:
git checkout master git branch hotfix1 git checkout hotfix1
该错误在修补程序分支中修复并合并回主节点(可能在拉取请求/代码审查之后(:
echo "Bugfix" > bugfixFile git commit -a -m "Bugfix Commit" git checkout master git merge --no-ff hotfix1
功能1的开发仍在继续:
git checkout feature1
假设我需要功能分支中的修补程序,可能是因为错误也发生在那里。如何在不将提交复制到我的功能分支的情况下实现这一点?
我想防止在我的功能分支上获得两个与功能实现无关的新提交。如果我使用拉取请求,这对我来说似乎尤其重要:所有这些提交也将包含在拉取请求中,并且必须进行审查,尽管这已经完成(因为修补程序已经在主文件中(。
我不能做git merge master --ff-only
:"致命:不可能快进,中止",但我不确定这是否对我有帮助。
主分支合并到功能分支中?容易:
git checkout feature1
git merge master
在这里强制快进合并是没有意义的,因为它无法完成。您已同时提交到功能分支和主分支。现在快进是不可能的。
看看GitFlow。它是可以遵循的 git 分支模型,而您已经在不知不觉中做到了。它也是 Git 的扩展,它为新的工作流步骤添加了一些命令,这些命令会自动执行您原本需要手动执行的操作。
那么,您在工作流程中做了哪些正确的工作?您有两个分支可以使用,您的 feature1 分支基本上是 GitFlow 模型中的"开发"分支。
您从 master 创建了一个修补程序分支,并将其合并回来。现在你被困住了。
GitFlow 模型要求您将修补程序也合并到开发分支,在您的情况下为"feature1"。
所以真正的答案是:
git checkout feature1
git merge --no-ff hotfix1
这会将修补程序内所做的所有更改添加到功能分支,但仅添加这些更改。它们可能会与分支中的其他开发更改冲突,但如果最终将功能分支合并回主分支,它们不会与主分支冲突。
重定基时要非常小心。仅当您所做的更改保留在存储库的本地时,才变基,例如,您没有将任何分支推送到其他存储库。变基是一个很好的工具,您可以在将本地提交推送到世界之前将其排列成有用的顺序,但是之后变基会让像您这样的 git 初学者感到混乱。
你应该能够在 master 上重新定位你的分支:
git checkout feature1
git rebase master
管理出现的所有冲突。当你使用错误修复(已经在master中(提交时,Git会说没有更改,也许它们已经被应用了。然后,您继续变基(同时跳过已在 master 中的提交(
git rebase --skip
如果在功能分支上执行git log
,则会看到错误修复提交仅出现一次,并且出现在主部分中。
更详细的讨论,请查看有关git rebase
(https://git-scm.com/docs/git-rebase( 的 Git 书籍文档,其中涵盖了此确切用例。
编辑其他上下文 ===
===================这个答案是针对@theomega提出的问题,考虑到他的具体情况。请注意此部分:
我想防止我的功能分支上的 [...] 提交与功能实现无关。
将他的私人分支重新建立在主人身上,正是产生这种结果的原因。相比之下,将 master 合并到他的分支中将准确地执行他特别不希望发生的事情:添加一个与他通过分支处理的功能实现无关的提交。
为了解决阅读问题标题的用户,请跳过问题的实际内容和上下文,然后盲目阅读顶部答案,假设它始终适用于他们的(不同(用例,请允许我详细说明:
- 仅
- 重构私有分支(即仅存在于本地存储库中且未与他人共享的分支(。重新定位共享分支会"破坏"其他人可能拥有的副本。
- 如果你想将来自分支(无论是 master 还是另一个分支(的更改集成到一个公共分支中(例如,您已经推送分支以打开拉取请求,但现在与 master 存在冲突,您需要更新您的分支来解决这些冲突(,您需要将它们合并(例如,
git merge master
如@Sven的答案(。 - 如果您愿意,也可以将分支合并到本地私有分支中,但请注意,这将导致分支中出现"外部"提交。
最后,如果您对这个答案不适合您的情况这一事实感到不满意,即使它是针对@theomega的,那么在下面添加评论不会特别有帮助:我不控制选择哪个答案,只有@theomega可以。
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
根据本文,您应该:
-
创建基于新版本的主节点的新分支
git branch -b newmaster
将旧功能分支 合并为新功能分支
git checkout newmaster
解决新功能分支上的冲突
前两个命令可以组合git checkout -b newmaster
。
这样,您的历史记录将保持清晰,因为您不需要反向合并。而且你不需要那么谨慎,因为你不需要做 Git 变基。
我添加了我的答案,类似于其他人,但也许这将是最快的阅读和实现。
注意:在这种情况下不需要变基。
假设我有一个repo1
和两个分支master
和dev-user
。
dev-user
是在某种master
状态下完成的分支。
现在假设dev-user
和master
都前进。
在某些时候,我希望dev-user
获得所有提交master
。
我该怎么做?
我先去我的存储库根文件夹
cd name_of_the_repository
然后
git checkout master
git pull
git checkout dev-user
git pull
git merge master
git push
我希望这对处于相同情况的其他人有所帮助。
Zimi的回答概括地描述了这个过程。以下是具体细节:
-
创建并切换到新分支。确保新分支基于
master
,以便包含最近的修补程序。git checkout master git branch feature1_new git checkout feature1_new # Or, combined into one command: git checkout -b feature1_new master
-
切换到新分支后,合并现有功能分支中的更改。这将添加您的提交,而不会复制修补程序提交。
git merge feature1
-
在新分支上,解决要素与主分支之间的任何冲突。
做!现在使用新分支继续开发您的功能。
下面是一个脚本,可用于将主分支合并到当前分支中。
该脚本执行以下操作:
- 切换到主分支
- 拉取主分支
- 切换回当前分支
- 将主分支合并到当前分支中
将此代码另存为批处理文件 (.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 arg
set repoPath=%1
cd %repoPath%
FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)
echo current branch is %currentBranch%
echo switching to master
git checkout master
echo.
echo pulling origin master
git pull origin master
echo.
echo switching back to %currentBranch%
git checkout %currentBranch%
echo.
echo attemting merge master into %currentBranch%
git merge master
echo.
echo script finished successfully
PAUSE
您也许可以执行"挑选"以将所需的确切提交拉入功能分支。
执行git checkout hotfix1
以转到修补程序 1 分支。然后执行git log
以获取相关提交的 SHA-1 哈希(唯一标识提交的随机字母和数字的大序列(。复制该字符(或前 10 个左右的字符(。
然后,git checkout feature1
返回到功能分支。
然后,git cherry-pick <the SHA-1 hash that you just copied>
这会将该提交(并且仅该提交(拉入您的功能分支。这种变化将在分支中 - 你只是"挑选"它。然后,继续工作,编辑,提交,推送等,尽情享受。
当你最终从一个分支执行另一个合并到你的功能分支时(反之亦然(,Git 会识别出你已经合并到那个特定的提交中,知道它不必再次进行,然后"跳过"它。
补充现有的答案,因为这些命令是反复出现的,我们可以连续执行。鉴于我们在功能分支中:
git checkout master && git pull && git checkout - && git merge -
或者将它们添加到别名中:
alias merge_with_master="git checkout master && git pull && git checkout - && git merge -"
我在功能分支上并进行了重构。我现在想将主更改合并到我的功能分支。我远远落后。注意 我不想将主更改拉到我的本地,因为我的功能分支将模块从一个地方移动到另一个地方。我发现只是在下面表演而不拉动是行不通的。它说"已经是最新的"。
//below does not get the latest from remote master to my local feature branch without git pull
git checkout master
git fetch
git checkout my-feature-branch
git merge master
这在下面有效,注意使用 git 合并 origin/master:
git checkout master
git fetch
git checkout my-feature-branch
git merge origin/master
In Eclipse -
1(结帐主分支
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(将母版合并到要素中
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(现在,您将在功能分支中获得主分支的所有更改。删除冲突(如果有(。
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