【问题标题】:I am really confused about Git Branches我真的对 Git 分支感到困惑
【发布时间】:2022-06-13 22:49:31
【问题描述】:

我来自 TFS 背景,所有内容都存储在 SQL Server 中。我现在处于通过 DevOps 使用 GIT 来管理代码的情况。有几件事我很困惑。

假设我通过 Web 浏览器进入 DevOps,我看到了默认分支(即 Master)。现在我进入 Visual Studio 2019,我说基于 Master 的新分支,并将其命名为 QA_6.5.3_George。

分支似乎已创建,我有代码,但在 DevOps 中看不到该分支。当你创建这样的分支时,它只是本地的,直到你把它推上去?

然后,假设我想清理我创建的分支:

我在 Visual Studio 中单击 Git Repository Explore 并看到以下内容:

我只想删除我的本地分支。我怎么知道哪些是我创建的分支,哪些不是我的?我只是觉得这很令人困惑。我找到了关于如何删除分支等的文档。我只是不明白 Git 背后关于“所有权”和分支位置的内容。

仅供参考,我希望在 Azure DevOps 和 Visual Studio 2019 的背景下理解这一点

任何帮助将不胜感激。

更新:所以这是我试图理解的一个实际示例:

这是我的 DevOps 服务器,显示除了 master 之外我没有其他项目的分支:

但是在 Visual Studio 中,我看到我有一个基于 6.5.2 的分支。

我想了解的是为什么我在 DevOps 中看不到我的 QA_6_5_3_George 分支?

【问题讨论】:

  • 听起来您正在寻找有关 git 基本概念的教程。当您尝试搜索答案时,您使用了哪些术语?
  • Git 分支没有所有者。 (一些托管站点 add 的“保护”概念到各种分支名称,但这不是 Git 的一部分。)事实上,分支 names 在 Git 中并不重要,你根本不应该非常关心它们 except 因为 humans(不是 Git)使用分支名称来 find 特别重要的-人类提交。 Git 真的是关于 commits
  • Git 存储库是提交的集合。提交本身带有编号,带有神奇的“哈希 ID”(或正式的对象 ID、OID)。这些数字看起来是随机的,人类很难使用。因此,存储库还包括一个单独的 names 表,例如分支和标记名称;这些名称帮助 Git 的人类用户找到提交哈希 ID,以便 Git 可以找到提交。 (Git 需要原始哈希 ID。)如果您不再找到对查找提交有用的名称,您可以随意删除该名称:您将无法再找到这些提交。跨度>
  • 另一方面,如果您想保留查找提交的能力,请保留 name。只要对有用,就保留分支或标签名称。当它对不再有用时,将其删除。基本上就这些了。
  • 在您包含的图像中,粗体分支是您当前所在的分支(始终是本地分支)。 remotes/origin 下有那个蓝色小图标的分支是远程分支(特别是远程origin)。所有其他分支都是本地分支(因此删除它们不会影响其他任何人)。

标签: git visual-studio azure-devops


【解决方案1】:

我认为,这就是您的困惑所在:Git 是一个分布式版本控制系统,其中每个用户都可以获得每个存储库的副本 Git 存储库主要由1 两个数据库组成,一个通常比另一个大得多:

  • 较大的数据库包含提交和其他内部 Git 对象。这些对象都有编号:每个对象都有一个非常大的随机数字,用hexadecimal 表示,Git 将其称为 object ID 或更不正式地称为 hash ID .这些数字在存储库的每个副本中都是相同的:也就是说,如果您的副本有一个哈希 ID 为 9c897eef06347cc5a3eb07c3ae409970ab1052c8 的对象,而其他一些存储库有一个具有相同哈希 ID 的对象,那么这些是同一个对象

    Git 需要这些数字来访问对象。但显然很难记住9c897eef06347cc5a3eb03c3ae409970ab1052c8。这甚至与我刚才引用的数字相同吗? (不是。看看你能不能看到我改变了哪个字符。)因此,每个存储库都有第二个数据库:一个将 names 映射到哈希 ID 的表。

  • 较小的数据库是这个名称表。在这里,您将找到您的分支名称、标签名称和远程跟踪名称,以及其他名称。每个名称仅映射到一个哈希 ID:这意味着您可以输入分支名称,例如 mastermainQA_6.5.3_George 并让 Git 本身 查找正确的哈希 ID。

通过使用名称而不是数字,您可以避免记住哈希 ID。但这里我们必须小心:branch name 不是 branch,除非说 branch 的人表示 branch name 。 (有关记住事物与其名称之间区别的幽默方式,请参阅the Wikipedia article on Haddock's Eyes。有关 Git 中的更多区别,请参阅What exactly do we mean by "branch"?

当你克隆一个仓库时,你会得到所有的提交(和支持的对象),你得到根本没有分支名称。然后,克隆存储库后,您的 Git 软件将在您的存储库中创建 一个 分支名称。您可以使用此分支名称或任何远程跟踪名称来创建更多分支名称;或者您可以使用任何 Git 提交哈希 ID 创建分支名称。 hash IDsGit 关心的。分支名称的存在是为了您的目的。

同样,克隆过程仅复制 commits(和其他 Git 对象)数据库,而不是 names 数据库。这意味着所有您的分支名称都是本地的。甚至您的远程跟踪名称也是本地名称:它们是您的软件和存储库本地 内存 其他存储库的 分支 名称。

当您运行git push 时,您的 Git 软件会连接到其他一些 Git 软件。您的 Git 软件从您的 Git 存储库中读取。他们的软件读取并可能写入他们的存储库。您的 Git 可以在这里看到他们的分支名称(和其他名称)以及他们的哈希 ID,并且您的 Git 可以向他们的 Git 提供 commits

您的 Git(与您的存储库一起工作的软件)现在将向他们的 Git(他们的软件与他们的存储库一起工作)提供您所做的任何新提交,而他们还没有。这一切都通过 hash ID 起作用。因为哈希 ID 是唯一的,并且当且仅当两个存储库具有相同的实际 commits 时才匹配,所以您的 Git 可以轻松判断您拥有的某些提交是否与它们的某些提交相同有。因此,您所做的任何新 提交 都可以发送过来,而无需重新发送现有提交。

一旦您的 Git 完成发送新的提交(根据需要),您的 Git 现在要求他们的 Git 创建或更新一个its 分支名称数据库中的 its 分支名称。如果他们遵守这个礼貌的要求,你的 Git 也会创建或更新你相应的远程跟踪名称。

例如,假设您创建了一个新的分支名称george-ceaser。让我们进一步假设 他们 没有相同的分支名称。

无论您是否在此分支上进行任何新的提交,然后运行 ​​git push origin george-ceaser 以便您的 Git 调用他们的 Git 并:

  • 发送您所做的任何新提交(如果有),然后
  • 要求他们在他们的 Git 中创建或更新一个名为 george-ceaser 的分支。

如果他们遵守这个礼貌的请求,他们现在有一个分支名称george-ceaser,并且您的 Git 将创建 origin/george-ceaser 以记住您刚刚让他们记住的名称 george-ceaser 下的相同哈希 ID。现在你和他们有“同一个分支”,正如人类所说的那样——但事实上,他们有他们自己的名字george-ceaser,而你自己的名字george-ceaser。这是两个不同的名字,只是碰巧拼写相同!

您可以随时删除您的george-ceaser。完成后,您应该将其删除。这根本不会影响他们的 george-ceaser:那个是他们的 名字。如果您希望他们删除 他们的 george-ceaser,您可以这样做:

git push origin --delete george-ceaser

向他们发送一个礼貌的请求,他们删除他们的分支名称george-ceaser。如果他们遵守这个礼貌的要求,你的 Git 什么都不会发生。如果他们拒绝这个礼貌的请求,你的 Git 什么都不会发生

(同样,“您的 Git”是指“您的软件在您的存储库上运行”。)

时不时地运行git fetch origin --prune 是明智之举。这会让你的 Git 调用他们的 Git,列出他们所有的分支名称,然后——由于 --prune——你的 Git 将从 your 存储库中删除任何@987654345 @ 存在于您的存储库中的名称,但 他们的 分支 名称现在已经消失了。2 通常,您会知道您是否已经在他们的存储库中创建了george-ceaser,如果你在自己的存储库中删除名称george-ceaser,你会知道是否要让他们删除名称george-ceaser在他们的存储库。

你会在一段时间内发现这令人困惑。这从根本上让人类感到困惑,因为他们不能很好地处理克隆。我们认为克隆是精确的复制品,但它们不是;然后我们对副本进行更改,我们不记得我们更改了哪个副本;然后我们混淆了谁拥有什么,事情变得一团糟。请记住,Git 背后的理念是每个人都有一份副本。您对您的副本进行更改,之后您可以(但不是必须)使用git push您的新提交发送给一些其他 复制,然后要求他们创建或更新其分支名称之一以记住您的新提交。

在某些情况下,您最终可能会使用git push --force-with-leasegit push --forcegit push 的最后一步从“礼貌请求”更改为“强制命令”。也就是说,不要问其他 Git 请,如果没问题,请创建或更新您的 george-ceaser 您可以发送 我命令您创建或更新您的 george-ceaser 他们被允许拒绝命令,但他们更有可能服从命令,即使它是有害的,而不是他们服从礼貌的请求,即使它是有害的。所以在使用--force--force-with-lease 时要(非常)小心。当您使用礼貌请求表单时,Git 会努力不做任何有害的事情。


1大部分仓库也提供工作区,你使用的仓库会是这样的。

2我个人非常喜欢这种行为,可以将 fetch.prune 设置为 true,这样每个 git fetch 都会这样做,但在 Git 中到处都有一些尖锐的边缘,这可能会出乎意料删除一些远程跟踪名称,因此您可能只想在仔细选择的时间执行此操作,直到您对此更加熟悉为止。

【讨论】:

    猜你喜欢
    • 2012-09-18
    • 2012-08-22
    • 2015-10-28
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    相关资源
    最近更新 更多