git-subtree:从克隆的 repo 推送更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12801936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 14:44:51  来源:igfitidea点击:

git-subtree: Push changes from an cloned repo

gitgit-subtree

提问by arge

I'm using git-subtree(from Avery Pennarun). In my current git repo I have of course all my project files/folders and a subtree called "lib". If I now clone this git repo using git cloneI get all of the project files and the subtree "lib" (everything as it should be). What I tried now: I changed something within the subtree "lib" in the cloned repo and tried to push the changes back to the remote repo of the subtree "lib" using git subtree push, but it didn't work. What is the problem? Do I have to add it as subtree first with git subtree add?

我正在使用 git-subtree(来自 Avery Pennarun)。在我当前的 git repo 中,我当然拥有我所有的项目文件/文件夹和一个名为“lib”的子树。如果我现在使用克隆这个 git repo,git clone我将获得所有项目文件和子树“lib”(一切都应该如此)。我现在尝试过的:我在克隆的存储库中的子树“lib”中更改了一些内容,并尝试使用 将更改推送回子树“lib”的远程存储库 git subtree push,但没有用。问题是什么?我是否必须首先使用 git subtree add 将其添加为子树?

Thx in advance

提前谢谢

回答by Rog

Disclaimer, I suspect I am only a few days ahead of you learing about subtree :-)

免责声明,我怀疑我只比你提前几天了解子树:-)

If you are just using git subtree pushyou are not giving subtree enough information to extract and push your changes.

如果您只是在使用,则git subtree push您没有为子树提供足够的信息来提取和推送您的更改。

If you cloned the repo correctly the subtree will already be in there. Subtree needs to be told which subtree you want to push from (even if you only have one) and it also needs to know where to push to - specifically, you do not want to push to the top level repo. Hence, you want something like:

如果您正确克隆了 repo,则子树将已经在那里。需要告诉子树你想从哪个子树推送(即使你只有一个),它还需要知道推送到哪里 - 特别是,你不想推送到顶级存储库。因此,你想要这样的东西:

git subtree push --prefix=lib [email protected]:arges-github/lib.git master

Obviously the repo and refspec should be changed to match your repo.

显然,应该更改 repo 和 refspec 以匹配您的 repo。

If you want to look into what is happening here (and it does help) subtree actually splits the changes that affect the files inside the subtree into a different branch and then pushes that to the subtree repo. To see this happen, use subtree split

如果您想查看这里发生的事情(它确实有帮助),子树实际上会将影响子树内文件的更改拆分为不同的分支,然后将其推送到子树存储库。要看到这种情况,请使用subtree split

git subtree split --rejoin --branch=shared-changes --prefix=lib

then have a look at the branch you've made:

然后看看你所做的分支:

git checkout lib-changes

and, push them manually

并且,手动推动它们

git push [email protected]:arges-github/lib.git master

If this isn't working then it may be that you have not merged the subtree into your repo. When you add a subtree:

如果这不起作用,则可能是您尚未将子树合并到您的存储库中。添加子树时:

 git subtree add --squash --prefix lib [email protected]:arges-github/lib.git master

you also need to merge the subtree and push it back to your top level repo.

您还需要合并子树并将其推送回您的顶级存储库。

 git subtree pull --squash --prefix lib [email protected]:arges-github/lib.git master
 git push

回答by Carl

I had exactly the same problem you were having and I solved it using essentially the approach Roger Nolan suggested. However, if you're unlucky enough to be on a case-insensitive file system like I was, you also have to make sure that every time you do a pull and a push, the case of your prefix stays the same.

我遇到了与您完全相同的问题,我基本上使用 Roger Nolan 建议的方法解决了它。但是,如果您不幸像我一样使用不区分大小写的文件系统,您还必须确保每次执行拉取和推送时,前缀的大小写保持不变。

When you do end up mixing up the case by mistake, git will think you have two subtrees whereas only one will exist on the filesystem.

当您最终错误地混淆了大小写时,git 会认为您有两个子树,而文件系统中只存在一个。

So the solution that I ended up with (in case it helps anyone) is:

所以我最终得到的解决方案(以防它对任何人有帮助)是:

  1. Create a script that will push your subtree. Call it publish_<your-subtree-name>.
  2. Create another script that will pull your subtree. Call it update_<your-subtree-name>.
  3. Create a temporary branch at your HEAD and test out update. If your script is right, your temp branch won't move.
  4. Clone the subtree repo elsewhere, add in a test commit, push it and try to pull it into your repo using the update script you just wrote.
  5. If it all works, delete your temporary branch and now check in both scripts to the super project repo.
  6. Then whenever you need to push or pull subtrees, use the scripts.
  1. 创建将推送您的子树的脚本。叫它publish_<your-subtree-name>
  2. 创建另一个脚本来拉你的子树。叫它update_<your-subtree-name>
  3. 在您的 HEAD 创建一个临时分支并测试更新。如果你的脚本是正确的,你的临时分支就不会移动。
  4. 在别处克隆子树存储库,添加测试提交,推送它并尝试使用您刚刚编写的更新脚本将其拉入您的存储库。
  5. 如果一切正常,请删除您的临时分支,然后将两个脚本都签入超级项目存储库。
  6. 然后,每当您需要推送或拉取子树时,请使用脚本。

PS> The --squash parameter is important, particularly if different branches of your reporsitories are pulling different branches of the subtree and also if you have multiple subtrees in your project.

PS> --squash 参数很重要,特别是如果您的存储库的不同分支正在拉取子树的不同分支,并且您的项目中有多个子树。