首页 > 解决方案 > 当我的本地存储库中只有项目的子目录时,是否可以推送 Git?

问题描述

我有一个本地 git 存储库,该存储库配置为通过 Gitlab 上的 SSH 远程连接(我们称之为git@gitlab.com:myrepo/myproject.git),在克隆存储库后,我喜欢仅在本地保留项目的特定文件夹,我使用以下命令进行操作:

git filter-branch --prune-empty --subdirectory-filter subdirectory HEAD~..

此命令使本地存储库跟踪subdirectory远程 git 项目上的文件夹(并忽略我项目中此文件夹之前的所有文件)。只要我只将它用于拉它就可以了......问题是如果我尝试将更改推送到该远程分支,如果我尝试我会看到以下错误:

$ git push -u origin master
To git@gitlab.com:myrepo/myproject.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@gitlab.com:myrepo/myproject.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

我没有找到任何关于这个特定案例的内容git push --helppush当我的本地存储库中只有项目的子文件夹时,有谁知道是否可以使用远程文件夹?

标签: git

解决方案


git push推送完整的历史;你正在做的是一个子树合并。Git可以做到这一点,将您的过滤器分支从HEAD更改HEAD~..为不重写整个历史记录,然后您可以

git checkout origin/master
git merge -s subtree master
git push origin HEAD:master

任何其他保留合并基础的过滤器分支截止都可以,这完全取决于您真正想要在本地重写多少。


如果完整原始快照的签出非常痛苦,即使您可以通过一些轻微的修饰来避免不必要的工作树流失,您也不想经历它们。

为临时工作创建一个轻量级的克隆并切换到它:

git branch -tf mergeback origin/master
git clone -nsb mergeback -o local . `mktemp -d`
cd $_

请注意,以这种方式完成的整个 linux 存储库的克隆在我的盒子上使用了 320KB(这不是错字)。然后,您可以进行最小结帐合并:

git reset --quiet                    # load just the index, not the worktree
git merge -s subtree local/master    # merge my master branch into the right subtree
git push local mergeback             # push the results back to the main repo
cd -                                 # back to my repo

从那里您可以git push origin mergeback:master将结果推送到 gitlab。

编辑: ps 而不是用过滤器分支重写提交,您还可以在新的提交中提升子树:git read-tree -um @:path/to/subdir; git commit,这样合并不会引入现有提交的邪恶双胞胎。


推荐阅读