题 将git分支合并为master的最佳(也是最安全)方法


一个新的分支来自 master 创建,我们称之为 test

有几个开发人员要么承诺 master 或创建其他分支,然后合并到 master

让我们说工作吧 test 需要几天,你想继续保持 test 更新内部提交 master

我会做 git pull origin master 从 test

问题1: 这是正确的方法吗?其他开发人员可以轻松地处理相同的文件,就像我工作顺便说一句。


我的工作 test 已完成,我准备将其合并回去 master。以下是我能想到的两种方式:

A: 

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B: 

git checkout test
git pull origin master
git checkout master
git merge test

我没用 --rebase 因为从我的理解,rebase将得到改变 master 并将其叠加在其上,因此它可以覆盖其他人所做的更改。

问题2: 这两种方法中哪一种是对的?那有什么区别?

所有这一切的目标是保持我的 test 分支更新了发生的事情 master 后来我可以将它们合并回来 master 希望尽可能保持时间线的线性。


1467
2018-04-09 00:01


起源


不..改变从不覆盖,它只是试图实现更清洁的历史。通过重新附加(或假冒)历史到主人的后期点 - Junchen Liu
rebase不会覆盖你的提交。它撤消您的提交,将主分支中的提交应用于您的测试分支,然后将您的提交应用于测试。 - zundi
如果在做git pull origin master时你得到“拒绝合并不相关的历史记录”...但是你真的需要将master中的任何东西合并到你的测试分支中(这可能/实用吗?) - iloveretards


答案:


我该怎么做

git checkout master
git pull origin master
git merge test
git push origin master

如果我有一个远程本地分支,我觉得将其他分支与远程分支合并后感觉不舒服。此外,我不会推动我的更改,直到我对我想要推送的内容感到满意,而且我根本不会推送任何东西,这些内容仅适用于我和我的本地存储库。在你的描述中似乎是这样的 test 只适合你吗?所以没有理由发表它。

git总是试图尊重你和其他人的变化,所以也会如此 --rebase。我认为我不能恰当地解释它,所以看一看 Git书 - 重新定位 要么 git-ready:介绍变基 有一点描述。这是一个非常酷的功能


2170
2018-04-09 00:45



@Duncanmoo嗯,当然是分支机构 test 必须存在。当然,您可以使用提交哈希,但通常更容易使用分支名称。在内部它只是检索哈希 HEAD 的分支。 - KingCrunch
什么是结账后拉主人的点? - Junchen Liu
@shanyangqu从遥控器获取最新的更改。如果您单独工作并且只使用一个系统,则没有问题。但是当从不同的系统(可能来自不同的开发人员)推送更改时,只要您尝试推送合并(第4步),就会发现冲突。现在唯一的解决方案是将您的本地主服务器合并到远程主服务器中,这最终会形成一个非常难看的“合并主服务器到源/主服务器”合并提交。因此,在合并之前进行拉动总是一个好主意 - KingCrunch
@KingCrunch 5年后仍然是SO上最有用的答案 - sterling archer
“在您的描述中似乎,该测试仅适用于您?因此没有理由发布它。”例如,如果该服务器提供针对本地驱动器的备份失败,或者您没有其他方法进行备份,则可能需要将本地分支推送到服务器。 - Eric


这是一个非常实际的问题,但上述所有答案都不切实际。

喜欢

git checkout master
git pull origin master
git merge test
git push origin master

这种方法有 两个问题

  1. 这是不安全的,因为我们不知道测试分支和主分支之间是否存在任何冲突。

  2. 它会将所有测试提交“挤压”到master上的一个合并提交中;也就是说在master分支上,我们看不到测试分支的所有更改日志。

所以,当我们怀疑会有一些冲突时,我们可以进行以下git操作:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

测试 merge 之前 commit,避免快速提交 --no-ff

如果遇到冲突,我们可以运行 git status 查看有关冲突的详细信息并尝试解决

git status

一旦我们解决了冲突,或者没有冲突,我们就会 commit 和 push 他们

git commit -m 'merge test branch'
git push

但是这种方式将丢失测试分支中记录的更改历史记录,并且它会使主分支很难让其他开发人员了解项目的历史记录。

所以我们必须使用最好的方法 rebase 代替 merge (假设,在这个时候,我们已经解决了分支冲突)。

以下是一个简单的示例,对于高级操作,请参阅 http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

是的,当你完成鞋面时,所有Test分支的提交都将转移到Master分支的头部。变基的主要好处是可以获得线性且更清晰的项目历史记录。

你唯一需要避免的是:永远不要使用 rebase 在公共分支上,像主分支。

喜欢以下操作:

git checkout master
git rebase -i test

永远不要做这些操作。

细节 https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

附录:


260
2018-03-14 12:13



我同意重新定位测试分支,以便以后合并到master中是可行的方法。即使其他答案都是正确的,这将保留分支机构测试的变化历史,作为版本控制系统的目的,提到“你得到一个班轮和更清洁的项目”。 - le0diaz
声明“它不是一种安全方式,因为我们不知道测试分支和主分支之间是否存在任何冲突”并非如此:总是可以中止合并。即使没有冲突,只要没有推送,你总是可以撤消上一次本地提交。如果没有正确理解git,有些事情可能看起来有些可怕或不清楚,但“不安全”在任何方面都是错误的。请注意不要将其他人的信息混淆。 - Paul van Leeuwen
同意@PaulvanLeeuwen,当你 git merge 将测试分支转换为主服务器,您将收到有关冲突的通知,以及您将介入并合并更改的地方。一旦完成,您将提交合并并推回。如果您后悔或似乎无法正确合并,您可以随时丢弃您的工作并再次从主人那里取出。所以它绝对不是不安全的.. - Juan
为什么rebase -i? - MushyPeas
重新定位本质上比合并更不安全。提议将变基作为一种更安全的合并选择是错误的。重新定位是一种有效的策略,但需要注意用户应注意的更多警告。 - Ikke


无论是rebase还是合并都不应该覆盖任何人的更改(除非您在解决冲突时选择这样做)。

开发过程中的常用方法是

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

当你准备合并回主人,

git checkout master
git log ..test # if you're curious
git merge test
git push

如果你担心在合并上破坏某些东西, git merge --abort 是给你的

使用push然后pull作为合并的手段是愚蠢的。我也不确定你为什么要把测试推向原点。


73
2018-04-10 00:17



此过程将增加提交次数,每次在分支之间切换时,都必须提交分支。 - iBug
什么?你是说它每次切换分支时都会增加提交次数?或者你是说每次切换分支时,都必须“提交你的分支”?第一个是不真实的,我不确定第二个意味着什么。 - raylu
在结账之前,你必须提交分支。这就是我说的 - iBug
你没有:那是(其中一件事) git stash 是为了。 - msanford
我推荐 git checkout test; git pull 代替 git merge origin/test。更好的是 git pull --rebase。无论如何,你忘了拉变化,所以之前 git merge origin/test 你应该 git fetch origin test (git fetch .. && git merge .. 什么是 git pull .. :) :)) - KingCrunch


除了 KingCrunches回答,我建议使用

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

您可能在另一个分支中进行了许多提交,这应该只是主分支中的一个提交。要使提交历史记录尽可能干净,您可能希望将所有提交从测试分支压缩到主分支中的一个提交中(另请参见: Git:要挤压还是不挤压?)。然后,您还可以将提交消息重写为非常富有表现力的内容。一些易于阅读和理解的东西,无需深入研究代码。

编辑:你可能会感兴趣

所以在GitHub上,我最终为功能分支做了以下事情 mybranch

从原点获取最新信息

$ git checkout master
$ git pull origin master

找到合并基础哈希:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

现在确保只有第一个 pick,其余的是 s

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

接下来选择一个非常好的提交消息并推送到GitHub。然后发出拉取请求。

合并拉取请求后,您可以在本地删除它:

$ git branch -d mybranch

并在GitHub上

$ git push origin :mybranch

20
2018-04-21 08:18



“它应该只是master分支中的一个提交“,不一定;你可能希望保留历史 - Cocowalla
当然。但那就是不要压缩提交 - Martin Thoma


这是我在团队工作中使用的工作流程。场景如您所述。首先,当我完成工作时 test 在我工作的那段时间里,我和主人一起决定把所有添加到主人的东西拉进来 test 科。

git pull -r upstream master

这将把你的变化拉到掌握,因为你分叉了 test 分支并应用它们,然后应用您所做的更改来“测试”当前主服务器状态。如果其他人对您在测试中编辑的相同文件进行了更改,则此处可能存在冲突。如果有,您将必须手动修复它们并提交。一旦你完成了,你就可以切换到主分支并合并 test在没有问题。


3
2018-03-16 22:27





git checkout master
git pull origin master
# Merge branch test into master
git merge test

合并后,如果文件被更改,那么当你合并它将通过“Resolve Conflict”错误

那么你需要首先解决所有的冲突然后,你必须再次提交所有的更改然后推送

git push origin master

在测试分支中做了更改的人更好,因为他知道他做了什么改变。


1
2018-04-07 08:55