【问题标题】:GIT checkout except one foldergit checkout 除了一个文件夹
【发布时间】:2015-11-26 08:25:57
【问题描述】:

我想签出到其他分支或以前的提交,但我想保留一个文件夹相同的文件(而不是签出文件夹)。

我希望该文件夹将显示在git status 中,因此我现在可以将此文件夹添加到索引中。

例如,我有一个带有node_modules 的文件夹。我希望该文件夹包含在我的所有提交中(我知道大多数人更喜欢 .gitignore node_modules 文件夹)。但是当我移动到其他提交或检查其他分支时,我希望git 不会触及node_modules 文件夹。

有可能吗?

【问题讨论】:

    标签: git git-checkout


    【解决方案1】:

    您可以使用sparse checkoutnode_modules 目录的已提交内容从工作树中排除。正如文档所说:

    “稀疏检出”允许稀疏地填充工作目录。它使用skip-worktree 位告诉 Git 工作目录中的文件是否值得查看。

    这里是你如何使用它。首先,启用sparseCheckout 选项:

    git config core.sparseCheckout true
    

    然后,在.git/info/sparse-checkout 文件中添加node_modules 路径作为否定

    echo -e "/*\n!node_modules" >> .git/info/sparse-checkout
    

    这将创建一个名为 sparse-checkout 的文件,其中包含:

    /*
    !node_modules
    

    这实际上意味着忽略 node_modules 在将提交的树读入工作目录时目录

    如果您以后想再次包含node_modules 目录(即从其文件中删除skip-worktree bit),您必须修改sparse-checkout 文件以仅包含/*——即“包含所有路径”——并使用git read-tree 更新您的工作目录:

    echo "/*" > .git/info/sparse-checkout
    git read-tree -mu HEAD
    

    然后,您可以通过将其配置变量设置为 false 来完全禁用稀疏结帐:

    git config core.sparseCheckout false
    

    请注意,sparse checkout 最初是在 Git 1.7.0 中引入的。

    【讨论】:

    • 谢谢!只是为了确认。如果有一天,我会从sparse-checkout文件中删除node_modules,我可以正常回到过去,看看它过去包含什么吗? (我看了你发的链接,但我不明白这是什么意思skip-worktree bit...
    • 是的,你可以。我更新了我的答案,包括如何重新引入 node_modules 目录并禁用稀疏结帐。
    • 非常有趣。我将不得不检查它(不是 git checkout),我需要测试它:)
    • 澄清一点,这对单个文件名或目录名的工作方式与对目录名的工作方式相同
    • 对于echo 命令,也许应该使用单引号?我不确定是责怪 ZSH、Ember 还是某种组合,但是当我执行 echo "/*\n!node_modules" 时,我的 shell 扩展会导致 echo "/*\nnode_modules/.bin/ember -v"
    【解决方案2】:

    我从我要签出的分支中签出了整个代码

    # assume we want the `components` folder on my-branch to follow us
    
    # first checkout your code to (my-new-branch) for ex.
    git checkout -b my-new-branch
    
    # now i'm on my-new-branch (but it doesn't have the components from my-branch :| )
    
    # delete ./components
    rm -rf ./components 
    
    # replace it with the one on my-branch :)
    git checkout my-branch -- ./components 
    

    祝你好运……

    【讨论】:

      【解决方案3】:

      read-tree sparse checkout 的替代方法是命令 git sparse-checkout 在锥形模式 (presented here)

      使用 Git 2.34(2021 年第四季度),在锥模式下,sparse-index 代码路径学会了删除稀疏锥外的忽略文件(如构建工件),从而允许删除稀疏锥外的整个目录,即当稀疏模式发生变化时特别有用。

      commit 716f68e(2021 年 8 月 10 日)Junio C Hamano (gitster)
      请参阅commit 55dfcf9commit ce7a9f0commit 77efbb3commit 02155c8commit 8a96b9dcommit 5dc1675commit 72d84eacommit e27eab4commit 522d3ce(2021 年 9 月 8 日)@98 sup>(2021 年 9 月 20 日由 Junio C Hamano -- gitster --commit dc89c34 中合并)

      sparse-checkout: 清除跟踪的稀疏目录

      签字人:Derrick Stolee
      审核人:Elijah Newren

      当使用锥形模式更改稀疏签出的范围时,我们可能会有一些被跟踪的目录超出范围。
      当前逻辑从这些目录中删除跟踪的文件,但将忽略的文件保留在这些目录中。
      对于那些向 Git 提供输入并说他们不再需要这些目录的用户来说,这有点出乎意料。

      这是锥形模式模式类型的新内容:用户明确表示“我想要这些目录,那些目录。”典型的稀疏检出模式更普遍地适用于“我想要具有这些模式的文件”,因此将被忽略的文件保持原样是很自然的。
      这种对锥形模式目录的关注为我们提供了改变行为的机会。

      将这些被忽略的文件留在稀疏目录中会导致无法在稀疏索引中获得性能优势。
      当我们跟踪这些目录时,我们需要知道这些文件是否被忽略,这可能取决于稀疏目录中的跟踪 .gitignore 文件。
      这取决于文件的索引版本,因此必须扩展稀疏目录。

      在删除这些目录之前,我们必须特别注意在这些目录中查找未被跟踪、未被忽略的文件。
      我们不想删除用户在这些目录中所做的任何有意义的工作,并且可能忘记在切换稀疏签出定义之前添加和提交。
      由于那些未跟踪的文件可能是生成忽略的构建输出的代码文件,因此在这种情况下也不要从这些目录中删除任何被忽略的文件。
      用户可以通过重置他们的稀疏检出定义以包括该目录来恢复他们的状态并继续。
      或者,他们可以看到显示的警告并自行删除目录以恢复他们期望的性能。

      通过在更改范围时删除稀疏目录(或运行 'git sparse-checkout'(man) reapply),我们重新获得了这些性能优势,就像存储库处于干净状态一样。

      由于这些被忽略的文件经常是来自 IDE 的构建输出或帮助文件,因此用户应该不需要这些文件,因为跟踪的文件已被删除。
      如果跟踪的文件重新出现,那么它们的时间戳将比构建工件更新,因此无论如何都需要重新生成工件。

      使用稀疏索引作为数据结构,以便找到可以安全删除的稀疏目录。
      如果之前已满,则将索引重新扩展为完整的。

      git sparse-checkout 现在包含在其man page 中:

      在锥形模式下更改稀疏结帐模式时,Git 将检查每个 不在稀疏结帐锥内的跟踪目录,以查看它是否 包含任何未跟踪的文件。如果所有这些文件由于 .gitignore 模式,则目录将被删除。
      如果任何一个 该目录中未跟踪的文件不会被忽略,因此不会删除 发生在该目录中,并且将出现一条警告消息。如果这些文件 很重要,然后重置您的稀疏结帐定义,以便包含它们, 使用git addgit commit 来存储它们,然后删除所有剩余的文件 手动确保 Git 能够以最佳方式运行。

      【讨论】:

      猜你喜欢
      • 2020-12-08
      • 2023-03-29
      • 2016-06-22
      • 1970-01-01
      • 2021-08-09
      • 2020-01-16
      • 2020-05-19
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多