新文件未出现在GIT存储库中

时间:2018-08-21 18:54:48

标签: git visual-studio-2017 bitbucket

我正在Visual Studio(也是命令行)中学习带位桶扩展的GIT。 当我更改文件Program.cs时,一切正常,我可以看到存储库中的更改。接下来,我在新文件,阶段,提交和推送中创建新类。然后,我可以在存储库上看到提交消息,几秒钟前关于提交的消息,但是没有我的新文件。我也尝试使用git add .在cmd中执行此操作,但其作用相同。

有人有类似情况或知道该怎么办吗?

编辑:

  

git状态

On branch second
Your branch is up to date with 'origin/second'.

nothing to commit, working tree clean
  

git ls文件

.gitattributes
.gitignore
ConsoleApp1/ConsoleApp1.sln
ConsoleApp1/ConsoleApp1/ConsoleApp1.csproj
ConsoleApp1/ConsoleApp1/Program.cs
ConsoleApp1/ConsoleApp1/Test.cs

1 个答案:

答案 0 :(得分:2)

我不清楚您如何查看其他存储库中的提交,因此请在此处稍加容忍。

首先,请记住,使用Git时,它会创建许多存储库副本。让我们从一个仅在Bitbucket上存在的单一存储库 R 开始。您可能会在命令行中运行:

$ git clone https://bitbucket.com/path/to/R.git my-R

(其中$是bash shell提示符)。这将在您的计算机上创建一个名为my-R的全新Git存储库。现在,您可以导航到该目录/文件夹:

$ cd my-R

,您将拥有大量文件。 Git将此称为您的工作树,因为它是您进行工作的地方。还有一个名为.git的隐藏目录/文件夹,其中包含实际的存储库本身。

在隐藏的.git之外,您可以查看的文件不是Git使用的文件。 Git中的文件以一种特殊的,压缩的,仅Git的格式存储,只能由Git本身使用。用于将文件获取到工作树中的获取的动作动词为git checkout。运行git clone时,git clone的最后一步是git checkout,通常是git checkout master

分支名称与提交

克隆本身是每个文件的每个修订版本的完整副本。因此,现在不仅在Bitbucket上存在存储库 R ,而且在您自己的计算机上还有 R 的另一个完整副本。在处理文件并进行提交时,您将在<{1}}中的 R 副本中添加 new 提交。这些提交在其他任何地方都不可用(尚未!):它们未发布。

分支名称也是如此。如果在存储库中创建新的分支名称,则该分支名称将存在于您的存储库中。不过,分支名称和提交之间有一些关键区别。

提交的实际名称是哈希ID。您可能会在my-R输出中看到这些哈希ID:

git log

哈希ID大,丑陋,看似随机,并且人类无法使用。它们必须像这样大而丑陋,因为Git保证每次提交都会获得一个唯一的唯一哈希ID,永远不要重复使用。因此,Git为我们提供了使用$ git log commit b7bd9486b055c3f967a870311e704e3bb0654e4f Author: ... master之类的名称来命名提交的功能。

关于这些名称的棘手的事情是,每个名称都标识一个准确的提交。但是我们希望提交在提交的系列中一​​个接一个。因此,Git使每个提交都记住其前身或 parent 提交。 Git将此称为父级的子级。大多数提交都有一个父母(一个前任)和一个孩子(一个后继),这些构成了链:

second

大写字母代表哈希ID。

分支名称(例如... <-F <-G <-H ... master)只是记住链中的 last 提交。如果我们从左(较早)向右(较晚)绘制提交,则所有内部箭头都指向后。因此,我们应该将名称放在最右边,向左指向链的 tip commit

second

我已停止绘制内部箭头,因为提交内的箭头永远无法更改。实际上,任何提交都不会改变。名称​​ (此处的...--F--G--H <-- master \ I--J <-- second master可以更改,并且始终会更改。他们指向一次提交second,然后稍后提交GH,但是提交中的箭头始终前后指向其父级。

I

git push的作用是将您的新提交发送到其他Git存储库。例如,您的git push使用名称my-R记住其原始来源 R 的URL。这样就可以运行:

origin

让Git将您的提交$ git push origin second (假设J指向second)推送到保存原始存储库 R 的Git。提交J指的是提交JII的父母),而J则指的是I,因此您的Git也会提供GI的提交。不过,大概是您在G从存储库 R 中获得了G本身,因此他们说:我已经有了那个。 / em>因此,您的Git只需将origin(及其所有文件)和I(及其所有文件)发送到 R ,这就是其中的第一部分J可以。

已经发送了提交git pushI,您的Git现在要求其Git设置名称J来指向提交second 。如果他们还没有J,则该请求可以创建。如果他们确实有second,他们将检查以确保您请求将其second移至second而不是现在指向的内容是好吧。

假设他们全部接受,并假设他们的J仍然指向提交master而不是提交G,即您的提交{ {1}}在您的 H上,但您尚未将其发送到 R 放入他们的 {{1 }}-现在他们现在看起来像这样:

H

(如果您将他们的master发送给他们,并要求他们调整其master以指向...--F--G <-- master \ I--J <-- second ,并且如果他们接受了该请求,那么他们的一组提交和分支名称将匹配您的。)

所有这些都描述了 commits ,但是他们的工作树呢?

我们早些时候提到,您的工作树(您在其中工作的地方,在存储库 R H副本中)是Git创建的

他们的工作树如何?也许他们甚至没有一个! Git支持所谓的裸存储库,裸存储库非常简单,就是没有工作树的存储库。这些存在的原因很简单:当有人将您推送到您已经签出且正在处理的分支推入master时该怎么办并不明显。如果您正处于更改或创建H文件的过程中,而其他人又在其中推送了一个带有my-R文件的提交,那么您正在处理的提交会发生什么?

(答案是,您的Git通常首先只是拒绝该请求。这样,Git不必弄清楚该文件应该怎么做。因此,裸仓库没有工作树,因此也没有检查-文件的副本,因此无需担心破坏文件。)

还请记住,您的分支机构-您的分支机构名称-是您的 ,而他们的分支机构是他们的

使用git push时,您发送 commits 和一个请求其他Git来更新分支名称的请求。他们可以接受或拒绝该请求。提交本身由哈希ID标识,每个提交都有自己的唯一哈希ID,并保证永远与其他所有提交哈希ID不同。 (这就是Git判断新提交的方式。)但是,如果您使用他们已经拥有的名称,并要求他们设置名称,则要求他们设置名称。 / p>

当您使用Test.cs时,您将颠倒此过程:您的Git调用了他们的Git,并从他们中获得了 ,而他们没有的任何新提交。为避免弄乱您的分支名称,您的Git通过重命名分支名称来保存分支名称到提示提交的映射:它们的Test.cs成为您的分支名称git push,他们的第二个就成为您的git fetch

因此,在您的 Git中,您通过比较master来判断他们的origin/master是否与您的origin/second相匹配的方式-您的Git对他们的{ {1}}-与您的second相匹配。如果是这样,您会收到消息:

second

这就是您在这里看到的。这意味着他们确实拥有您的最新提交,包括所有文件。如果您没有在其存储库中 see 查看文件,则仅表示其工作树与该特定提交无关。可能您需要登录到他们的计算机,导航到他们的存储库,然后运行origin/second(假设他们有一个非裸露的存储库)。

但是请记住,一旦您这样做,他们可能会开始拒绝origin/second操作,因为现在他们的Git不得不担心您的second会更改他们(无论“他们”位于)的某些文件这一点—正在努力之中。 (或者,当然,他们可以有一个裸仓库,但如果这样,它们就没有 工作树...在这种情况下,您要查看的是什么文件?)