在BASH中,如何递归地只复制由Git控制的内容版本?

在BASH中,如何递归地只复制由Git控制的内容版本?,git,bash,version-control,directory,cp,Git,Bash,Version Control,Directory,Cp,是否有一种方法可以在bash终端中从一个子目录到另一个子目录进行大规模递归复制(cp-rf等效),保留目录结构,但只有复制文件/目录才受git的版本控制 天真的策略是 cp -rf <targetDir> variantDir/; git add variantDir; 基本上,${baseDir}/包含所有原始版本控制的内容,${baseDir}/variantA包含与目标变体不同的内容。对于原始目标文件夹,忽略${baseDir}/variantA。对于第二个目标,包含文件夹v

是否有一种方法可以在bash终端中从一个子目录到另一个子目录进行大规模递归复制(
cp-rf
等效),保留目录结构,但只有复制文件/目录才受
git
的版本控制

天真的策略是

cp -rf <targetDir> variantDir/; git add variantDir;
基本上,
${baseDir}/
包含所有原始版本控制的内容,
${baseDir}/variantA
包含与目标变体不同的内容。对于原始目标文件夹,忽略
${baseDir}/variantA
。对于第二个目标,包含文件夹
variantA
,有效地替代了路径的
variantA
部分以外的任何匹配内容

i、 e.如果我有:

${baseDir}/someFolder/someStuff.cpp
${baseDir}/variantA/someFolder/someStuff.cpp
它将第二条路径用于第二个目标,第一条路径用于第一个目标

现在我添加了
variantB
,它是一个完整的变体(与
variantA
不同,它对基本目标的文件有一些缺陷)。它更接近于
variantA
,因此我想先复制基本文件夹中的所有内容,然后将
variantA
子文件夹中的所有内容复制到
variantB
子文件夹中。。。这样,我就有了一个所有内容的新副本(包括下拉列表)进行版本提交,当存在重叠时,我会优先选择
variantA
文件版本


我会使用上面的简单代码段,但我有一个更基本的问题,我的IDE删除了
*.xml
文件和其他垃圾文件,
git
以某种方式聪明到可以标记为非未提交内容(可能是特定于语言的),但
cp
会忽略它们。如果明确要求,我相信
git
会复制这些文件,因此,我想排除所有非
git
控制的内容,同时使用前面所述的一般策略。

仅将源代码控制下的文件从Variata复制到variantB:

cd variantA
rsync --files-from <(git ls-files .) . ../variantB
cd variantA

rsync--files from仅将源代码管理下的文件从Variata复制到variantB:

cd variantA
rsync --files-from <(git ls-files .) . ../variantB
cd variantA

rsync--files from如果您有GNU
cp
,您可以使用
--parents
选项:

mkdir variantB
cd variantA
cp --parents $(git ls-files .) ../variantB

如果您有GNU
cp
,您可以使用
--parents
选项:

mkdir variantB
cd variantA
cp --parents $(git ls-files .) ../variantB
这将获取工作树中当前位置的内容。要使用提交的子目录,请使用
git archive
解决方案

要处理当前添加但未提交的内容,您可以为上面的
master
替换
$(git write tree)

这将获取工作树中当前位置的内容。要使用提交的子目录,请使用
git archive
解决方案


要处理当前添加但未提交的内容,您可以为上面的
master
替换
$(git write tree)

为什么不创建一个新的工作树(因为它是从源代码管理生成的,所以其中显然只有源代码管理的文件)

有几种方法可以做到这一点(克隆或工作树),但我认为

git worktree add -b variantB path/where/variantB/will/be/created master 
将让您从相关文件(那些在源代码管理下的文件)开始。然后您只需将
path/where/variant/B/will/be/created/variantA
复制到
path/where/variant/B/will/be/created

由于
-b
选项,您已经在一个新的分支上了-这就是您可能希望保持这种变化的方式,因为它是一个完整的替换。(对于varientA来说,这是有争议的,因为您希望varientA能够及时更新对文件的基线更改,而不会改变…)


但如果你不想为此维持一个新的分支机构,那没什么大不了的。使用clone或worktree add命令(不带
-b
)如上所述创建variantB的工作树映像,然后将生成的文件移动到…/variantB目录下的默认工作树中

为什么不创建一个新的工作树呢(因为它是从源代码管理生成的,所以其中显然只包含源代码管理的文件)

有几种方法可以做到这一点(克隆或工作树),但我认为

git worktree add -b variantB path/where/variantB/will/be/created master 
将让您从相关文件(受源代码管理的文件)开始。然后您只需在
path/where/variant/B/will/be/created/variantA
上复制
path/where/variant/B/will/be/created

由于
-b
选项,您已经在一个新的分支上了-这就是您可能希望保持这种变化的方式,因为它是一个完全的替代品。(对于varientA来说,这是有争议的,因为您希望varientA跟上对它没有变化的文件的基线更改…)


但是如果您不想为此维护一个新分支,那没什么大不了的。使用clone或worktree add命令(不带
-b
)如上所述创建variantB的工作树映像,然后将生成的文件移动到…/variantB目录下的默认工作树中

您不是在重新发明分支吗?对于我当前正在处理的代码库,Dir结构或多或少在某种程度上超出了我的控制,但其背后的推理有点道理。Tradi在某些情况下会使用分支,而在同时针对多个目标时,会使用带有专门构建系统的变体目录来减少冗余…虽然我有点被锁定,但是的,我知道在某些方面这是一个奇怪的情况,但这就是为什么我首先列出简单版本,因为我觉得这是一个普遍的问题关于如何
cp-rf
只有版本控制的内容是非常普遍的。除了
git
(或专门设计用于git存储库的工具)之外,我不希望有任何其他工具要做到这一点,为什么不使用
git archive
命令呢?它可以通过管道将tarball传输到其标准输出,这样就可以通过管道将tar-x-C/path/to/destination
完成了