难以使工作树看起来像索引?

Pro Git解释如下的git reset

概括

reset命令按照特定的顺序覆盖这三棵树,当你告诉它时:

  • 将分支HEAD指向(如果 - --soft ,则停在此处)
  • 使索引看起来像HEAD(除非--hard
  • 使工作目录看起来像索引
  • 我理解的方式是,如果我git reset --hard ,那么我的两个指标,我的工作目录将成为完全像我的头。 所以我继续做下去:

    # make a git repo
    mkdir mygitrepo
    cd mygitrepo
    git init
    
    # init commit
    touch old_file
    git commit -a
    
    # stage a file
    touch staged
    git add staged
    
    # create file that is not staged
    touch unstaged
    

    到目前为止,我的回购看起来像这样:

  • HEAD old_file
  • index old_file +上演
  • working dir old_file + staged + unstaged
  • 现在,如果我运行git reset --hard那么我希望我的回购变成:

  • HEAD old_file
  • index old_file
  • working dir old_file
  • 但我会得到这个:

  • HEAD old_file
  • index old_file
  • working dir old_file + unstaged
  • 我通过显式传递目标参数来做类似的测试,比如git reset --hard target ,而且我得到了类似的结果:staged文件全部没了,但未归档的文件在git reset --hard后仍然存在。

    有人可以解释我是否误解了有关git reset任何内容?


    正如“撤销更改”中所述

    git clean命令通常与git reset --hard一起执行。
    请记住,重置仅影响跟踪的文件,因此需要单独的命令清理未跟踪的文件

    结合起来,这两个命令可让您将工作目录返回到特定提交的确切状态。

    --hard选项记录为:

    重置索引和工作树。
    放弃自<commit>以来对工作树中跟踪文件所做的任何更改。


    早在2008年就已经讨论过了。
    Linux Torvalds简单地说:

    如果你习惯做“ git checkout -f ”或“ git reset --hard ”,那么这两个检查(*)都会被忽略。 毕竟,你要求强制切换。

    (*检查=脏文件或未跟踪文件)

    至少在第二种情况下, 我认为会发生的事情是git不会删除它不知道的文件,所以你会留下一个“烂”字


    虽然增加了文件,即使从未提交过(即全新的),仍然会被git reset --hard删除,如2008年所见:

    我实际上意外删除了数百个新添加的文件,昨天就这样做了。

    我的问题是为什么“ git reset --hard ”不能为新添加的跟踪文件制作特殊情况?
    毕竟,“ git status ”知道它们是“新文件”,而“ git reset --hard ”可以意识到,将它们从地球表面抹去并不是最有用的可能。

    作为一个建议,在git reset --hardgit read-tree -m HEADgit rm --cached <file list> git reset --hard会帮助保留这些新文件(将它们从索引中删除)

    Junio C. Hamano stil认为:

    当HEAD中不存在路径但在其他情况下在索引中存在路径时,您会想要“ reset --hard ”来移除该路径
    这是我的经验,往往不是它是可取的。

    (比如摆脱冲突合并中的残酷)

    请注意,在这种情况下, git fsck仍然可以帮助恢复这些被删除的新文件。


    Git总会遵循一条重要规则(除非明确告知不要这样做): 不要触摸未跟踪的文件

    使用默认功能,Git不会执行任何会导致未跟踪文件数据丢失的操作。 这是因为来自未跟踪文件的信息永远无法通过Git恢复:它不会“知道”它们,因此它不会将其内容存储到任何地方,因此对它们进行任何操作都非常危险。 所以它不会触及它们。

    这也是为什么如果分支包含具有相同路径的跟踪文件,Git不会让您切换到未跟踪文件的分支。 因为这样做会覆盖未跟踪的文件,将其替换为来自该分支的文件,但无法恢复未跟踪的文件。 因此,Git将不会切换分支,要求您首先处理未跟踪的文件(这可能意味着将其重命名,将其添加到Git中,甚至删除它)。

    所以当你做git reset ,你只会影响索引。 而git reset --hard会影响索引和工作目录。 而对于Git,工作目录只包含跟踪的文件。 这就是为什么git reset --hard既不会删除未记录的文件,也不会删除位于.gitignore文件。 Git不会“知道”它们,所以它不会触及它们。

    如果你想删除未跟踪的文件,有一个命令负责:git clean。 该命令附带了不同的参数组合,它们都执行各种不同的作业。

    默认情况下, git clean -f会删除未跟踪的文件,但保留忽略的文件。 如果你还想删除被忽略的文件,你可以使用git clean -x -f 。 请注意,您通常必须始终指定-f (或--force )作为git clean来执行任何操作。 这只是一个额外的安全机制,以确保你知道你在做什么。 您可以使用-n来执行干运行,并只显示Git将删除的文件。 这可以很容易地避免问题。

    链接地址: http://www.djcxy.com/p/23509.html

    上一篇: hard doesn't make the working tree look like index?

    下一篇: How to reverse apply a stash that with conflict?