GIT 检出一个文件夹除外

GIT checkout except one folder

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

我想要文件夹显示在 git status 中,所以我现在可以将此文件夹添加到索引中。

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

可能吗?

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

"Sparse checkout" allows populating the working directory sparsely. It uses the skip-worktree bit to tell Git whether a file in the working directory is worth looking at.

这是您的使用方法。首先,启用 sparseCheckout 选项:

git config core.sparseCheckout true

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

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

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

/*
!node_modules

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

如果您稍后想再次包含 node_modules 目录(即从其文件中删除 skip-worktree bit),您必须修改 sparse-checkout 文件以仅包含 /* – 即 "include all paths" – 并使用 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.

中首次引入的

我从我想签出的分支签出了全部代码

# 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 

祝你好运...

read-tree sparse checkout is the command git sparse-checkout in cone mode (presented here)

的替代方法

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

参见 commit 716f68e (10 Aug 2021) by Junio C Hamano (gitster)
参见 commit 55dfcf9, commit ce7a9f0, commit 77efbb3, commit 02155c8, commit 8a96b9d, commit 5dc1675, commit 72d84ea, commit e27eab4, commit 522d3ce (08 Sep 2021) by Derrick Stolee (derrickstolee)
(由 Junio C Hamano -- gitster -- in commit dc89c34 合并,2021 年 9 月 20 日)

sparse-checkout: clear tracked sparse dirs

Signed-off-by: Derrick Stolee
Reviewed-by: Elijah Newren

When changing the scope of a sparse-checkout using cone mode, we might have some tracked directories go out of scope.
The current logic removes the tracked files from within those directories, but leaves the ignored files within those directories.
This is a bit unexpected to users who have given input to Git saying they don't need those directories anymore.

This is something that is new to the cone mode pattern type: the user has explicitly said "I want these directories and not those directories." The typical sparse-checkout patterns more generally apply to "I want files with with these patterns" so it is natural to leave ignored files as they are.
This focus on directories in cone mode provides us an opportunity to change the behavior.

Leaving these ignored files in the sparse directories makes it impossible to gain performance benefits in the sparse index.
When we track into these directories, we need to know if the files are ignored or not, which might depend on the tracked .gitignore file(s) within the sparse directory.
This depends on the indexed version of the file, so the sparse directory must be expanded.

We must take special care to look for untracked, non-ignored files in these directories before deleting them.
We do not want to delete any meaningful work that the users were doing in those directories and perhaps forgot to add and commit before switching sparse-checkout definitions.
Since those untracked files might be code files that generated ignored build output, also do not delete any ignored files from these directories in that case.
The users can recover their state by resetting their sparse-checkout definition to include that directory and continue.
Alternatively, they can see the warning that is presented and delete the directory themselves to regain the performance they expect.

By deleting the sparse directories when changing scope (or running 'git sparse-checkout'(man) reapply) we regain these performance benefits as if the repository was in a clean state.

Since these ignored files are frequently build output or helper files from IDEs, the users should not need the files now that the tracked files are removed.
If the tracked files reappear, then they will have newer timestamps than the build artifacts, so the artifacts will need to be regenerated anyway.

Use the sparse-index as a data structure in order to find the sparse directories that can be safely deleted.
Re-expand the index to a full one if it was full before.

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

When changing the sparse-checkout patterns in cone mode, Git will inspect each tracked directory that is not within the sparse-checkout cone to see if it contains any untracked files. If all of those files are ignored due to the .gitignore patterns, then the directory will be deleted.
If any of the untracked files within that directory is not ignored, then no deletions will occur within that directory and a warning message will appear. If these files are important, then reset your sparse-checkout definition so they are included, use git add and git commit to store them, then remove any remaining files manually to ensure Git can behave optimally.