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

3
我有一个Git存储库,其中master是应用程序的当前版本,每个客户都有自己的分支,具有自己的自定义内容。
我使用--single-branch单独将每个客户的分支克隆到目录中。
我的目标是将master合并到我的分支中。我使用以下命令克隆了存储库:
git clone {{REPO_URL}} --single-branch my-branch --branch my-branch

然后我尝试了:

git fetch origin -- master

git merge master

我得到了以下信息:

合并:主分支 - 不是我们可以合并的内容

我知道我可以通过克隆整个仓库来解决这个问题,但有没有其他方法可以解决?

3个回答

5

您只需要将URL添加为本地存储库中的另一个远程存储库即可。

以下是详细命令:

# 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

这个方法可以运行,但是它会拉取所有的分支,而我想要避免这种情况。仓库中有很多数据,我不想拥有整个仓库的许多副本。这就是一开始使用“--single-branch”的原因。是否可能只为主分支添加上游? - Firze
@Firze 是的,这是可能的。-t branchname 可以实现这一点。你可以在我的回答中找到详细信息。 - Marina Liu

0

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

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

现在我想将它合并到一个新的分支 "destn_branch" 中,但是我没有在本地克隆它,所以我必须先再次获取该分支...

git fetch --depth 1 origin destn_branch:destn_branch

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

现在我可以这样做

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的单个克隆,现在谁更谨慎>_>


0

简述

你必须:

  • 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文档将其缩写为<src>和<dst>)。

然后考虑你的命令:

git fetch origin -- master
(这里的--是无意义的。)git fetch命令将origin视为存储库的名称(因此它查找与origin关联的URL和fetch =origin关联的refspecs),然后将master视为一个refspec,与先前定义的任何fetch refspecs组合并部分覆盖。

当您进行--single-branch克隆时:

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

这将更改与新克隆相关联的fetch refspecs。(注意:额外的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,让我们 看看它在那里的含义,即:

<refspec>

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

由于您没有和目标,因此<dst>部分为空,并且没有本地引用被快速转发。(前导加号+会告诉Git强制更新本地引用,即使快速转发失败,但首先省略了本地引用,因此+强制标志对其没有影响。)

这意味着git fetch带来的提交仅记录在旧的、向后兼容Git版本1.5的FETCH_HEAD文件中。因此,您需要git merge FETCH_HEAD来合并保存在FETCH_HEAD中的提交ID——另一个Git的master分支的尖端提交。

其他选择

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

git fetch origin master:refs/heads/tmpbranch

在这种情况下,您可以创建一个名为tmpbranch的新本地分支,然后将其作为参数提供给git merge

git merge tmpbranch

然后将其删除:

git branch -D tmpbranch

这样你就可以为下一次做好准备(没有tmpbranch留在那里,可能会导致git fetch失败)。

或者,你可以使用强制标志来强制创建或更新你自己的master分支:

git fetch origin +master:master

这依赖于Git的自动限定,将master转换为refs/heads/master——如果您正在编写脚本,最好明确说明;自动限定是为懒惰的人类而不是计算机设计的。然后您可以使用git merge master

请注意,如果您已经创建了自己的本地master并正在使用它,则此操作将覆盖它。出于这个原因,您可能希望改用远程跟踪名称:

git fetch origin +master:refs/remotes/origin/master

然后你可以运行 git merge origin/master

最后,你可以将你的 Git 设置为默认获取其他 Git 的 master 分支:

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

现在你可以直接运行:

git fetch origin
git merge origin/master

现在从origin获取,因为有两个remote.origin.fetch设置,将获取另一个Git的所有分支,mybranchmaster,并将获取到的哈希ID放置到您的远程跟踪名称中,refs/remotes/origin/mybranchrefs/remotes/origin/master

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


简而言之:git fetch origin +master:refs/remotes/origin/master。请阅读上文了解其作用和原因。感谢@torek提供的详细信息! - theannouncer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接