如何从我的主存储库子树上的子项目中变基一个“过滤器分支”?
How to rebase a `filter-branch` from a subproject on my main repository's subtree?
如何从我的主存储库子树上的子项目变基 filter-branch
?
对我来说,这是对子模块执行的正常操作。我只想按照此处所述进行正常的变基:Rebasing everyone onto changed git history after filter-branch
我所做的操作是在我的子项目上,在它自己的存储库上。这是操作:
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch "some_folder/path" -r -f' \
--prune-empty --tag-name-filter cat -- --all
之后我将更改推送到子项目自己的存储库:
git push origin --force --all
git push origin --force --tags
现在我想将更改集成到我的主存储库中,其中我的子项目是一个子树。所以,这不是一个普通的存储库。为什么我在 git 子树上看不到变基选项?
解决这个问题的方法只有这个:git subtree: possible to change subtree branch/path in a forked repository?,要删除它并重新添加它吗?
尝试
做的时候:
git subtree pull --prefix=subprojectFolder subprojectRemoteRepository.git
输出为:
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
使用git subtree merge
:
git remote add subproject_remote subprojectRemoteRepository.git
git fetch --no-tags
git checkout master
git subtree merge --prefix=subprojectFolder subproject_remote/master
fatal: refusing to merge unrelated histories
如何使它们相关联?
--allow-unrelated-histories
只会导致:
error: unknown option `allow-unrelated-histories'
usage: git subtree add --prefix=<prefix> <commit>
or: git subtree add --prefix=<prefix> <repository> <ref>
or: git subtree merge --prefix=<prefix> <commit>
or: git subtree pull --prefix=<prefix> <repository> <ref>
or: git subtree push --prefix=<prefix> <repository> <ref>
or: git subtree split --prefix=<prefix> <commit...>
我现在正在应用这个解决方案,而没有更方便的东西。
第 1 部分
- 克隆
subproject dedicated repository
并在其上结帐。
- 按照我喜欢的方式执行
filter-branch
操作。
- 执行
git push origin --force --all
和标记。
第 2 部分
- 克隆
main project
存储库并检出它。
要执行与 第 1 部分 完全相同的 filter-branch
,并删除当前的子项目树,或使用 bfg-repo-cleaner 与:
git clone --mirror mainRepository.git
java -jar bfg.jar --no-blob-protection --delete-folders 'subprojectFolder' mainRepository.git
cd mainRepository.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push origin --force --all
git push origin --force --tags
cd ..
rm -r mainRepository.git
第 3 部分
终于读取刚刚清理过的子树:
git clone mainRepository.git
cd mainRepository
git checkout master
git subtree add --prefix=subprojectFolder subproject.git master
git push
- 告诉大家Rebasing everyone onto changed git history after filter-branch你的主项目,以及子项目的专用克隆,如果有的话。
结束
请注意,目前使用 bfg-repo-cleaner,只有在主项目上没有其他文件夹与子项目名称相同的情况下,您才能删除该文件夹。这是因为 BFG 将删除所有匹配 subprojectFolder
名称的文件夹。指定文件夹路径的功能仍在开发中:How to delete one folder/directory using BFG repo cleaner?。否则您可以使用 filter-branch
删除项目的 subtree
.
要完全删除内容,请在完成存储库中的 filter-branch
(s) 后,从另一个答案 Why is my git repository so big? 中执行此操作:
rm -Rf .git/refs/original && \
git reflog expire --expire=now --all && \
git gc --aggressive && \
git prune
要列出最大的文件,请使用:
git rev-list --all --objects | \
sed -n $(git rev-list --objects --all | \
cut -f1 -d' ' | \
git cat-file --batch-check | \
grep blob | \
sort -n -k 3 | \
tail -n40 | \
while read hash type size; do
echo -n "-e s/$hash/$size/p ";
done) | \
sort -n -k1
从另一个答案 How to remove unreferenced blobs from my git repo 中,您可能希望在 filter-branch
拉取之后执行此操作。记得看原文哦
git tag | xargs git tag -d && \
git remote rm origin && \
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ && \
git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d && \
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \
-c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
如何从我的主存储库子树上的子项目变基 filter-branch
?
对我来说,这是对子模块执行的正常操作。我只想按照此处所述进行正常的变基:Rebasing everyone onto changed git history after filter-branch
我所做的操作是在我的子项目上,在它自己的存储库上。这是操作:
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch "some_folder/path" -r -f' \
--prune-empty --tag-name-filter cat -- --all
之后我将更改推送到子项目自己的存储库:
git push origin --force --all
git push origin --force --tags
现在我想将更改集成到我的主存储库中,其中我的子项目是一个子树。所以,这不是一个普通的存储库。为什么我在 git 子树上看不到变基选项?
解决这个问题的方法只有这个:git subtree: possible to change subtree branch/path in a forked repository?,要删除它并重新添加它吗?
尝试
做的时候:
git subtree pull --prefix=subprojectFolder subprojectRemoteRepository.git
输出为:
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
使用git subtree merge
:
git remote add subproject_remote subprojectRemoteRepository.git
git fetch --no-tags
git checkout master
git subtree merge --prefix=subprojectFolder subproject_remote/master
fatal: refusing to merge unrelated histories
如何使它们相关联?
--allow-unrelated-histories
只会导致:
error: unknown option `allow-unrelated-histories'
usage: git subtree add --prefix=<prefix> <commit>
or: git subtree add --prefix=<prefix> <repository> <ref>
or: git subtree merge --prefix=<prefix> <commit>
or: git subtree pull --prefix=<prefix> <repository> <ref>
or: git subtree push --prefix=<prefix> <repository> <ref>
or: git subtree split --prefix=<prefix> <commit...>
我现在正在应用这个解决方案,而没有更方便的东西。
第 1 部分
- 克隆
subproject dedicated repository
并在其上结帐。 - 按照我喜欢的方式执行
filter-branch
操作。 - 执行
git push origin --force --all
和标记。
第 2 部分
- 克隆
main project
存储库并检出它。 要执行与 第 1 部分 完全相同的
filter-branch
,并删除当前的子项目树,或使用 bfg-repo-cleaner 与:git clone --mirror mainRepository.git java -jar bfg.jar --no-blob-protection --delete-folders 'subprojectFolder' mainRepository.git cd mainRepository.git git reflog expire --expire=now --all && git gc --prune=now --aggressive git push origin --force --all git push origin --force --tags cd .. rm -r mainRepository.git
第 3 部分
终于读取刚刚清理过的子树:
git clone mainRepository.git cd mainRepository git checkout master git subtree add --prefix=subprojectFolder subproject.git master git push
- 告诉大家Rebasing everyone onto changed git history after filter-branch你的主项目,以及子项目的专用克隆,如果有的话。
结束
请注意,目前使用 bfg-repo-cleaner,只有在主项目上没有其他文件夹与子项目名称相同的情况下,您才能删除该文件夹。这是因为 BFG 将删除所有匹配
subprojectFolder
名称的文件夹。指定文件夹路径的功能仍在开发中:How to delete one folder/directory using BFG repo cleaner?。否则您可以使用filter-branch
删除项目的subtree
.要完全删除内容,请在完成存储库中的
filter-branch
(s) 后,从另一个答案 Why is my git repository so big? 中执行此操作:rm -Rf .git/refs/original && \ git reflog expire --expire=now --all && \ git gc --aggressive && \ git prune
要列出最大的文件,请使用:
git rev-list --all --objects | \ sed -n $(git rev-list --objects --all | \ cut -f1 -d' ' | \ git cat-file --batch-check | \ grep blob | \ sort -n -k 3 | \ tail -n40 | \ while read hash type size; do echo -n "-e s/$hash/$size/p "; done) | \ sort -n -k1
从另一个答案 How to remove unreferenced blobs from my git repo 中,您可能希望在
filter-branch
拉取之后执行此操作。记得看原文哦git tag | xargs git tag -d && \ git remote rm origin && \ rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ && \ git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d && \ git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \ -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"