Git从分支 checkout 文件而不跟踪它们

e3bfsja2  于 2022-12-02  发布在  Git
关注(0)|答案(2)|浏览(167)

我的问题是:我有一个git存储库,它的目录在.gitignore文件中。通常情况下,这是可行的,并且目录中任何被更改的文件都将被忽略。但是,如果我从一个分支 checkout 文件到被忽略的目录中,* 不会 * 忽略这些文件,即:

git checkout a_branch /c/IgnoredDirectory

我发现应该被忽略的目录和文件现在被跟踪

git status

那么,我如何从一个单独的分支添加文件而不被git跟踪呢?我的想法是,git应该忽略我添加的文件,因为它们在.gitignore文件的ignored目录中。我在哪里看到了错误呢?
编码:
我的.gitignore文件

RecordDataBases/

当我从一个单独的分支 checkout 文件并运行git status时,我得到:

new file:   RecordDataBases/AstroFiles
    new file:   RecordDataBases/AstroFiles_goodversion
    new file:   RecordDataBases/AstroFiles_old_file
    new file:   RecordDataBases/README.rtf

谢谢

kulphzqa

kulphzqa1#

正确答案:git checkout *commit-specifier* -- *paths*将指定提交中的指定路径复制到 * 索引 *(也称为 * 暂存区 *)。一旦它们进入索引,就会被 * 跟踪 *。然后,它使用任何目录或glob扩展产生的相同完整路径,将文件从索引复制到工作树。
由于任何在索引中的文件都被定义为被跟踪,你的任务要么是避免它们进入索引,要么是在索引之后再次删除它们。后者更容易:

git rm -r --cached RecordDataBases/

例如(但是注意,它将移除用于这些文件的 * 所有 * 索引条目,而不仅仅是由git checkout步骤创建的索引条目)。--cached选项告诉git rm从索引中 * 仅 * 移除文件,而不是从工作树中移除文件。
你也可以从指定的提交中提取文件,而不用先把它们复制到索引中。最简单的方法是使用git show,语法为git show *commit-specifier*:*path* > *path*,例如git show a_branch:RecordDataBases/AstroFiles > RecordDataBases/AstroFiles。除了需要重复每个路径名外,这里还有一些注意事项:

  • 这需要一次处理一个文件(没有容易的方法来获得包括子树的整个目录树);和
  • 默认情况下,忽略任何行尾、识别或涂抹过滤操作。

但是,由于这不会先将扩展路径复制到索引中,因此以后无需将它们从索引中删除。

    • 编辑:**Git-2.23 git restore中的新功能可以从提交中提取文件,而不需要将其写入索引(在最初的问题中,这个选项还不可用)。这比事后修复要容易,但对许多文件来说仍然有点笨拙。

提取特定提交在不影响其他文件的情况下,考虑使用git worktree add--detach来创建指定提交的detached-HEAD提取。额外的工作树可以用来获取所有文件。或者,考虑使用git archive(参见its documentation)来创建特定提交或其子集的tar或zip文件。(它可以按照指示进行归档替换;请再次参阅文档)。

zpgglvta

zpgglvta2#

那么另一种方法呢:

git checkout commit-specifier RecordDataBases/
mv RecordDataBases/ RecordDataBases.historical/
git reset
#optionally: mv RecordDataBases.historical/ RecordDataBases/

在这个git状态显示RecordDataBases.historical/作为未跟踪的目录。如果你重命名它的行为是相同的,前提是RecordDataBases/之前不存在。
是否有任何(其他)我看不到的副作用?

相关问题