Git可以跟踪祖先分支及其自己的分支吗?

时间:2020-03-11 20:55:36

标签: git git-track

很抱歉,如果这是一个菜鸟问题,但我一直在搜索一个小时以上,无法获得明确的答案。

我想做的是这样:

  • 检出远程分支git checkout origin/feature
  • 根据分支机构git checkout -b feature_my_tweak创建一个本地分支机构
  • 因此,现在我有一个feature的本地副本,称为feature_my_tweak,我可以使用它
  • 进行一些更改,commit -m "added my tweak"现在我的本地feature_my_tweakfeature有所不同
  • 现在执行git push --set-upstream origin feature_my_tweak来将我的本地分支推送到远程服务器
  • 现在一个同事将更改推送到远程服务器上的feature

在这一点上,我希望能够git pull并让git看到feature有所更改,并将其(获取/合并)到我的本地feature_my_tweak中科。有没有一种方法可以自动执行此操作?还是我必须手动进行git merge feature才能将所有更改从该分支转移到我的本地feature_my_tweaks分支?我想我以为有一种方法可以使一个分支跟踪另一个分支。

另一部分是,我仍然希望能够对feature_my_tweaks进行本地更改,并且仍然能够git push并且仅将其推送到远程{{1} }分支,并且不会污染origin/feature_my_tweak分支。

有没有办法做到这一切?据我了解,似乎如果任何branch_A正在跟踪远程branch_B,则任何推送都将进入branch_B,这是我所不希望的。

我希望这是有道理的。

1 个答案:

答案 0 :(得分:2)

TL; DR

答案的简短版本归结为否,但这并不重要,不必担心,只需手动即可;很简单。如果您经常使用一个特定的分支,请编写脚本或Git别名来实现。

中等

要手动执行此操作,对于您的分支 B ,您想知道origin/feature上是否有新内容,而您自己的分支feature_my_tweaks的上游设置为{{ 1}},只需运行:

origin/feature_my_tweaks

这将打印出两个数字。左侧的数字是您在git rev-list --count --left-right feature_my_tweaks...origin/feature 上拥有的,不属于feature_my_tweaks的提交数。右边的数字是origin/featureorigin/feature上没有的提交次数。

如果第二个数字不为零,并且您愿意,现在可以运行feature_my_tweaksgit checkout feature_my_tweaks; git rebase origin/feature

是否以及何时使用git checkout feature_my_tweaks; git merge origin/feature取决于您,但是重新定级后,您将需要git rebase(或git push --force origin feature_my_tweaks)才能在git push --force-with-lease origin feature_my_tweaks上使用Git。丢弃您的origin在将您的提交复制到新的和改进的提交时丢弃的旧提交。

这里最大的问题可能是术语。 tracking 一词对您意味着什么? Git至少以三种不同的方式来使用这个单词, 1 ,因此其中最多一种可以与您正在考虑的单词匹配。 (根据您的想法,这里可能没有一个完全匹配。)

不管您使用哪个字,这都是思考这个问题的正确方法:

  • 重要的是 commits 。每个提交都有一个唯一的哈希ID。每个地方的每个Git(此存储库的每个副本)都使用 that 哈希ID进行提交。如果您有一个带有那个哈希ID的提交,则它是相同的提交。如果没有,则没有该提交。

  • Git中的
  • 名称具有多种形式。每个名称都拥有一个哈希ID,只有一个!

    您使用的三种形式是:

    • 分支名称: git rebasemasterdevelopfeature,依此类推。这些是您的,与您一样会做。 (不过,至少在不同的时间,您可能会想要与他人的名字相匹配。)

    • 标记名: feature/one,依此类推。当您属于您时,您的Git会尝试与其他Git存储库共享:如果您的Git看到他们有v2.1,而您没有,则您的Git可能会复制它们给你的。

    • 远程跟踪名称: v2.1origin/master,依此类推。 Git称这些远程跟踪分支名称,有些人将其简称为远程跟踪分支,但它们与分支名称不太相似。您的Git将这些奴隶奴隶到其他一些Git的分支名称。您让您的Git呼叫他们的Git,并从他们那里获取任何新提交。然后,您的Git会更新您的远程跟踪名称,以使其与它们的名称匹配。

      远程跟踪名称是通过将远程名称(在本例中为origin/feature)粘贴在其分支名称之前并用斜杠让他们分开。这就是为什么您的origin“跟踪”他们的origin/master,并在每次运行master时进行更新。 2


    所有这些名称都类似地工作。它们都有很长的格式:例如git fetch originrefs/heads/master的完整拼写,而master则是refs/remotes/origin/master。这就是Git知道哪种名字的名字的方式。 Git通常会缩短显示给您的名称,删除分支名称的origin/master部分或远程跟踪名称的refs/heads/部分。

    < / li>

请注意,refs/remotes/git fetch的对面一样近。看起来这些应该是git pushpush,但是由于历史事故 3 ,它们分别是pullpush。拉取仅表示:运行获取,然后默认运行第二个Git命令fetch,以与当前分支的上游合并。

提取和推送非常相似,但有两个主要区别:

  1. 获取获取内容。您告诉Git:调用以名称git merge (或您在此使用的任何远程名称)存储URL的Git。您的Git会在该URL上调用服务器,该URL必须作为Git存储库来回答。然后,该服务器会告诉您其分支名称及其提交,然后您的Git会检查您是否有那些提交。如果没有,您的Git会向其Git询问这些提交,如果您没有它们,则向其父母提交,如果需要,则向父母的父母提交,依此类推。它们会为您提供所有您拥有的,您没有的,Git需要完成的提交。

    已获得提交,origin然后通过重命名分支来更新您的远程跟踪名称

  2. 推动发送东西。和以前一样,您的Git通过一个远程名称(如git fetch来调用另一个Git。然后,您的Git给他们提交,而不是从他们那里获得提交。但是这里有些不同:

    • 您的Git提供的提交是您要推送的任何分支的提示提交。 (如果您只是推动一个分支,那只是一次提交。)如果他们没有这些提交,则您的Git必须提供这些提示提交的父级。 (大多数提交只有一个父母,所以又有一个提交。)如果他们没有那些,则您的Git必须提供更多的父母,依此类推。通过此过程,您的Git会找到其Git所需的所有提交,以完整了解您要发送的 tip 提交:所有历史记录。

      在获取时,他们提供了 all 个分支。区别在于:您只推送指定的任何分支。

    • 当您的Git发送了您没有的所有提交后,他们需要为您要推送的分支完成提示提交,您的Git发送了一个礼貌的请求让他们设置自己的分支名称。

      获取时,您的Git会设置您的远程跟踪名称。您现在要他们设置他们的分支名称。

总结这些关键点:

  • 获取获取(默认情况下,除非受限制,否则全部为默认值)从它们提交并分支,并将其分支重命名为您的远程跟踪名称
  • push sends (默认为一个) 4 分支提示提交(及其祖先(如果需要),然后要求他们设置其分支名称) )

可以origin要求他们设置一个与您用来选择要提交的提交的名称不同的不同的名称。例如:

git push

发送git push origin test-xyz:new-feature 分支(及其父项和其他祖先,如果需要的话)的尖端提交,但要求他们设置或创建分支名test-xyz

所以:

...看来,如果任何branch_A都在跟踪远程branch_B,则任何推送都会转到branch_B ...

这是完全错误的,至少在默认情况下是这样。 (不过,new-feature有一个设置确实实现了。)

这里有很多要了解的东西,尤其是push.default在做什么以及“提交”(或更准确地说,可从到达)意味着什么?分支名称,但此时此答案我已经用完了时间和空间。


1 特别是,可以对文件进行跟踪未跟踪,某些名称是远程跟踪名称,并称具有上游集的分支是 tracking (上游)。在前两种情况下,动词(以其现在的分词形式)变为形容词,修饰了 name file

2 有些方法可以运行有限的git rev-list --left-right --count,而不会会更新您的所有远程跟踪名称。例如,有时使用git fetch会这样做。我更喜欢将git pull和其他命令分开,而不是使用git fetch fetch-then-run-another-Git-command命令。

3 在获取后通常想集成所获取的内容,因此起初,git pull是一个后端“管道”命令,而不是供用户运行,然后git fetch先运行git pull,然后再运行git fetch。这是在 remotes 作为概念出现之前,因此在还没有远程跟踪名称之前,因此没有任何理由让用户运行git merge

随着时间的流逝,Git增加了远程名称和远程跟踪名称,现在git fetch(获取并合并)与pull之间的区别就是没有合并(或者至少没有这样做然而)变得既有用又重要。但是名称 fetch已被用来表示获取并合并,因此发生了这种特殊的历史事故。

4 也就是说,这是Git 2.0及更高版本中的默认设置。您可以使用pull进行更改,而2.0之前的Git版本默认为push.default

使用matching时,您的Git会询问其Git有关其分支名称的信息,匹配您匹配的分支名称,默认情况下是从您的匹配名称推入其匹配名称。

如果您将此设置更改为matching,您的Git会要求其Git根据分支的上游设置来设置其分支,这就是您在问题中所假定的。

现代的默认设置为upstream,这要求将上游设置为相同名称的分支,以便您端的simple立刻失效如果您的上游设置为他们这边的其他名称。但是,您可以通过输入git push来轻松地覆盖它,这与git push origin branch含义相同:要求其Git使用与您在Git中使用的相同的分支名称。

相关问题