git 将子目录推送到另一个主存储库中

发布于 2024-11-28 18:17:47 字数 862 浏览 0 评论 0原文

我有一个很大的主项目,有几个目录作为子树

我想将一个特定子树中的更改推送到其原始位置,这是一个单独的存储库。

问题似乎是,我想要推送的当前子树最初并不是来自我想要推送到的存储库。它来自另一个存储库,通过我通过谷歌搜索找到的子树指南。它只是看起来很相似。

大项目布局,其中 important_subtree 是我担心的事情。

~/devel/bigproject
  .git/
  some_subtree/
  other_subtree/
  important_subtree/
    abc.txt
    efg.txt   <--- new version
    hij.txt

并且 important_subtree 与该存储库“密切相关”:

~/devel/important
   .git/
    abc.txt
    efg.txt   <--- old version
    hij.txt

现在 ~/devel/bigproject/important_subtree/efg.txt 已更改,我想推送 important_subtree 到存储库~/devel/important。所以之后~/devel/important/efg.txt也有变化。

我唯一能做的就是将bigproject中的所有推入重要,这显然不是我想要的。仅应推送子树中的更改。

I have a big main project with several directories as subtrees.

I want to push the changes in one specific subtree to its origin, which is a separate repository.

The trouble seems to be, that the current subtree I want to push does not originally came from the repository I want to push into. It came from a different repo, via the subtree guides I found by googling. It just looks very similar.

Big project layout, where important_subtree is the thing I am worried about.

~/devel/bigproject
  .git/
  some_subtree/
  other_subtree/
  important_subtree/
    abc.txt
    efg.txt   <--- new version
    hij.txt

And the important_subtree is "strongly related" to that repo:

~/devel/important
   .git/
    abc.txt
    efg.txt   <--- old version
    hij.txt

Now ~/devel/bigproject/important_subtree/efg.txt has changed and I want to push the important_subtree onto the repo ~/devel/important. So afterwards ~/devel/important/efg.txt also has the changes.

The only thing I managed to do is to push push everything in bigproject into important, which is obviously not what I want. Only the changes in the subtree should be pushed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愿与i 2024-12-05 18:17:47

这不再那么复杂,您只需使用 git filter-branch 命令即可在您的存储库的克隆上,剔除您不需要的子目录,然后推送到新的远程目录。

git clone <ORIG_REPO_DIR> <NEW_REPO_DIR>
cd <NEW_REPO_DIR>
git filter-branch --prune-empty --subdirectory-filter <THE_SUBDIR_TO_MAKE_NEW_ROOTDIR> master
git push <MY_NEW_REMOTE_ORIGIN_URL> -f .

This is no longer so complex, you can just use the git filter-branch command on a clone of your repo to cull the subdirectories you don't want and then push to the new remote.

git clone <ORIG_REPO_DIR> <NEW_REPO_DIR>
cd <NEW_REPO_DIR>
git filter-branch --prune-empty --subdirectory-filter <THE_SUBDIR_TO_MAKE_NEW_ROOTDIR> master
git push <MY_NEW_REMOTE_ORIGIN_URL> -f .
冷夜 2024-12-05 18:17:47

我建议在 git 中添加 git-subtree 。它添加了一个 git subtree split 命令来执行您想要的操作。

git subtree split --prefix=important_subtree --branch=backport <subtree merge SHA1>^.. --onto=<imported SHA1> --rejoin
git push ~/devel/important backport:master

自您将 important 合并为子树以来,此选择会优先选择 bigproject 中的更改,仅采用那些修改了 important_subtree/ 的更改。然后,它将它们作为新提交应用到从 ~/devel/important 导入的提交之上,并创建一个分支 backport,您可以以正常方式推回该分支。此外,--rejoin 也可以实现这一点,因此如果您想在更多更改上重复该过程,则将来无需使用提交 ID。

作者的博客文章中有更多解释。

I would recommend the git-subtree addition to git. It adds a git subtree split command that does what you want.

git subtree split --prefix=important_subtree --branch=backport <subtree merge SHA1>^.. --onto=<imported SHA1> --rejoin
git push ~/devel/important backport:master

This cherry-picks the changes in bigproject since you merged important as a subtree, taking only those that modified important_subtree/. It then applies them as new commits on top of the commit you imported from ~/devel/important and creates a branch backport that you can push back in the normal way. Also --rejoin makes it so you don't need to use commit IDs in the future if you want to repeat the process on more changes.

There is more explanation on the author's blog post.

旧街凉风 2024-12-05 18:17:47

使用不同的分支进行推送可能是一件非常棘手的事情。

也许最简单的方法是:

  1. 从服务器再次克隆您的“重要”存储库。
  2. 在您的“大项目”中生成补丁,其中包含您想要的更改
    首先推送(例如 git format-patch)(如果您的原始提交混合了应该推送的文件和不应该推送的文件,您可能需要首先在侧分支中进行“较小的”提交)
  3. 在您的新克隆中“important”的应用补丁(git am)
  4. 将“important”的新克隆推送到其默认的远程主机。现在推送只是简单的快进,不会造成麻烦。

Pushing with different branches can be a very tricky thing.

Maybe the easiest way would be:

  1. Clone your "important" repo once more from the server.
  2. In your "bigproject" produce patches, which contain exactly the changes you intended to
    push in the first place (e.g. git format-patch) (you might need to make "smaller" commits in a side branch first, if your original commits mix files that should be pushed and such files that shouldn't)
  3. In your new clone of "important" apply the patches (git am)
  4. push the new clone of "important" to its default remote master. Now the push is just a simple fast forward and should not cause trouble.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文