我正在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
答案 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
,然后稍后提交G
或H
,但是提交中的箭头始终前后指向其父级。
I
git push
的作用是将您的新提交发送到其他Git存储库。例如,您的git push
使用名称my-R
记住其原始来源 R 的URL。这样就可以运行:
origin
让Git将您的提交$ git push origin second
(假设J
指向second
)推送到保存原始存储库 R 的Git。提交J
指的是提交J
(I
是I
的父母),而J
则指的是I
,因此您的Git也会提供G
和I
的提交。不过,大概是您在G
从存储库 R 中获得了G
本身,因此他们说:我已经有了那个。 / em>因此,您的Git只需将origin
(及其所有文件)和I
(及其所有文件)发送到 R ,这就是其中的第一部分J
可以。
已经发送了提交git push
和I
,您的Git现在要求其Git设置其名称J
来指向提交second
。如果他们还没有J
,则该请求可以创建。如果他们确实有second
,他们将检查以确保您请求将其second
移至second
而不是现在指向的内容是好吧。
假设他们全部接受,并假设他们的J
仍然指向提交master
而不是提交G
,即您的提交{ {1}}在您的 H
上,但您尚未将其发送到 R 放入他们的 {{1 }}-现在他们现在看起来像这样:
H
(如果您将他们的master
发送给他们,并要求他们调整其master
以指向...--F--G <-- master
\
I--J <-- second
,并且如果他们接受了该请求,那么他们的一组提交和分支名称将匹配您的。)
我们早些时候提到,您的工作树(您在其中工作的地方,在存储库 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
会更改他们(无论“他们”位于)的某些文件这一点—正在努力之中。 (或者,当然,他们可以有一个裸仓库,但如果这样,它们就没有 工作树...在这种情况下,您要查看的是什么文件?)>