gpt4 book ai didi

git - 更改远程分支的本地引用

转载 作者:行者123 更新时间:2023-12-02 22:49:30 26 4
gpt4 key购买 nike

我有两个存储库绑定(bind)到我的工作目录。

git remote show origin
* remote origin
Fetch URL: ssh://project.git/
Push URL: ssh://project.git/
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

git remote show develop
* remote develop
Fetch URL: ssh://projecttest.git/
Push URL: ssh://projecttest.git/
HEAD branch: master
Remote branch:
master new (next fetch will store in remotes/develop)
Local ref configured for 'git push':
master pushes to master (local out of date)

据我所知,本地分支是通过这种方式引用到远程分支的:
  • 远程origin/master指向本地分支master
  • 远程develop/master指向本地分支master

  • 我要实现的是更改对 develop/master远程分支的引用。我希望它指向 trunk本地分支
  • 远程develop/master应指向本地分支trunk

  • 我该怎么做?

    最佳答案

    在我回答之前,我想在这里更改术语,因为您使用某些单词的方式与大多数git文档中使用的单词和方式都不匹配。

    首先,让我们讨论一下git存储库中的提交所生成的图。

    每当您在存储库中创建提交时,都必须指定以下项目。其中许多是隐式的。实际上,git commitgit merge(这是两个主要的提交创建者)将为您查找所有它们:

  • 父提交,或一组父提交
  • 一个作者和“作者日期”(通常与提交者相同)
  • 是提交者,“提交日期”(通常与上面的作者相同)
  • 是一棵“树”(通常取自索引/临时区域),而
  • 提交消息(通过-m参数或git commit启动您的编辑器等)

  • Git结合了所有这些内容,并给出了一个新的唯一SHA-1值(那些笨拙的40个字符的字符串,如 9c4ea50db79d3ce6fe3abccf20f1af27abae45b2),即为提交(通过SHA-1 ID将该提交对象存储在存储库中)。如果提交是普通提交,则它有一个父对象, git commit会在 HEAD创建新提交之前不久通过 .git(git存储在 git commit目录中)找到该父对象。如果它是“根提交”,如新 repo 中的第一次提交,则它没有父级。如果它是一个“merge 提交”(例如,由 git merge创建),则它至少具有两个父ID(这些ID也来自 .git目录中的git存储文件)。存储在任何给定提交中的父代都是原始的SHA-1 ID。

    因此,给定任何一个提交SHA-1 ID,您都可以从存储库中读取该提交并获取其父提交。读那些书会让你成为 parent 。继续,直到到达根提交,您可以绘制一些东西,其中可能包含分支点和 merge 点:
    o-o-o-o-o-o-o
    \ /
    o-o-o

    这是一个带有十个提交“节点”( o)的提交图,其中一些分支分支出来然后 merge 回去。我在节点之间用 - \/字符画了线。

    当我们使用git时,我们经常将这些行称为“分支”,这是一个合理的名称,但是“分支”还有另一种含义。

    接下来,让我们以这种方式定义一个“分支”(或“本地分支”),这就是git真正起作用的方式: (本地)分支是一个名称,例如masterdevelop,它存储一个SHA-1 ID并且具有另一项特殊属性(property)。 的特殊属性是,当我们进行新的提交时,存储的ID会更改,以便分支名称始终标识分支的“尖端”。

    请记住,每个提交都有其父ID,但没有任何子ID。当您进行新的提交时,新的提交(通过这些存储的ID)“指向”旧的提交,但是旧的提交永远不会改变。仅给定父ID的子ID很难找到,但给 child ID的父ID却很容易。因此,只要分支名称“指向”分支的尖端,我们就可以轻松找到“分支的其余部分”。因此git只是保证本地分支名称始终标识分支的尖端。

    (不幸的是,“分支”的意思是“拥有分支尖端ID的本地名称”和“从尖端开始并向后工作而形成的提交链”。几乎总是显而易见的是,哪一个是仅在“几乎”时使用。)

    现在让我们定义“远程”: 远程名称是由您组成的名称,并放置在本地git存储库中,该名称将用于记住有关其他git存储库的事情,通常是在另一台机器上并属于其他人。 远程有一个 url(或者有时是几个: remote.origin.url和可选的 remote.origin.pushurl),这是git从另一个 repo 中获取和推送的方式。

    当然,其他 repo 具有(本地)分支(指向提示提交的分支名称),事实证明,我们经常希望知道其他 repo 的本地分支(名称和提示提交)的含义,或更确切地说,他们是我们上次检查的时间。 (它们过时了,所以我们会不时刷新它们。)这些就是“远程分支”。因此,现在我们可以通过示例宽松地定义“远程分支”:远程分支 remotes/origin/master是本地分支 master的副本,在远程 origin上,这是我们最后一次有机会连接到 origin并询问“什么”在您的 master中?”

    更精确地说: 每个远程分支remotes/R/B是上次我们检查并保存时在远程B上本地分支R的副本。

    现在我们只需要为“跟踪分支”定义一个。 跟踪分支是一个本地分支,我们在其中告诉git有一个相应的远程名称,在该远程名称上还有一个相应的分支名称。 我们告诉git这两项的底层方法是使用 git config配置两个字符串。例如,假设我们希望本地分支 greyhound跟踪名为 racetrack的远程 hare上的分支。为此,请执行以下操作:
    git config branch.greyhound.remote racetrack
    git config branch.greyhound.merge hare

    (要使事情复杂化-这似乎是历史性的意外-实际的跟踪是通过 Remote 的 fetch配置进行映射的。但是 remote.racetrack.fetch几乎总是设置为读取 +refs/heads/*:refs/remotes/racetrack/*。在大多数情况下,我们只能假设 refs/remotes/部分是恒定的。)因此,再次,在底层,当git想查看 greyhound是否 catch hare时,它的真正作用是查看 remotes/racetrack/harehare部分来自 branch.greyhound.merge行,而 racetrack部分来自 branch.greyhound.remote

    如果您忽略它,Git将提供 remotes/部分。因此,通常不用编写 remotes/origin/master即可编写 origin/master。 (如果创建歧义,会有一些异常(exception),例如,如果您创建一个名为 origin的本地分支,它会很棘手。但是只要您不这样做,就可以忽略 remotes/,而人(和git)通常会这样做放掉它。)

    最后一点请注意,因为我具有上面的所有其他定义。特殊引用 HEAD通常是“符号引用”。符号引用包含另一个引用的名称,通常是本地分支名称。这是git知道如何将本地分支调整为新的分支提示的方法:如果您“在分支主站点上”,则 HEAD包含 ref: refs/heads/master,因此 git commit会添加新的提交并也会更新 master。如果 HEAD包含原始SHA-1值,则 git commit照常添加新的提交,然后将 HEAD更改为具有新的SHA-1,但是没有本地分支名称指向新的提交。这是“分离头”条件。

    ew!好的,现在回到手头的问题。您将偶然发现git中当前已解决的烦恼。

    您想要或需要:

    远程名为 origin上的
  • ,必须有一个带有master分支
  • 的git repo
    远程名为 develop上的
  • ,必须有一个带有master分支
  • 的git repo
    本地仓库上的
  • ,您希望master成为origin/master的跟踪分支
  • 本地仓库上的
  • ,您希望trunk成为develop/master的跟踪分支
  • 当您使用git push origin时,您希望将自己的master推送到原点的master,并且可能根本没有将trunk推送到所有
  • 当您使用git push develop时,您希望将自己的trunk推送到开发的master,并且可能根本没有将master推送到所有
  • 当您使用git push(不带其他参数)时,您想要...好吧,我不确定您想要的是什么,但是我在下面进行猜测。

  • 步骤1至4仅需执行一次。如果尚未在一个或两个上都创建分支 master,则可以执行以下操作:
    git push -u origin master:master
    git push -u develop trunk:master

    (如果您的git push足够新,可以使用 -u)一次完成所有操作。或者,您可以使用 --set-upstream(如果有的话),也可以使用 git config完全手动进行跟踪。但是,一种或另一种方法是,根据需要在远程存储库上创建分支,然后将其拾取(作为本地存储库中的“远程分支”),并设置本地分支以“跟踪”远程分支。

    剩下剩下的步骤了。这些变得有些困惑。

    在最新版本的git(至少1.7及更高版本)中,有一个配置设置 push.default,当您省略refspec时,该设置会影响 git push的工作方式,即项目5至7中的 push命令。您需要将此设置为 upstream 。这永远不是默认设置,因此您必须运行:
    git config push.default upstream

    设置它。

    如果您运行一个简单的 git push(如#7),则git使用相同的跟踪分支信息来选择远程服务器。所以在这里,现在您已经更改了 push.default,如果您在 master分支上并运行 git push,则实际上将在运行 git push origin master:master;如果您在分支 trunk并运行 git push则实际上将在运行 git push develop trunk:master

    但是,如果您只是让 push.default upstream设置起作用,然后在使用 git push develop时运行 master,那么您并没有告诉它推送名为 trunk的本地分支。因此,要使5和6正常工作,您需要两个不同的git配置项。

    如果您运行 git push remote(不带refspec参数),则 git push会查询 remote.remote.push,并在已设置的情况下使用它。因此,您可以设置 remote.origin.push master:masterremote.develop.push trunk:master。现在 git push develop有了设置,不需要使用 push.default

    关于git - 更改远程分支的本地引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20310723/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com