所以,我有一个更大的(闭源)项目,并且在这个项目的上下文中创建了一个在其他地方也有用的库,我认为。
我现在想要在自己的项目中拆分库,它可以作为github或类似的开源。当然,图书馆(及其历史)不应包含我们项目的痕迹。
git-subtree在这里似乎是一个解决方案,但它并不完全适合。
我的目录布局是这样的(因为它是一个Java项目):
拆分后,我希望库的目录布局如下所示(包括直接在粗体目录中的任何文件):
历史记录还应该只包含主要项目历史记录的一部分,该部分涉及存储库的这一部分。
第一眼看到我git-subtree split --prefix=src/de/fencing_ame/transport
,但这将
transport
(不会编译)和transport/client
,transport/server
和transport/fencing
目录。第一点可以通过在接收方使用git subtree add --prefix=src/de/fencing_ame/transport <commit>
来缓解,但我不认为git-subtree可以对导出这些子目录做很多事情。 (这个想法真的是只能在这里分享完整的树。)
我必须在这里使用git filter-branch
吗?
在拆分之后,我希望能够导入我的主项目中的库,使用git-subtree或git-submodule,在一个单独的子目录中而不是现在的位置。我想象这样的布局
答案 0 :(得分:3)
我认为你有一些真正的洞察力要做。如果您只想拆分“协议”,可以使用“git subtree split ...”或“git filter-branch ...”
git filter-branch --subdirectory-filter
fencing-game/src/de/fencing_game/transport/protocol -- --all
但如果您在传输以及传输/协议中有文件,它就会变得毛茸茸。
我为我正在进行的项目编写了一些自定义工具。它们不会在任何地方发布,但您可以使用reposurgeon执行类似的操作。
答案 1 :(得分:3)
这似乎是一个常见的请求,但是当文件夹混合在一起时,我认为没有 简单的 答案。
我建议拆分与其他文件夹混合的库的一般方法是:
使用库的新根创建分支:
git subtree split -P src/de/fencing_game -b temp-br
git checkout temp-br
# -or-, if you really want to keep the full path:
git checkout -b temp-br
cd src/de/fencing_game
然后使用某些东西重写历史记录以删除不属于库的部分。我不是这方面的专家,但我能够尝试并找到这样的工作:
git filter-branch --tag-name-filter cat --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch client server otherstuff' HEAD
# also clear out stuff from the sub dir
cd transport
git filter-branch --tag-name-filter cat --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch fencing client server' HEAD
注意:您可能需要删除连续命令之间filter-branch所做的备份。
git update-ref -d refs/original/refs/heads/temp-br
最后,只需为库创建一个新的仓库并拉入剩下的所有内容:
cd <new-lib-repo>
git init
git pull <original-repo> temp-br
我建议您的最终库路径更像/transport/protocol
而不是完整的父项目路径,因为这似乎与项目有关。
答案 2 :(得分:2)
这里的问题是,图书馆的内容与图书馆的内容并没有很好的分离。我强烈建议重构该解决方案,然后您可以将该库作为子模块包含在内。
如果此库的重用仅由其他开发人员在同一个repo中,则只需在单独的分支上跟踪这些更改,而不必担心额外的repos。
答案 3 :(得分:1)
项目的历史是仅为了您的利益,还是为了github上的人的利益?
如果历史记录仅供您使用,那么使用移植物的方法很简单。基本上,只需为github创建一个全新的存储库,删除所有专有代码。现在你有一个只有公共代码的开源仓库,你可以推送到github。在您的本地开源仓库副本中,您可以将专有仓库的历史记录移植到开源仓库中。
这样做意味着您(或任何有权访问专有仓库的人)都可以看到完整的历史记录,但普通公众只能从您开源的那一点看到代码。
答案 4 :(得分:1)
我做了类似的事情,但是在加密分区(/ secure / tmp / newrepo)上将几个东西拆分成一个完全独立的仓库,因此笔记本电脑小偷无法使用它们。 我写了shell脚本然后做了: git filter-branch --tree-filter'~ / bin / tryit / secure / tmp / newrepo personal private' - 95768021ff00216855868d12556137115b2789610..HEAD (SHA避免在任一目录存在之前提交)
#!/bin/sh
# to be used with e.g:
# git filter-branch --tree-filter '~/bin/tryit /secure/tmp/newrepo personal private'
# Don't do it on any repository you can't repeatedly do:
# rm -rf foo ; git clone /wherever/is/foo
# when it breaks
SRC=`pwd`
DEST=$1
shift
MSG=/dev/shm/msg.txt
TAR=/dev/shm/tmp.tar
LIST=/dev/shm/list.txt
LOG=/dev/shm/log
DONE=''
echo $GIT_AUTHOR_DATE >> $LOG
git show --raw $GIT_COMMIT > $MSG
for A in $*
do
if [ -d $A ]
then
DONE=${DONE}x
tar -cf $TAR $A
tar -tf $TAR > ${LIST}
cat ${LIST} >> ${LOG}
rm -rf ${A}
cd ${DEST}
tar -xf $TAR
else
echo $A non-existant >> ${LOG}
fi
cd $SRC
done
if [ -z "${DONE}" ]
then
echo Empty >>$LOG
else
cd ${DEST}
unset GIT_INDEX_FILE
unset GIT_DIR
unset GIT_COMMIT
unset GIT_WORK_TREE
touch foo
git add .
git commit -a -F ${MSG} >> ${LOG}
fi
exit 0
出于您的目的,您可能希望为tar设置不同的规范(例如--exclude =),然后使用cat $ {LIST} | xargs rm只能删除tar中的内容,但是我希望这样做并不是太棘手。
未设置的东西和退出0很重要,因为filter-branch将它们设置为你的源代码(不是你想要的!),如果sh传递了脚本中最后一个命令的非零退出代码,它将会死掉。