我和Git已经合作了一年了,今天在合并分支机构时偶然发现了令人困惑的事情。这是我本地的.config文件部分:
[branch "develop"]
remote = origin
merge = refs/heads/develop
[branch "Feature/Sprint4.4/mybranch"]
remote = origin
merge = refs/heads/Feature/Sprint4.4/mybranch
现在我在当地分支mybranch。我按顺序执行了以下命令。
1) git pull
--> 2d6cf1e..655001e develop -> origin/develop
--> already up-to-date
2) git merge origin develop
--> already up-to-date
3) git merge origin/develop
--> merge made by recursive strategy...
....(all the changes were indicated)
7 files changed, 202 insertions(+), 181 deletions(-)
我的问题是上面的命令(2)和(3)之间的确切区别是什么以及输出改变的原因?
我知道我可以通过Git文档和其他书籍,但寻找答案更简单的语言。
答案 0 :(得分:1)
您在mybranch
1) git pull // This will pull changes from origin and write them into your my branch.(It will fetch for your develop branch)
--> 2d6cf1e..655001e develop -> origin/develop
--> already up-to-date
2) git merge origin develop // This will take almost no effect as you already pulled as it shows develop -> origin/develop
// This is same as git merge origin/develop develop
--> already up-to-date
3) git merge origin/develop // This will merge changes from origin/develop to mybranch
// This is same as git merge origin/develop mybranch
--> merge made by recursive strategy...
....(all the changes were indicated)
7 files changed, 202 insertions(+), 181 deletions(-)
答案 1 :(得分:1)
我知道这已经得到了回答和接受,但我认为接受的答案中缺少一点关键。
git merge
。换句话说,git merge origin develop
很少是一个好主意;不要这样做。要了解原因,请继续阅读。
git pull
和git merge
采用不同的参数 git pull
仅运行git fetch
后跟git merge
(或者,如果您指示git pull
,那么这是正确的(即,它是正确的){{1}然后是git rebase
)。棘手的部分是如何运行它们,pull
命令通常需要两个参数:
$ git pull remote refspec
但merge
命令通常需要一个:
$ git merge commit
请注意此处的名称( remote
, refspec
和 commit
)都不同:这是理解命令的关键之一。另外,请注意"一般"在谈论所使用的参数数量时:有时可能会省略某些参数,或者使用更多的参数。
在最简单的形式中,远程只是一个名为origin
的名称,它引用git配置文件(.git/config
)中的条目。 pull
脚本有很长的使用它的替代方法的历史,所以你可以把其他的东西放在这里,但只要你只使用这些名字,事情就会很好用而且不那么令人困惑,所以让我们来看看。把它留在那。
完整的refspec最多有三个部分。这三个问题对git push
很重要,但git fetch
更不重要,而且git pull
运行git fetch
,我们可以使用最简单的版本,它只是一个分支或标记名称。使用git fetch
(以及git pull
)时,您提供的分支名称是远程上的分支的名称。因此:
git pull origin branch
让你的git联系远程origin
并询问它名为 branch
的分支。
假设分支机构名称存在于遥控器上,你的git将获得该分支的最新版本(通常也会更新refs/remotes/origin/branch
,至少如果你有git版本1.8.4或更新版本是的,对于更新版本的git,您的"远程跟踪分支"总是得到更新。)
作为git pull
依赖的副作用,git fetch
还将所有更新的分支信息 1 写入名为{{1的文件在git的私有(FETCH_HEAD
)目录中。您真正需要知道的唯一事情是.git
脚本使用它(但如果您愿意,可以阅读文件的内容)。
摘要:pull
运行git pull
并将更新存储在git fetch
中,有时也存储在您的远程跟踪分支中#34} ;例如FETCH_HEAD
和origin/master
等等。
origin/develop
现在让我们转到git merge
。
我上面说过它"一般"有三个参数,git merge
。
git merge commit
命令始终给出pull
三个参数(以及许多标志,包括一些用于提供合并提交消息的标志)。 merge
脚本获取 commit 参数 - 就此而言,pull
文件的合并提交消息 - 2
如果你想手动执行此操作,可以像FETCH_HEAD
脚本那样执行此操作,但提取和输入长SHA-1 ID非常痛苦。而且,在任何情况下,您要做的是合并一个不同的本地分支,而不是pull
步骤带来的提交的原始SHA-1。
您输入命令时最初出错的地方:
fetch
这会将两个参数传递给git merge origin develop
。它们都被视为提交ID,这告诉merge
执行一个名为" octopus merge"的事情。除非你是一名高级的git master,否则你可能不想这样做。 (幸运的是,在你的情况下,考虑到你给git的多个提交ID,无论如何都无事可做。)
我会在此注意git merge
不看起来像是提交ID,origin
也不像SHA-1。但事实上,这两个名称做都指定了特定的提交 - 如果他们没有,你会从develop
命令得到一条错误消息。要查找哪些提交,您可以使用命令git merge
:
git rev-parse
(你的胜利与这个SHA-1不相符,但这个想法应该足够明确了)。分支名称也解析为原始SHA-1 - 我没有$ git rev-parse origin
a17c56c056d5fea0843b429132904c429a900229
但我确实有develop
和master
所以我会在这里使用这些:
origin/master
(在这种情况下,两者与我的$ git rev-parse master
a17c56c056d5fea0843b429132904c429a900229
$ git rev-parse origin/master
a17c56c056d5fea0843b429132904c429a900229
相同,现在与master
最新。)
通常,分支名称解析为分支顶端的提交。
我会重复这一点,因为它是理解git的另一个关键。 分支名称解析为分支顶端的提交,其中包含一个非常重要且非常重要的异常,即执行origin/master
时。由于git checkout
是人们使用git做的第一件事之一,他们知道分支名称是特殊的 - 这对于git checkout
是正确的,但对于大多数其他git命令则不然。大多数命令只是将名称转换为原始SHA-1,当它们执行时,它们会获得分支的提示。
git checkout
使用符号名称git merge origin/develop
运行git merge
非常合理:git会为您查找原始提交ID,并设置默认合并消息以使用符号名称,这对于人类稍后阅读日志意味着更多。如果您使用原始提交ID,那么您将在日志中获得该ID。
合并摘要: origin/develop
是合理的做法。这意味着"找到git merge origin/develop
的提示提交并将其合并为常规合并。"但是,origin/develop
不是一个好主意,因为它意味着"找到git merge origin develop
和origin
的提示提交并执行这两个章节的合并提交"
1 当您使用四参数表单develop
时,git fetch remote refspec
步骤只会 您要求的一个分支。有三个参数,即fetch
,git fetch remote
步骤通常会带来所有分支。只有两个参数,fetch
通常会根据需要自动从git fetch
获取,并再次带来所有分支。因此,您通常只需运行origin
。
2 如果您检查文件,您会看到以下内容:
git fetch
您可能还会看到更多行,例如:
a17c56c056d5fea0843b429132904c429a900229 branch 'master' of [url]
(或者你可能没有) - 这是ca00f80b58d679e59fc271650f68cd25cdb72b09 not-for-merge branch 'maint' of [url]
带来的所有东西。在这种特殊情况下,我运行了git fetch
而没有任何参数,它带来了git pull
和master
(以及更多项目)。所有提交ID都会在maint
中结束,然后FETCH_HEAD
脚本会提取 "用于合并"通过排除标记为" not-for-merge"。