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

时间:2011-04-09 00:01:01

标签: git git-branch git-merge branching-and-merging

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

有几位开发人员提交master或创建其他分支,然后合并到master

假设test上的工作需要几天时间,并且您希望通过test内的提交继续更新master

我会git pull origin mastertest

问题1:这是正确的做法吗?其他开发人员可以轻松地处理相同的文件,因为我已经使用了btw。


我对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,希望将时间轴保持为线性尽可能。

14 个答案:

答案 0 :(得分:2688)

我将如何做到这一点

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

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

git总是试图尊重你和其他人的变化,--rebase也是如此。我认为我无法对其进行适当的解释,因此请查看the Git book - Rebasinggit-ready: Intro into rebasing进行一些描述。这是一个非常酷的功能

答案 1 :(得分:335)

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

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

这种方法有两个问题

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

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

  3. 因此,当我们怀疑存在一些冲突时,我们可以进行以下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,例如master branch。

    从不执行操作,如下所示:

    git checkout master
    git rebase -i test
    

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

    的详细信息

    附录:

答案 2 :(得分:85)

rebase或merge不应覆盖任何人的更改(除非您在解决冲突时选择这样做)。

开发过程中的常用方法是

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作为合并的手段是愚蠢的。我也不确定你为什么要把测试推向原点。

答案 3 :(得分:36)

我首先要使待合并的分支尽可能干净。运行测试,确保状态符合您的要求。按git squash清除新提交。

除了KingCrunches answer,我建议使用

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

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

编辑:您可能对

感兴趣

所以在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

答案 4 :(得分:6)

这是我在团队工作中使用的工作流程。场景如您所述。首先,当我完成test工作时,我会与主人一起工作,以便在我test分支工作期间拉入已添加到主人的任何内容。

git pull -r upstream master

这会将更改提取到master,因为您分叉了test分支并应用它们,然后应用您在"之上测试的更改。当前的主人状态。如果其他人对您在测试中编辑的相同文件进行了更改,则此处可能存在冲突。如果有,您将必须手动修复它们并提交。完成后,您可以切换到主分支并合并test而不会出现任何问题。

答案 5 :(得分:4)

旧线程,但是我还没有找到解决方法。这对于使用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 checkout master
git rebase <branch_name>

答案 6 :(得分:3)

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

合并后,如果文件被更改,那么当你合并时,它将通过&#34; Resolve Conflict&#34;

的错误

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

git push origin master

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

答案 7 :(得分:3)

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

因此,我什至不用签出master,就可以:

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

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

答案 8 :(得分:3)

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

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

答案 9 :(得分:2)

我将按照开发和功能分支进行回答,

如果您位于功能分支上,并且需要通过开发进行更新,请使用以下命令:

git checkout develop
git pull
git checkout feature/xyz
git merge develop

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

答案 10 :(得分:1)

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

git checkout master
git pull

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

git rebase master test  

git checkout master
git merge test

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

git push
git checkout test

答案 11 :(得分:1)

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

发件人:https://git-scm.com/docs/merge-strategies

  

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

用法:

In [303]: s[0].__dict__
Out[303]: {'idm': 1.0, 'area': 35.66, 'zz': 2490.8, 'nc': 1.0}

In [304]: s[1].__dict__
Out[304]: {'idm': 2.0, 'area': 65.35, 'zz': 2414.93, 'nc': 1.0}

Git Alias

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

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

现在您可以:

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

答案 12 :(得分:0)

来自GitLab: 只需按照说明进行操作即可:

enter image description here

答案 13 :(得分:0)

仅进行git merge feature-branch时,我总是会遇到合并冲突。这似乎对我有用:

git checkout -b feature-branch

进行大量代码更改...

git merge -s ours master 
git checkout master
git merge feature-branch

git checkout -b feature-branch

进行大量代码更改...

git checkout master
git merge -X theirs feature-branch