【问题标题】:How to set up branches with different pull/push upstreams如何设置具有不同拉/推上游的分支
【发布时间】:2018-01-20 04:29:44
【问题描述】:

我有一个带有两个遥控器的本地 git 存储库:upstream,原始主存储库和 origin,我的 GitHub 分支。

我想基于 upstream/master 创建新的分支,将它们推送到 origin 以获得 PR,并定期从 upstream/master 中提取新的更改。

有没有办法设置我的分支,以便默认情况下发生这种情况?即:

$ git checkout -b my-new-branch --some-other-flags
$ git maybe some other command
# branch 'my-new-branch' points to 'upstream/master' and is checked out
# make changes, git commit
$ git push  # pushes to origin/my-new-branch
$ git pull  # pulls from upstream/master

【问题讨论】:

    标签: git github version-control git-fork


    【解决方案1】:

    以下似乎有效:

    git config push.default current && git config remote.pushdefault origin

    然后,使用git checkout -b new-branch upstream/master 创建分支。

    git push 推送到 origin/my-branchgit pullupstream/master 拉取。


    对于基于其他本地分支而不是上游/主分支的分支,事情似乎有点棘手。我可以git config branch.autoSetupMerge always,但随后分支将从他们开始的本地分支中提取,而不是upstream/master。或者我可以在创建分支时使用-u 明确地将上游设置为upstream/master。不过我不确定哪个更合适。

    另一个烦恼是,当我签出有更改的分支时,git 有时会告诉我:

    您的分支领先于“上游/主”7 次提交。 (使用“git push”发布你的本地提交)

    但是 A)我领先于上游很好,我正在等待将这些更改合并到 PR 中,并且 B)更重要的是,git push 将在 originnew-branch /em>,而不是上游的master

    但这并不总是发生,所以我认为这里还有一些其他变量。

    【讨论】:

    • 既然你解决了问题,你可以标记你自己的答案。这将使有类似问题的其他人受益。
    • 我仍然对我的解决方案不太满意。它有时似乎有效,但有一些我需要解决的问题。
    【解决方案2】:

    有没有办法设置我的分支,以便默认情况下发生这种情况?

    否:每个分支您只能获得一个“上游”或 @{u} 设置(如果您愿意,您可以设置一个带有 no 上游设置的分支,但您的另一个选项是 one 上游)。 git fetch 从这个上游的远程获取,git merge 与这个上游命名的分支合并(和往常一样,git pull 本质上等于 fetch + merge); git push 推...好吧,现在事情变得复杂了。

    有没有办法设置我的存储库,以便默认情况下发生这种情况?

    是的,但有一个缺陷。这个缺陷有多大取决于您的使用和需求。使用(和配置)这个缺陷非常复杂。让我们来看看这些项目。

    每个本地分支只能有一个上游,但是:

    • 上游命名两个部分。一个是远程,例如originupstream;另一个是 merge,例如 refs/heads/master

    例如,这些组合起来形成origin/master。因此,无论 anything 是否为 origin,我们都无法将默认上游设置为 origin/master<em>anything</em>/my-new-branch

    但是:

    • 您可以将 Git 配置为“三角工作流”,通过为任何一个给定的远程设置 两个 URL,您可以从一个 URL 获取但推送到另一个 URL。

    这意味着您可以制作一些遥控器,我们将其命名为tri 用于三角形,从您拥有的origin 的URL 获取并推送到您拥有的upstream 的URL。如果分支Btri 作为它的远程,并且tri 从与origin 相同的URL 中获取,但推送到与upstream 相同的URL,那么您实际上将获取从origin 推送到upstream

    不过,对于 refs/remotes/tri/master 的含义,您的 Git 会有些困惑。。如果是表单的推送:

    git push tri somebranch:master
    

    成功了,您的 Git 现在认为 refs/remotes/tri/master 具有您刚刚推送的相同哈希值。你的 Git 认为:好吧,当然!我在tri 下打电话的那个人说他接受了! 一旦你运行git fetch tri,你会得到一些其他的哈希值,你的Git 会修复它以再次记住与origin 相同的URL 上的内容.你的 Git 认为:嗯,这很有趣,我打电话给 tri 的那个人说他已经重置了他的 master。哦,好吧,那是你的另一个 Git,一直在重置他的 master...

    此外,当您运行 git push trigit push 并隐含 tri,但在命令行上没有 refspec 参数时......嗯,这来自 the git push documentation

    如果 git push [&lt;repository&gt;] 没有任何 &lt;refspec&gt; 参数 设置为使用&lt;src&gt; 更新目的地的一些参考 remote.&lt;repository&gt;.push配置变量,:&lt;dst&gt;部分可以 省略——这样的推送将更新&lt;src&gt; 通常更新的引用 在命令行上没有任何&lt;refspec&gt;。否则,失踪 :&lt;dst&gt; 表示更新与&lt;src&gt; 相同的引用。

    这意味着您可以设置一个特殊的remote.tri.push 配置,以便git push tri 不命名源,或git push tri somebranch 不命名:&lt;dst&gt;,您可以在此处使somebranch 映射到somebranch,即使你被允许somebranchmaster 的一个上游设置。

    把这些放在一起

    • 你只会得到一个@{u}
    • 但是@{u} 有两部分,remotemerge
    • 您的@{u} 可以命名一个具有两个 URL 的特殊遥控器:一个用于获取,另一个用于推送。
    • 这个遥控器还可以有一个remote.<em>remote</em>.pushdefault,它会强制推送:dst 部分使用与提取的merge 设置不同的名称。 (最后一点我们称之为 pushtarget。)
    • 副作用是远程跟踪分支<em>specialremote/pushtarget</em> 会出错,直到您运行git fetch <em>specialremote</em>。这会让事情变得混乱,就好像它们还没有因为上述所有原因而变得混乱。

    如果你问我这样做是否是一个好主意,我会说:绝对不是

    【讨论】:

    • 只是为了强调这是对 git 的滥用:“请注意,推送 URL 和获取 URL,即使它们可以设置不同,仍然必须指向同一个地方。你推送到的内容如果您立即从获取 URL 获取,推送 URL 应该是您将看到的内容。如果您尝试从一个地方(例如您的上游)获取并推送到另一个地方(例如您的发布存储库),请使用两个单独的遥控器。 git-scm.com/docs/git-remote#git-remote-emset-urlem
    【解决方案3】:

    创建分支后,您需要将其推送到上游并设置它,以便您的 local 可以跟踪 remote

    你可以这样做(假设你已经在 master 分支):

    // Create and checkout the new branch
    git checkout -b <your_branch_nane>
    
    // Push new branch upstream and set it to track remote branch
    git push -u origin <your_branch_name>
    

    这会将您的新分支推向上游; -u 参数将其设置为跟踪远程分支。 -u 参数只是 --set-upstream 参数的快捷方式。

    你可以阅读更多关于working with remote branches的信息。

    【讨论】:

      【解决方案4】:

      有几种方法可以解决这个问题。我认为您可能想要的是采用如下所示的工作流程:

      1. 开始基于上游master的新分支:

        git checkout -b my-new-branch upstream/master
        
      2. 进行更改,并将分支配置为推送到远程存储库:

        git push -u origin my-new-branch
        

        (随后您可以单独运行git push,更改将发送到您的存储库)

      3. 当你想从上游引入新的变化时:

        git remote update
        git rebase upstream/master
        

      这使您可以定期从上游引入新的更改,同时保留线性历史记录(而不是乱七八糟的合并提交),这可以简化您想要将更改提交回上游的事情。

      【讨论】:

      • 这基本上就是我现在正在做的事情,我只是想看看是否有我可以设置的标志/配置以默认情况下实现这一点,而无需记住许多单独的步骤。
      猜你喜欢
      • 1970-01-01
      • 2016-10-24
      • 2010-12-27
      • 2017-11-03
      • 2014-04-09
      • 1970-01-01
      • 2012-10-09
      • 2015-04-02
      • 2015-01-27
      相关资源
      最近更新 更多