Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git如何在技术层面上允许一个文件同时存在于两种状态?_Git_Macos_Github - Fatal编程技术网

git如何在技术层面上允许一个文件同时存在于两种状态?

git如何在技术层面上允许一个文件同时存在于两种状态?,git,macos,github,Git,Macos,Github,我对git和github非常陌生,我正试图了解这个程序的所有不同功能 我目前正在探索在我的本地回购中建立新的分支机构,将这些分支机构推到我的远程回购中,并在我的本地回购中的分支机构之间切换,我遇到了一个既令人困惑又非常有趣的属性,我希望有人能对该属性的工作原理提供一些澄清 我正在处理一个html文件。在我的本地回购协议中,我创建了一个新分支,签出了该分支,并在分支中打开了该文件并进行了一些编辑。然后,我回到我的另一个分支,打开了同一个文件,正如预期的那样,我所做的编辑不在那里,因为它们存在于另一

我对git和github非常陌生,我正试图了解这个程序的所有不同功能

我目前正在探索在我的本地回购中建立新的分支机构,将这些分支机构推到我的远程回购中,并在我的本地回购中的分支机构之间切换,我遇到了一个既令人困惑又非常有趣的属性,我希望有人能对该属性的工作原理提供一些澄清

我正在处理一个html文件。在我的本地回购协议中,我创建了一个新分支,签出了该分支,并在分支中打开了该文件并进行了一些编辑。然后,我回到我的另一个分支,打开了同一个文件,正如预期的那样,我所做的编辑不在那里,因为它们存在于另一个分支上,而不是我当前所在的分支上。我从概念上理解这一点,即您对一个分支上的文件进行更改,显然这些更改不会出现在另一个分支上,除非您合并它们。但是,我感到困惑的是,在我的机器上,我只有一份这个文件的副本。。。但不知何故,这个文件在我的机器上同时以两个不同的版本存在。这是一个属性,我再一次从抽象的角度理解它,但是我希望能解释一下文件是如何拥有这个属性的

在我的机器上,我只有这个文件的一个副本

但你没有

Git会记住文件的所有版本,Git add会将快照添加到存储库中,并根据需要将您希望在文件系统中看到的快照放在预期的位置

在我的机器上,我只有这个文件的一个副本

但你没有

Git会记住文件的所有版本Git add会将快照添加到存储库中,并根据需要将您希望在文件系统中看到的快照放在预期位置。

因为,您的工作树或工作树只有一个文件副本。Git在其提交中拥有文件的每个副本:每个提交都有每个文件的一个副本。副本是以一种巧妙的方式进行重复数据消除的,这取决于这样一个事实:Git中的任何内容一旦提交就永远无法更改。因此,提交中的文件一直处于冻结状态,在提交的其余部分中,除了文件之外还有一些内容

更准确地说,每次提交都有一个完整的文件快照,这些文件是您在提交时告诉Git放入该提交中的。或者,如果提交的不是您,请插入其他参与者作为调用Git命令的人

这些提交的文件位于存储库中,包含在每个提交中。但是您在工作树中看到并使用的文件根本不在Git中。我认为,从概念上讲,如果您将工作树文件视为您的文件,这会有所帮助:您负责这些文件。git负责提交中的文件和每个提交快照中的文件,这些文件是在运行git提交时创建的

一旦你意识到Git只是从提交中复制了它的一组文件,在你的文件之上,很多事情都会发生。剩下的相当令人惊讶的是,在一个重要的方面,分支并不重要。Git中最重要的是提交。诸如master或develope之类的分支名称只是查找特定提交的一种方法

当您克隆存储库,或使用git push或git fetch时,1您要求您的git连接到其他git。因此,每个存储库都有多个副本。这些存储库通过复制它们来共享提交,但它们根本不需要共享它们的分支名称。没关系,因为重要的是提交,而不是分支名称

1不要认为git pull是git fetch的反面,因为它不是。把“抓取”和“推”看作是两个相反的概念。好吧,好吧:Git在这里找到对立面的时候,他们就离得很近了。Mercurial在Mercurial中使用了这个特殊的术语,pull做的和Git中fetch做的一样,Git只是有点倒退

分支名称并不重要,除了人类 提交的真实名称是其散列ID。要查看某个提交的散列ID,请使用git rev parse,其任务是将名称转换为散列ID:2

$git rev解析主机 b994622632154fc3b17fb40a38819ad954a5fb88 $git rev解析来源/维护 af6b65d45ef179ed52087e80cb089f6b2349f4ec 这些散列ID是Git查找提交的方式,至少是我们人类现在可能关心的一些特定提交。名称master是一个分支名称,而origin/maint或origin/master不是分支名称。但所有这些名称都找到了一些提交。有时,多个名称会定位同一个提交:

$git rev解析源代码/主代码 b994622632154fc3b17fb40a38819ad954a5fb88 这是我给我主人的哈希ID。这不是巧合:我克隆的Git存储库有一个主分支, 提交,它涉及Git的索引。不过,我不会在这个答案中详细说明

5技术上,如果我们知道:

快照中将包含哪些源文件及其名称和内容; 您将为Git提供哪些元数据—您的姓名、电子邮件地址等,以及您将使用的日志消息;和 散列ID H以及您将进行新提交I的确切日期和时间; 然后我们可以预测commit I的实际散列ID。但我们如何预测所有这些呢?所以我们不妨把我看作是随机的

画图表! 我把dev翻到了最上面一行,这样更大的字母K和L就会出现在底部。只要仍然绘制从commit到commit的连接、从J到I的向后链接等,并且只要使用正确的名称标记正确的提交,就可以以任意数量的方式绘制图形。您可以省略一些名称,以及一些提交,就像G之前的提交一样,它们只是将图形弄得乱七八糟

不过,不管你做什么,在纸上、白板上或其他任何地方画一堆图表都是很好的练习。当你这样做时,你会注意到一些事情,比如:

分支名称查找链中的最后一个提交。Git将其称为分支的提示提交。 箭头都是向后的。Git必须从最后开始,并向后工作。 如果一个链的最后一次提交没有名字,Git就找不到它。 了解了这些知识,您就可以很好地了解Git的所有其他奥秘,例如Git merge和Git rebase是如何工作的。

因为,您的工作树或工作树只有一个文件副本。Git在其提交中拥有文件的每个副本:每个提交都有每个文件的一个副本。副本是以一种巧妙的方式进行重复数据消除的,这取决于这样一个事实:Git中的任何内容一旦提交就永远无法更改。因此,提交中的文件一直处于冻结状态,在提交的其余部分中,除了文件之外还有一些内容

更准确地说,每次提交都有一个完整的文件快照,这些文件是您在提交时告诉Git放入该提交中的。或者,如果提交的不是您,请插入其他参与者作为调用Git命令的人

这些提交的文件位于存储库中,包含在每个提交中。但是您在工作树中看到并使用的文件根本不在Git中。我认为,从概念上讲,如果您将工作树文件视为您的文件,这会有所帮助:您负责这些文件。git负责提交中的文件和每个提交快照中的文件,这些文件是在运行git提交时创建的

一旦你意识到Git只是从提交中复制了它的一组文件,在你的文件之上,很多事情都会发生。剩下的相当令人惊讶的是,在一个重要的方面,分支并不重要。Git中最重要的是提交。诸如master或develope之类的分支名称只是查找特定提交的一种方法

当您克隆存储库,或使用git push或git fetch时,1您要求您的git连接到其他git。因此,每个存储库都有多个副本。这些存储库通过复制它们来共享提交,但它们根本不需要共享它们的分支名称。没关系,因为重要的是提交,而不是分支名称

1不要认为git pull是git fetch的反面,因为它不是。把“抓取”和“推”看作是两个相反的概念。好吧,好吧:Git在这里找到对立面的时候,他们就离得很近了。Mercurial在Mercurial中使用了这个特殊的术语,pull做的和Git中fetch做的一样,Git只是有点倒退

分支名称并不重要,除了人类 提交的真实名称是其散列ID。要查看某个提交的散列ID,请使用git rev parse,其任务是将名称转换为散列ID:2

$git rev解析主机 b994622632154fc3b17fb40a38819ad954a5fb88 $git rev解析来源/维护 af6b65d45ef179ed52087e80cb089f6b2349f4ec 这些散列ID是Git查找提交的方式,至少是我们人类现在可能关心的一些特定提交。名称master是一个分支名称,而origin/maint或origin/master不是分支名称。但所有这些名称都找到了一些提交。有时,多个名称会定位同一个提交:

$git rev解析源代码/主代码 b994622632154fc3b17fb40a38819ad954a5fb88 这是我给我主人的哈希ID。这绝非巧合:我克隆的Git存储库有一个主分支,上次我与该Git存储库交谈时——几周前,他们将其主分支设置为记住提交b994622632154fc3b17fb40a38819ad954a5fb88。所以我告诉我的Git,它也应该记住我名下的b994622632154fc3b17fb40a38819ad954a5fb88

每当您在Git中使用分支名称时,您都在告诉Git:记住这个n下的提交哈希ID >然后我们可以预测commit I的实际散列ID。但我们如何预测所有这些呢?所以我们不妨把我看作是随机的

画图表! 我把dev翻到了最上面一行,这样更大的字母K和L就会出现在底部。只要仍然绘制从commit到commit的连接、从J到I的向后链接等,并且只要使用正确的名称标记正确的提交,就可以以任意数量的方式绘制图形。您可以省略一些名称,以及一些提交,就像G之前的提交一样,它们只是将图形弄得乱七八糟

不过,不管你做什么,在纸上、白板上或其他任何地方画一堆图表都是很好的练习。当你这样做时,你会注意到一些事情,比如:

分支名称查找链中的最后一个提交。Git将其称为分支的提示提交。 箭头都是向后的。Git必须从最后开始,并向后工作。 如果一个链的最后一次提交没有名字,Git就找不到它。
了解了这些知识,您就可以很好地了解Git的所有其他奥秘,例如Git merge和Git rebase是如何工作的。

您可能会发现,和/或在和我的最爱中找到有用的内容,和/或在和我的最爱中找到有用的内容,值得指出的是,Git逻辑上存储了每个文件的每个版本,但实际上,它在幕后进行了大量优化。如果它真的存储了每个版本的完整副本,那就不切实际了。没错,它从完整快照开始,分阶段压缩,廉价的n-prettygood zlib压缩,当它看起来有大赢家可用时,它会用一些工业强度压缩重新打包git,包括从历史中查找增量的范围,不仅仅是以前的版本,也不仅仅是一个文件。值得指出的是,git逻辑上存储每个文件的每个版本,但实际上,它在幕后进行了大量优化。如果它真的存储了每个版本的完整副本,那就不切实际了。没错,它从完整快照开始,分阶段压缩,廉价的n-prettygood zlib压缩,当它看起来有大赢家可用时,它会用一些工业强度压缩重新打包git,包括从历史中寻找增量的大量空间,不仅仅是以前的版本,也不仅仅是一个文件;事实上,当我想到对立面时,我不会想到这一点。我认为git push和git pull是对立的。这准确吗?另外,fetch和pull之间的区别是什么?第二个问题-我发现您确实不喜欢术语branch,了解到分支实际上并不重要这一点非常有趣。但是,这让我感到困惑,因为我认为分支的目的是存储不同于其他提交序列的提交序列。还有,难道不可能创建一个空分支吗?如果是这样的话,空分支基本上只是一个散列数,就像未来提交的空白空间一样吗?第三个问题-您说我们现在可以将特殊名称头附加到任一分支名称上。我们使用哪个名称并不重要,因为两者都表示提交H:我们在工作树中看到的文件无论哪种方式都是相同的。但是我们看到的文件将不一样——我们将在分支A中看到文件副本,如果我们切换到分支B,我们将看到分支B文件副本。对的还是只有在提交后才创建新文件副本?所以分支A上的文件A存在,然后我们创建分支B;此时是否创建了新的文件副本?或者分支B现在只是与文件a关联的一个名称吗?1:Fetch和push是Git的两个相反的名称。Mercurial命令hg pull拼写为git fetch in git,Mercurial命令hg push拼写为git push in git。因此,在Mercurial中,这两个词使用正确。但在Git中,Git pull意味着运行Git fetch,然后运行第二个Git命令。Git push没有第二个Git命令。这就是Git在给这两个词赋予意义时出错的地方,也是fetch而不是pull与push相反的原因。2:这并不是说我不喜欢这个词,因为Git中的词本身是模棱两可的。不同的人用同一个词来表示不同的事物,从而使彼此混淆。一个人会用同一个词来表示三种不同的事物。假设你在一个聚会上,每个人的名字都是布鲁斯。Bruce告诉你Bruce去接Bruce,Bruce和Bruce在Bruce家,但是如果你要找Bruce,Bruce在厨房。谁干了什么?谁在哪里?不,在Git中没有空分支,不管你使用哪种含义;事实上,当我想到对立面时,我不会想到这一点。我认为git push和git pull是
相反。这准确吗?另外,fetch和pull之间的区别是什么?第二个问题-我发现您确实不喜欢术语branch,了解到分支实际上并不重要这一点非常有趣。但是,这让我感到困惑,因为我认为分支的目的是存储不同于其他提交序列的提交序列。还有,难道不可能创建一个空分支吗?如果是这样的话,空分支基本上只是一个散列数,就像未来提交的空白空间一样吗?第三个问题-您说我们现在可以将特殊名称头附加到任一分支名称上。我们使用哪个名称并不重要,因为两者都表示提交H:我们在工作树中看到的文件无论哪种方式都是相同的。但是我们看到的文件将不一样——我们将在分支A中看到文件副本,如果我们切换到分支B,我们将看到分支B文件副本。对的还是只有在提交后才创建新文件副本?所以分支A上的文件A存在,然后我们创建分支B;此时是否创建了新的文件副本?或者分支B现在只是与文件a关联的一个名称吗?1:Fetch和push是Git的两个相反的名称。Mercurial命令hg pull拼写为git fetch in git,Mercurial命令hg push拼写为git push in git。因此,在Mercurial中,这两个词使用正确。但在Git中,Git pull意味着运行Git fetch,然后运行第二个Git命令。Git push没有第二个Git命令。这就是Git在给这两个词赋予意义时出错的地方,也是fetch而不是pull与push相反的原因。2:这并不是说我不喜欢这个词,因为Git中的词本身是模棱两可的。不同的人用同一个词来表示不同的事物,从而使彼此混淆。一个人会用同一个词来表示三种不同的事物。假设你在一个聚会上,每个人的名字都是布鲁斯。Bruce告诉你Bruce去接Bruce,Bruce和Bruce在Bruce家,但是如果你要找Bruce,Bruce在厨房。谁干了什么?谁在哪里?不,在Git中没有空分支,不管您使用哪种含义。
... <-F <-G <-H
... <-F <-G <-H   <--master
A--B--C--D--E--F--G--H   <-- master (HEAD)
...--G--H   <-- master (HEAD)
...--G--H   <-- dev, master (HEAD)
...--G--H   <-- dev (HEAD), master
...--G--H
         \
          I
...--G--H   <-- master
         \
          I   <-- dev (HEAD)
...--G--H   <-- master
         \
          I--J   <-- dev (HEAD)
...--G--H   <-- master, topic (HEAD)
         \
          I--J   <-- dev
          I--J   <-- dev
         /
...--G--H   <-- master
         \
          K--L   <-- topic (HEAD)