代码之家  ›  专栏  ›  技术社区  ›  Emanuele Paolini

未跟踪并同时删除(git)

git
  •  -1
  • Emanuele Paolini  · 技术社区  · 5 年前

    deleted untracked . 例如:

    $ git status base.html
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
        deleted:    base.html
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
        base.html
    
    $ git diff base.html
    $ ls -al base.html
    -rw-rw-r-- 1 crm crm 673 Sep  2  2016 base.html
    $ 
    

    发生什么事了?我该怎么解决这个问题?

    我不想冒删除和重新生成服务器上所有文件的风险。

    0 回复  |  直到 5 年前
        1
  •  1
  •   torek    5 年前

    我不清楚为什么文件显示为“要删除”(注意,它没有被删除) 然而 待删除 相反)但是输出的其余部分是非常正常的:这意味着,不知何故,您已经告诉Git 下一个 你计划做的提交应该忽略这个文件 base.html .

    要解决此问题,请使用上面Git本身显示的建议:

    git reset HEAD base.html
    

    文件现在将不再被标记为“下次提交时将被忽略”。

    (编辑:要对所有文件执行此操作,请考虑使用 git reset HEAD . 如果没有文件名,这会导致 --mixed 使用当前提交重置。)

    您来自Mercurial,它比Git更简单、更易于使用。两者之间有一些很大的区别,而本例中的关键一点与Git有关 指数 . 不过,首先让我们提一下相同的事情:

    • 在Mercurial中,存储在存储库中的文件只是存储在存储库中的文件。这些文件与提交本身一样永久地存储,也就是说,除非您显式地除去提交(或使用 hg commit --amend 回滚上一次提交,然后放入另一个提交,或者删除提交)。

      Git在这里也是一样的:有一个提交数据库(尽管与Mercurial的数据库不同,它的数据库结构不是很好)。这些承诺大多是永久性的,尽管您可以故意放弃它们。在Mercurial你用 hg strip 删除它们;在Git中,您抛弃它们,然后过一段时间,Git会自己获取它们。

    • 在Mercurial,你有一个 工作树 工作树 其中一些提交中的文件已被提取并可供您使用。从中提取文件的提交是 当前提交 rev hg update -r rev ,或者别的什么)。

      在Git中,其工作方式几乎完全相同:您的工作区包含来自当前提交的文件。当前提交被命名为 HEAD . ,尽管你可以使用 @

    • 不是工作树中的所有文件都需要出现在当前提交中。这些是 未跟踪的文件 其中一些可能也是 (通过 .hgignore ). 如果一个未跟踪的文件需要变成一个被跟踪的文件,那么它将进入下一个提交使用 hg add .

      在Git中,这里的机制不同,文件名为 .gitignore git add . 但是,由于底层机制不同,您也可以使用其他命令(这里就是这种情况)。

    在这一点上,您遇到的关键区别是在Mercurial中 工作树本身 是你提议的下一个任务。只需在工作树中更改一些文件,然后 hg status 告诉您文件已修改。下一个 hg commit 从工作树生成新的提交。 1 然而,在Git中 建议的下一次提交 你的工作树。它是Git调用的独立结构 索引 ,或 集结区 或者现在很少有时间 隐藏物 .

    这个东西,这个索引或暂存区域这两个名字指的是同一个东西 将进入下一次提交的每个文件的副本 . 2 Git中的文件是 跟踪 如果且仅当索引中有它的副本。如果你 去除 索引copy不影响任何现有的提交(它不能),也不影响您的工作树(索引不是您的工作树),那么该文件被安排为 遗漏 下一次提交。换句话说,您建议的下一个提交就是索引中的任何内容 马上 .

    这个索引的存在和使用就是为什么在Git中必须保持 git添加 -每次修改一个文件。在Mercurial中,建议的下一个提交 你的工作树,所以如果你修改了你的工作树中的一个文件,你已经更新了建议的下一次提交。在Git中,你必须告诉Git 将我更新的工作树文件复制回您的索引中 git添加 . 现在修改后的文件已经在索引中,可以提交了,所以 现在 建议的下一次提交具有更新的文件。

    在你的特殊情况下 基本.html 从索引中删除了。因此,当将当前提交与索引进行比较时,Git说 基本.html 会被删除,如果你现在提交 . 由于该文件不在索引中,但仍在您的工作树中,Git还表示该文件未跟踪,因为这正是具有未跟踪文件的含义:它不在索引中,而是在您的工作树中。

    所以,您所要做的就是将文件的某个版本复制回索引中。命令 git add base.html 将文件的工作树副本复制回Git的索引中。命令 git reset HEAD base.html 将复制当前提交( 头部 )将文件复制回Git的索引中。如果文件的这两个副本匹配,那么使用哪一个命令都无关紧要:这两个命令都会将文件还原到索引中,然后恢复到索引 git status 什么都不说 基本.html .


    1 这里有一些微妙的诡计 丢失的 Mercurial中的文件,这些文件不会自动删除。您还可以告诉Mercurial不要提交一些更新;这里我只讨论典型的用例。

    2 从技术上讲,索引没有文件的副本,而是对Git内部blob散列ID的引用 git update-index git ls-files --stage 命令,您实际上不需要知道:您可以将索引视为保存完整副本,准备提交。吉特 分享 通过这个底层 BLOB对象 机制,这是Git如何消除重复提交的文件副本而不更改它们。(Mercurial有一个不同的技巧,同样有效。)