GIT如何将master合并到使用-single-branch克隆的分支中

时间:2017-11-07 08:49:11

标签: git merge version-control

我有一个git存储库,其中master是应用程序的当前版本,每个客户都有自己的自定义分支。

我已使用--single-branch

将每个客户分支分别克隆到一个目录中

我的目标是将master合并到我的分支中。我使用以下命令克隆了repo:

git clone {{REPO_URL}} --single-branch my-branch --branch my-branch

然后我尝试了:

git fetch origin -- master

git merge master

然后我得到了这个

  

merge:master - 不是我们可以合并的东西

我知道我可以通过克隆整个存储库来解决这个问题,但无论如何都可以解决这个问题吗?

3 个答案:

答案 0 :(得分:5)

您只需将网址添加为本地仓库中的另一个遥控器即可。

详细命令如下:

# In local my-branch
git remote add upstream <repo URL> -f
git merge upstream/master

现在,您的本地my-branch包含master分支的更改。

更新:要仅为master分支添加远程,您可以使用以下命令:

git remote add upstream <repo URL> -t master -f

如果您已将远程upstream添加到所有分支,则可以通过以下方式进行更改:

git remote rm upstream
git remote add upstream <repo URL> -t master -f

答案 1 :(得分:0)

TL; DR

你必须:

  • FETCH_HEAD
  • 合并
  • git fetch refspec或
  • 中指定目标参考名称
  • 调整remote.origin.fetch设置

或这些项目的某些组合。例如,根据使用的组合,您可能需要提取refs/remotes/origin/master并运行git merge origin/master

解释

关键在于 refspecs 。 refspec是第二种最简单的形式,是一对由冒号分隔的引用,例如refs/heads/master:refs/heads/master。在某些情况下,引用可以缩写,例如master:master。左侧的名称是,右侧的名称是目的地(Git文档缩写为&lt; src&gt;和&lt; dst&gt;)。

然后考虑你的命令:

git fetch origin -- master

(此处--毫无意义。)git fetch命令会将origin视为存储库的名称(因此它会查找与origin关联的网址,并且与fetch =关联的origin refspec,然后将master视为refspec,与之前定义的任何fetch refspec合并并部分覆盖。

制作--single-branch克隆时:

git clone {{REPO_URL}} --single-branch --branch my-branch

这会更改与新克隆关联的fetch refspec。 (注意:附加的my-branch参数最终被视为目录名。)运行:

git config --list --local

将向您展示以下项目:

remote.origin.url=... whatever the URL expanded to...
remote.origin.fetch=+refs/heads/my-branch:refs/remotes/origin/my-branch

这告诉您的Git,当它在origin与其他Git联系时,默认操作是仅提取 其分支my-branch,将结果复制到远程跟踪名称origin/my-branch

当您运行git fetch origin而没有其他参数时,您的Git会执行此默认操作。

如果没有--single-branch,Git会使用默认的refspec fetch=+refs/heads/*:refs/remotes/origin/*。这将指示Git获取所有分支(所有refs/heads/名称),并将它们复制到您自己的存储库中的远程跟踪名称。

当您提供git fetch origin个其他参数时,它们是 refspecs ,就像这个fetch设置一样。例如,你可以写:

git fetch origin +refs/heads/normalbranch:refs/strangeref

会指示您的Git将其(本地的,非常正常的)分支normalbranch复制到您自己的名为refs/strangeref的存储库中的本地引用。

现在,我在上面说过,一对名称是第二种最简单的refspec形式。您使用的是最简单的名称:master。没有结肠;没有第二个名字。这仍然是有效的refspec,但意味着git fetchgit push中有所不同。由于我们只关注git fetch,因此请see what it means there

  

&LT;的Refspec&GT;

     
    指定要获取的引用和要更新的本地引用。 ...
     
    &lt; refspec&gt;的格式参数是一个可选的加号+,后跟源&lt; src&gt;,后跟冒号`:`,后跟目标ref&lt; dst&gt;。当&lt; ds&gt;时,可以省略冒号。是空的。 ...
     
    匹配&lt; src&gt;的远程引用取出,如果&lt; dst&gt;不是空字符串,匹配它的本地引用使用&lt; src&gt;快进。 ...

由于您没有:和目的地,因此&lt; dst&gt; part为空,没有快速转发本地引用。 (前导加号+会告诉Git强制更新本地引用,即使快速转发会失败,但是你首先省略了本地引用,所以{{{{{{{ 1}}强制标志影响。)

这意味着提交+带来的提交仅记录在旧的向后兼容的Git 1.5版git fetch文件中。因此,您必须FETCH_HEAD合并其ID保存在git merge FETCH_HEAD中的提交 - 其他Git的FETCH_HEAD分支的提示。

其他替代方案

如果在命令行上提供了不存在的目标refspec:

master

(在这种情况下创建一个名为git fetch origin master:refs/heads/tmpbranch 的新本地分支),然后您可以将其作为参数提供给tmpbranch

git merge

然后将其删除:

git merge tmpbranch

这样您就可以准备下次了(没有git branch -D tmpbranch 可以让tmpbranch可能失败。

或者,您可以使用force-flag强制创建或更新您自己的git fetch分支:

master

(这取决于Git的自动资格认证git fetch origin +master:master 转为master - 如果您正在编写脚本,最好明确拼写出来;自动资格认证是懒惰的人,而不是计算机)。然后你可以refs/heads/master

请注意,如果您已创建并正在使用它,则会覆盖您自己的本地git merge master。因此,您可能希望使用远程跟踪名称:

master

之后您将运行git fetch origin +master:refs/remotes/origin/master

最后,你可以指导你的Git始终默认获取其他Git&#39; git merge origin/master

master

现在你可以运行:

git config --add remotes.origin.fetch '+refs/heads/master:refs/remotes/origin/master'

现在提取git fetch origin git merge origin/master ,因为有两个origin设置,请抓取其他Git分支的remote.origin.fetch mybranch,将获取的哈希ID放入远程跟踪名称masterrefs/remotes/origin/mybranch

(将其与默认的refspec refs/remotes/origin/master进行比较,它告诉您的Git获取所有分支,并创建或更新名称与其他分支名称匹配的远程跟踪名称GIT中。)

答案 2 :(得分:0)

我也克隆了一个分支,深度为1(单次提交):

git clone --depth 1 --single-branch branch_to_merge

现在我想将其合并到一个新的分支“ destn_branch”中,但尚未在我的本地克隆它,因此我不得不首先再次获取该分支...

git fetch --depth 1 origin destn_branch:destn_branch

(我本不应该做深度1的,但是我别无选择:(,提交的次数太多了> _>)

现在我 可以 可以

git checkout destn_branch
git merge branch_to_merge

但是git说“你疯了,那两个分支是无关的”(那是“罕见的历史”,我忘了文字)

因此,我通过更深层次地重新运行上述命令来增加git,以便他们共享一个共同的历史提交,并且git可以理解它可以从那里链接两个分支。 因此,我重新运行了以下命令,它起作用了:

// fetch 3 latest commits of branch_to_merge
git checkout branch_to_merge
git fetch --depth 3

// fetch 4 latest commits of destn_branch - this way one of the fetched commits is the same as in other branch's fetched commit
git fetch --depth 4 origin destn_branch:destn_branch

// now do a normal merge
git checkout destn_branch
git merge branch_to_merge

他们称我小气总是因为做深1单克隆拉---,现在他是审慎的> _>