“肮脏”和“未承诺的变更”是什么意思?

时间:2019-01-25 00:40:10

标签: git

当说工作树目录脏或有未提交的更改时,是否表示某些跟踪文件有未提交的更改?它包括未跟踪的文件吗?

相同的问题,当说索引变脏或未提交更改时。

肮脏或未承诺的更改是否意味着相同?肮脏仅适用于工作树目录而不适用于索引吗?未提交的更改是否同时适用于工作树目录和索引?

例如,“您只能git stash pop进入干净的工作目录。” git stash pop是否要求索引干净或没有未提交的更改? git push和其他用于更新工作目录和/或索引的git命令呢?

谢谢。

2 个答案:

答案 0 :(得分:1)

他们指的是工作目录中有未提交的更改。

您可以使用git diff HEADgit status来查询工作目录中当前正在发生的事情。

如果您不关心先前尚未提交的文件,请使用git diff HEAD,否则我更喜欢git status

我已经在一个干净的目录中运行了这两个命令。结果请参见下文。

C:\Dev\dogs-api>git status
On branch bugfix/lowercase
Your branch is up-to-date with 'origin/bugfix/lowercase'.
nothing to commit, working directory clean

C:\Dev\dogs-api>git diff HEAD

C:\Dev\dogs-api>

现在,我将在分支上进行一些工作,以修复代码中有关小写字符串的错误。我已经添加了文件并修改了另一个文件,但是还没有将文件添加到舞台上。

C:\Dev\identity-dog-api>git status
On branch bugfix/lowercase
Your branch is up-to-date with 'origin/bugfix/lowercase'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   src/main/java/au/com/api/model/request/newUntrackedClass.java

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/main/java/au/com/api/model/request/Distribution.java


C:\Dev\identity-dog-api>git diff HEAD
diff --git a/src/main/java/au/com/api/model/request/Distribution.java b/src/main/java/au/com/api/model/request/Distribution.java
index 770cec4..f1e17a6 100644
--- a/src/main/java/au/com/api/model/request/Distribution.java
+++ b/src/main/java/au/com/api/model/request/Distribution.java
@@ -8,7 +8,7 @@ public class Distribution {

     @XmlElement(name = "XYS")
     public dogName getDogName() {
-        return dog;
+        return dogName; //newVarLine()
     }

     public void setDogName(String dogname) {
diff --git a/src/main/java/au/com/api/model/request/newUntrackedClass.java b/src/main/java/au/com/api/model/request/newUntrackedClass.java
new file mode 100644
index 0000000..f21156d
--- /dev/null
+++ b/src/main/java/au/com/dog/api/model/request/newUntrackedClass.java
@@ -0,0 +1,4 @@
+package au.com.dogs.api.model.request;
+
+public class newUntrackedClass {
+}

C:\Dev\identity-dog-api>

现在,我已经进行了一些更改,可以使用git stash存储这些更改。完成此操作后,我将进行其他一些更改,并说明您可以在肮脏的工作目录上运行这些命令。

如果存在冲突,则必须像解决两个分支之间的冲突那样解决这些冲突。

这看起来像。

C:\Dev\identity-dog-api>git stash pop
Auto-merging src/test/java/au/com/api/service/TokenIssuerUnitTest.java
CONFLICT (content): Merge conflict in src/test/java/au/com/api/unittest.java
Auto-merging src/main/java/au/com/api/web/rest/validation/ValidationUtils.java
Auto-merging src/main/java/au/com/api/web/rest/TokenController.java
CONFLICT (content): Merge conflict in src/main/java/au/com/api/web/rest/TokenController.java
Auto-merging src/main/java/au/com/api/service/TokenIssuer.java
CONFLICT (content): Merge conflict in src/main/java/au/com/api/service/TokenIssuer.java
Auto-merging src/main/java/au/com/api/service/Service.java

答案 1 :(得分:0)

我可能不得不稍后再编辑此内容,以解决git stash的许多细节(但有很多!),但是让我从这部分的答案开始:

  

当说工作树目录脏或有未提交的更改时,是否表示某些跟踪文件有未提交的更改?它包括未跟踪的文件吗?

正如我在评论中所述,肮脏一词是故意不精确的,因此我们可以传达一个普遍的想法-有些东西您没有保存在某个地方-没有具体说明什么,在哪里,如何等等。短语未提交的更改未提交的更改更精确,但仍缺少一些内容。让我们举一个具体的例子,例如一个名为README.txt的文件:

$ cat README.txt
I am a readme file
with two lines of text
$ 

此文件中的更改是什么?谁能回答这个问题?就像是说:今天的最高预报是60,那么这是多少摄氏度?好吧,在我们可以说60摄氏度多少之前,我们必须知道: 比什么更温暖或更冷?

状态与变化

要查看60摄氏度是多少,我们需要知道应该比较什么温度!假设问题是,今天的最高气温预计为60.昨天是60,一周是55。今天要比昨天温暖或寒冷多少,今天要比上周温暖多少?现在我们有一个 proper 问题,我们可以说与昨天没什么不同,但比上周温暖了5个。

如果我们有一个状态(“外面是60”或“ README.txt里面有这些行”),我们想要一个更改(“它是例如,“比上周暖和/凉快”或“第二行用来说一些文本,现在又说了两行文本”,我们还必须具有< em> previous 状态,以便我们可以减去。如果从今天的状态中减去昨天或上周的状态,则零。否则,无论发生什么变化,就是变化。

Git保持状态,不会改变

通常,Git是该规则的特定例外,我们将在这里不再赘述。它非常注重状态,并且以提交为中心。对于后者的示例,分支名称仅包含一个提交哈希ID。标签名称也是如此。两者之间的主要区别在于,标记名称可以始终标识一个特定的提交,或者至少可以这样做。标签永远都不会移动,而分支名称标识了我们应视为分支的 last 提交。

每个提交都由其自己的唯一哈希ID标识,其中包含一些元数据:创建者(名称和电子邮件地址)以及时间;他们关于为什么的日志消息; parent 提交的哈希ID;以及一整套文件,这些文件将一直冻结(只要提交本身存在就一直冻结),并压缩为特殊的仅Git格式。只要提交本身继续存在,您就可以始终以该格式取回所有这些文件。

压缩和只读形式对于存储来说很好,但是对于完成任何工作都没有用,因此Git必须能够将文件从深度冻结中取出并解冻。进行解压缩,然后将它们转换为有用且可写的普通文件。这些普通文件进入您的工作树(或工作树或此短语的多个变体)。在这里,您可以使用/处理它们。为此,您告诉Git:获取具有哈希ID H 的提交,而 H 现在是您当前的提交,并且您有 H 继续工作。通常,您使用git checkout mastergit checkout develop进行此操作,然后从 latest 提交中获取文件,其哈希ID存储在分支中。

因为您可以更改工作树中的文件,所以它们可能与冻结到当前提交中的文件有所不同。因此,我们可以将README.txt之类的文件的工作树副本与冻结的副本进行比较(并经过Git修饰(Git只需在内部将其再次扩展))。从工作树版本中减去冻结版本,向我们/ Git显示了更改(如果有的话)。

大多数版本控制系统都在这里停止,每个文件有两个副本:提交时冻结的一个副本,以及工作树中的常规副本。但是,Git在这两个之间插入一个第三副本。第三份副本进入Git调用的内容,分别是 index 登台区域缓存,具体取决于谁/哪一部分Git正在打电话。

第三个副本是每个文件的完整副本,就像以前一样。它以特殊的Git格式存储。但是,已提交副本和索引副本之间的主要区别在于索引副本没有完全冻结。 1 更容易冻结,或者有些肮脏。要替换名为 file 的某些文件的索引副本,请运行git add file。 Git修改了 file 中的内容,并将结果填充到索引中,准备好进入您将要进行的下一次提交

最后,这意味着当您进行当前提交时,每个文件都有三个副本。 Git让您命名所有三个:

  • HEAD:README.txt是冻结的,仅限Git的提交副本。没有什么可以改变的,即使它与我们可以比较的东西不同,它也永远不会“肮脏”。

  • :README.txt是索引副本-仍仅是Git且大多已冻结,可以进入 next 提交,但可以随时替换。我们可以将其与HEAD副本与工作树副本进行比较。它可以与任何一个都不相同,在两种情况下,我们都可以将 something 称为“脏”。通过将:README.txtHEAD:README.txt进行比较,我们可以判断这两个是否特别不同。

  • 最后,README.txt是一个普通文件。我们可以将 it HEAD副本或索引副本进行比较,但是据Git所知,它可以随时被任何人或任何事物替换(或就地更改) 。 2 如果与 HEAD:README.txt:README.txt不同,我们可以粗略地说它是“脏的”,并通过将其与一个进行比较来明确或其他。


1 从技术上讲,它只是一个带有Git哈希ID的 blob对象,这意味着它实际上已被冻结。但是,您可以随时用新的冻结副本替换它。如果您从不提交这些索引副本之一,则只要内容本身与任何以前或将来保存的内容不同,它都可能成为未引用对象,Git最终会< em>垃圾收集-但这是一堆您不需要知道的术语。对于使用Git,只需将索引副本视为可替换的(因为它是可替换的),而不必担心此替换过程的确切细节。

2 您的操作系统可能允许您或要求您限制可以修改它的人,时间和方式,但这完全超出了Git本身的权限。


定义已跟踪未跟踪

Git经常谈论未跟踪的文件,为了精确起见,我们再次需要一个正确的定义。当且仅当文件现在在索引中的 中时,该文件才会被跟踪

您可以将新文件放入索引:git add newfile从工作树中将newfile复制到索引中,如果没有,则将{{1} },现在有。您还可以从索引中取出文件 :newfile删除了git rm newfile,同时也删除了newfile

如果您现在运行:newfile ,Git将打包索引中的立即,并将其放入提交的冻结文件中。也就是说,索引具有所有文件,所有文件都经过Git修饰,泥泞且可以冻结,这就是git commit如此之快的原因:它只是将索引副本冻结到新的提交中。因此,跟踪的文件是索引中的文件。

只要提交存在,就存在提交中的文件,因为提交是冻结的。索引中的文件仅存在于索引中。从git commitgit checkout master从一个提交移到另一个提交,将向索引中添加文件,从索引中删除文件 ,并在需要时/ if /替换索引中的 文件,以使其成为当前提交。这还会将文件复制到您的工作树中,或将其从工作树中删除,以便您的工作树中包含(未冻结和未Git化的)文件供您使用。

但是您可以随时在工作树中创建自己的文件,并将它们添加到索引中。每当执行此操作时,您都将拥有未跟踪的文件。 Git通常会对未跟踪的文件进行尽可能少的处理,除非不断向您抱怨它们未被跟踪。

最后,我们可以解决突出显示的问题

让我们再次把它放在这里:

  

当说工作树目录脏或有未提交的更改时,是否表示某些跟踪文件有未提交的更改?它包括未跟踪的文件吗?

制作新存储时,除使用git checkout branchgit stash或}时,--include-untracked命令几乎不会抱怨,也不会处理未跟踪的文件。 --all。因此,使用git stash savegit stash push的常规(无额外标志),任何未跟踪的文件的状态都是无关紧要的。很难说这类文件本身是“干净的”还是“脏的”,因为首先没有明显的可比性。

因此,在这种情况下,我们最需要关注的是跟踪的文件-索引中的文件。尽管这里有一个极端的情况,但我们应该先来看一下。假设当前提交有一个名为yuck的文件,我们运行:

git rm yuck

文件yuck现在已从索引和工作树中消失。文件yuck甚至不存在。 (它是否未被跟踪?这是一个很好的哲学问题;对于从未存在,从未提交过任何文件且不在索引和工作树中的文件asdf呢,那也是未被跟踪的吗?Git很好。不过,具体的答案是:只要工作树中也不存在,它就不是未跟踪的文件。)

但是,如果我们将HEAD与索引进行比较,就会发现其中有一个已删除文件git status命令为我们运行该比较,并告诉我们已准备好删除。因此,这又是我们松散的 dirty 词,在这种情况下,我们将索引称为“脏”,因为它与HEAD提交不同。

因此,这是我们的第一句话:如果将HEAD与索引进行比较,我们还将看到其他所有不同的文件。如果有任何不同,则索引(尚未提交)肯定具有未提交的更改。我们也可以宽松地称它为肮脏。

类似地,这使我们有了第二个底线:我们将对索引与工作树进行第二次比较,同时完全不关注所有未跟踪的文件-工作树中的所有文件索引中的没有git status命令也进行第二次比较,并列出此处所有不同的文件。如果任何文件不同,则工作树具有未提交的更改,我们将其称为脏文件。

请注意,git stash本身使用两个单独的比较:HEAD -vs-index和index-vs-work-tree。这是git status运行的两个相同比较。他们告诉我们所有我们需要了解的大多数目的。有些人(而不是git stash)喜欢进行第三次比较,HEAD-vs-work-tree(忽略工作树中不在HEAD中的文件),并且如果有任何区别,请致电。但是您可以证明,如果第三次比较会显示出一些差异,那么git statusgit stash所做的两个比较中的至少一个也会显示出一些差异。 (尝试做为练习。)因此,两个比较就足够了,这就是git stash在这里使用的方式。