Git Subtree 只有一个文件或目录

Posted

技术标签:

【中文标题】Git Subtree 只有一个文件或目录【英文标题】:Git Subtree only one file or directory 【发布时间】:2014-04-15 13:49:16 【问题描述】:

我使用如下 Git 子树:

git subtree add --prefix=directory_destination_path --squash git@bitbucket.org:kicaj/projectname.git master

但在路径中:directory_destination_pathprojectname.git 复制所有 repo

如何仅复制到directory_destination_path 的子目录或仅从projectname.git 复制一些文件?

编辑: 还有一个问题: 如何更新(自动)两个存储库中的文件更改仍然相同?有可能吗?

【问题讨论】:

【参考方案1】:

如果我理解,您似乎只想合并到不同存储库的某个目录中,并且希望它成为存储库中的子树。我将调用 project.git 中感兴趣的目录path_of_interest_in_project 并调用你的 repo 中的目标directory_desination_path

尝试将远程 project.git 添加为远程,然后在本地签出其分支之一。然后使用git-subtree split 拆分出您感兴趣的project.git 目录。然后使用子树合并将其合并到您的repo 中。

git remote add project git@bitbucket.org:kicaj/projectname.git
git branch project_master project/master

project_master 分支现在应该存储你的 project.git 存储库的整个历史记录。

然后你需要使用git-subtrees-split 进程。

git checkout -f project_master
git subtree split --squash --prefix=path_of_interest_in_project -b temp_branch

现在应该有一个名为 temp_branch 的分支,其中只包含您感兴趣的目录。现在您可以执行 git-subtree-merge 将其全部放入您的存储库中。

git checkout -f master
git subtree merge --allow-unrelated-histories --prefix=directory_destination_path temp_branch

这应该在 temp_branch 中合并到您的 master 分支中。

【讨论】:

就它们同步而言,没有内置方法可以自动(仅)保持这些文件同步。您必须编写一个脚本来处理这一切。更简单的事情可能是将这些文件作为独立的 repo 进行跟踪,并将它们用作两个项目中的 subtress。总体而言,这根本不是一个好的工作流程。 问题:你需要先git fetch,然后才能git branch,否则你会得到fatal: Not a valid object name。当我到达git subtree split 时,我不知道之后该做什么,因为我得到了fatal: ambiguous argument 'temp_branch': unknown revision or path not in the working tree. 命令中有错字。我编辑了它。分支名称前需要 A -b。它现在完全按照 OP 的预期工作。 那么如何更新唯一的一个文件或目录呢?重复每一步? 据我所知,git subtree split --squash --prefix=path_of_interest_in_project -b temp_branch 仅当path_of_interest_in_project 是一个目录时。在这种情况下,它会抓取与该目录中所有文件相关的提交。有没有办法指定一个且只有一个文件【参考方案2】:

假设您想在 ref master 处添加 octocat git repo 的 images/ 前缀。

假设我们要使用托管在https://github.com/octocat/octocat.github.io.git 的远程(注意:GitHub 在以下fetch 命令中返回error: Server does not allow request for unadvertised object 是你指定了一个不与命名引用关联的sha1)

从您希望添加子树的分支开始,让我们首先获取所需的提交历史记录并检查我们的新分支

git fetch https://github.com/octocat/octocat.github.io.git master:tmp_octocat_master
git checkout tmp_octocat_master

接下来,让我们创建一个新的历史记录,其中仅存在我们所需前缀 (images/) 下的文件。

git subtree split --prefix=images -b subtree_split_branch

最后,让我们将这个子树添加到我们想要的分支(大概是你所在的最后一个分支,git checkout -

git checkout -
git subtree add --prefix=public/images subtree_split_branch

现在您应该在当前分支上拥有所有需要的文件以及完整的 git 历史记录。

Alt Squashed 历史

有时您希望将子树中的提交压缩成一个提交。这在一定程度上违背了添加子树的目的,但它有它的位置。以下是上述内容的变体,以限制拉入您的回购的历史记录

从您希望将子树添加到的分支开始:

git fetch --depth=1 https://github.com/octocat/octocat.github.io.git master:tmp_octocat_master
git checkout tmp_octocat_master

注意:我们在上面指定了--depth=1,因为我们使用--squash是下面的git subtree split命令。

git subtree split --squash --prefix=images -b subtree_split_branch
git checkout -
git subtree add --prefix=public/images subtree_split_branch

【讨论】:

注意:我不相信git subtree split 目前支持指定单个文件。它构建并直接将--prefix 命令传递给git read tree。 > --prefix=/ 保留当前索引内容,并读取 目录下的命名 tree-ish 的内容。该命令将拒绝覆盖原始索引文件中已经存在的条目。请注意,/ 值必须以斜杠结尾。 为什么我们在--prefix=public/images 中需要public 那么这个子树如何根据自己的remote更新呢?

以上是关于Git Subtree 只有一个文件或目录的主要内容,如果未能解决你的问题,请参考以下文章

golang项目git-subtree完美解决差异包管理

git怎么更新submodules

Git应用详解第十讲:Git子库:submodule与subtree

git bash 常用操作文件命令行

git bash怎么用cd命令切换路径写法?

git bash 怎么用cd命令切换路径写法