将Git分支合并到master中的最佳(最安全)方法是什么?


2101

master创建了一个新分支,我们称之为test

有几个开发人员致力于master或创建其他分支,然后合并到中master

假设工作test需要几天的时间,而您想不断test更新内部的提交master

我会git pull origin mastertest

问题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以期使时间表尽可能地线性。


18
不..改基永远不会覆盖,它只是试图获得更清晰的历史记录。通过将历史附加到(或伪造)大师的后期
Junjun Liu

7
rebase不会覆盖您的提交。它撤消您的提交,将master分支中的提交应用于您的测试分支,然后将您的提交应用于测试。
zundi

Answers:


2991

我将如何做

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

如果我有一个来自远程分支机构的本地分支机构,那么除了将这个分支机构与远程分支机构合并之外,我不满意。同样,我不会推送更改,直到对要推送的内容感到满意并且也不会推送所有仅适用于我和我的本地存储库的东西。在您的描述中,似乎test只适合您?因此,没有理由发布它。

git始终尝试尊重您和他人的更改,因此也会如此--rebase。我认为我无法适当地解释它,因此请看一下Git书-Rebasinggit-ready:介绍rebasing 作一些说明。这是一个很酷的功能


2
git merge test给我fatal: 'test' does not point to a commit。我必须git log在test分支上查找提交点,然后切换回master分支,然后执行git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234
Duncanmoo 2014年

17
@Duncanmoo好吧,当然分支test必须存在。当然,您可以改用commit hash,但是使用分支名称通常更容易。在内部,它只是检索HEAD分支的哈希值。
KingCrunch 2014年

44
@shanyangqu从远程获取最新更改。如果您独自工作并且仅使用一个系统,就不会有问题。但是,如果有来自不同系统(可能是来自不同开发人员)的更改,则当您尝试将合并推回时(第4步),您将看到冲突。现在唯一的解决方案是将您的本地主服务器合并到远程主服务器,最终导致一个非常难看的“将主服务器合并到源/主服务器”合并提交。因此,在合并之前
采取先机

7
“在您的描述中,看来该测试仅适合您?因此没有理由发布它。” 例如,如果该服务器为本地驱动器故障提供备份,或者您没有其他方法进行备份,则可能需要将本地分支推送到服务器。
艾瑞克(Eric)

5
“ ...而且我对要推送的内容感到满意之前,我不会推送更改...”为什么不备份以备份您的代码,以防您的本地计算机死掉并花了几天的精力消失了?
Rich Stone

399

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

喜欢

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

这种方法有两个问题

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

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

因此,当我们怀疑会有一些冲突时,我们可以执行以下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

一旦我们解决了冲突,或者如果没有冲突,我们commitpush他们

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的详细信息

附录:


4
我同意重新部署测试分支,以便以后合并到master中是必经之路。甚至其他答案都是正确的,因为作者提到“您将获得一个更清晰的项目,这是版本控制系统的目的”,所以这将使分支机构的更改历史记录保持在主管的头上。
le0diaz's

15
陈述“这不是一种安全方式,因为我们不知道测试分支和主分支之间是否存在任何冲突”是不正确的:人们总是可以中止合并。即使没有冲突,只要不推送最后一个本地提交,您也可以随时撤消它。如果没有正确地理解git,有些事情可能看起来有些令人恐惧或不清楚,但是“不安全”无论如何都是不正确的。请注意不要将其他人与错误信息混淆。
Paul van Leeuwen

4
同意@PaulvanLeeuwen的观点,当您测试分支git合并到master时,将会收到有关冲突的通知,那就是您将介入并合并更改的地方。完成后,将提交合并并向后推。如果您后悔或无法正确地合并它,则可以随时放弃您的工作并再次从大师那里拉来。因此,它绝对不是不安全
胡安

3
为什么要重新设置-i?
MushyPeas

8
从本质上讲,重新合并比合并更不安全。提议将基础调整作为更安全的合并选项是错误的。变基是一种有效的策略,但它带有更多用户应注意的警告。
Ikke '18

90

重新设置基础或合并都不应覆盖任何人的更改(除非您选择解决冲突时选择这样做)。

开发时通常的方法是

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可以使用。

使用推后拉作为合并的方法很愚蠢。我也不确定您为什么要把测试推向原点。


1
此过程将增加提交次数,每次在分支之间切换时,都必须提交分支。
iBug 2014年

2
什么?您是说每次切换分支都会增加提交次数吗?还是说每次切换分支机构都必须“提交分支机构”?第一个是不正确的,我不确定第二个是什么意思。
raylu 2014年

在结帐之前,您必须提交分支。我就是这么说的
iBug 2014年

11
您不需要:那是(其中之一)git stash
msanford 2014年

1
或者,您可以修改最后一次提交(在本地分支中),并在推送之前使其完美。
whihathac '16

42

我首先要使要合并的分支尽可能干净。运行测试,确保状态为所需状态。通过git squash清理新提交。

除了KingCrunches答案,我建议使用

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

您可能在另一个分支中进行了多次提交,而这些提交仅应在master分支中进行了一次提交。为了使提交历史记录尽可能整洁,您可能需要将所有来自test分支的提交压缩为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

这仅应是master分支中的一个提交 ”,不一定是这样;你可能wekk要保留历史
Cocowalla

当然。但后来干脆不壁球提交
马丁托马

我认为-第一父母似乎是最好的解决方案。davidchudzicki.com/posts/first-parent
bkribbs 18/09/20

7

旧线程,但是我还没有找到解决方法。对于使用rebase并想将master分支(功能)中的所有提交合并的人来说,这可能是有价值的。如果途中有冲突,则可以为每次提交解决它们。在此过程中,您可以完全控制,并且可以随时中止。

获取最新的Master和Branch:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

合并分支到主节点上:

git checkout <branch_name>
git rebase master

可选:如果在重新设置基准期间遇到冲突:

首先,解决文件冲突。然后:

git add .
git rebase --continue

推送您的基础分支:

git push origin <branch_name>

现在,您有两个选择:

  • A)创建一个PR(例如在GitHub上)并通过UI将其合并
  • B)返回命令行并将分支合并到master
git checkout master
git merge --no-ff <branch_name>
git push origin master

做完了


6

这是我在团队中使用的工作流程。情况如您所描述。首先,当我完成工作后,test我会与master一起进行基础工作,以提取在test分支机构工作期间添加到master中的所有内容。

git pull -r upstream master

自从分支test分支以来,这会将更改拉到master上并应用它们,然后应用所做的更改以“在” master的当前状态之上测试。如果其他人对您在测试中编辑的相同文件进行了更改,则此处可能存在冲突。如果有,则必须手动修复它们并提交。完成此操作后,最好切换到master分支并毫无问题地合并test


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

合并后,如果文件被更改,则当您合并文件时,将出现“解决冲突”错误

因此,您首先需要解决所有冲突,然后再次提交所有更改,然后再按

git push origin master

谁在测试分支中做过更改,这样做会更好,因为他知道自己做了什么更改。


3

我会使用rebase方法。主要是因为它在语义上完美地反映了您的情况,即。您想要做的是刷新当前分支的状态,并“假装”好像它是基于最新分支的。

因此,即使没有退房master,我也会:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

当然,仅从原点获取不会刷新您的本地状态master(因为它不执行合并),但这完全可以满足我们的目的-为了节省时间,我们希望避免切换。


2

@KingCrunch的答案在许多情况下都可以使用。可能出现的一个问题是您可能在另一台计算机上,需要从测试中获取最新信息。因此,我建议先进行测试。修订如下:

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

0

您必须将分支签出才能拉出,因为拉动意味着要合并到master中,并且您需要合并一个工作树。

git checkout master
git pull

无需先结帐;rebase用两个参数做正确的事

git rebase master test  

git checkout master
git merge test

git push默认情况下会推送此处和远程存在的所有分支

git push
git checkout test

0

正如标题中所说的“最佳方式”一样,我认为考虑耐心合并策略是个好主意 。

来自:https : //git-scm.com/docs/merge-strategies

使用此选项,“合并递归”花费一些额外的时间来避免有时由于不重要的匹配行(例如,来自不同功能的花括号)而导致的合并错误。当要合并的分支发散很大时,请使用此选项。另请参见git-diff [1] --patience。

用法:

git fetch
git merge -s recursive -X patience origin/master

Git Alias

我总是为此使用别名,例如运行一次:

 git config --global alias.pmerge 'merge -s recursive -X patience'

现在您可以执行以下操作:

git fetch
git pmerge origin/master

0

这是来自GitLab:只需按照说明进行操作:

在此处输入图片说明


0

我会按照开发和功能分支回答,

如果您位于功能分支上,并且需要使用以下命令进行开发,请使用以下命令进行更新:git checkout开发git pull git checkout功能/ xyz git merge开发

现在,您的功能已通过开发进行了更新,您可以推送更改。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.