我们在SVN中有代码,但现在切换到Git。
问题是我们有这个文件夹:
/src/com/something/main
/src/com/something/dev
,Eclipse源文件夹设置为/src
。
只有包.../main
中的代码必须公开。
包.../dev
中的代码未完成并且是私有的。
当.../dev
中的代码完成后,我们将类移到Eclipse中的.../main
。这是一个不同的Java包,我们不使用分支。所以这不是合并。
我试过
git filter-branch --index-filter
'git rm --cached --ignore-unmatch src/com/something/dev'
然而,移动前的所有历史都丢失了,文件突然出现了由移动的作者完成!
如何将存储库拆分为两个分支:分支“secret”包含所有内容,分支“public”具有文件夹.../main
中所有文件的完整历史记录,即使文件最初位于文件夹.../dev
中也是如此被隐藏了吗?
假设文件历史记录如下
.../dev/file1 created moved to .../main/file1 (released)
.../dev/file2 created but not released
然后我需要公开版本来显示两个提交:.../dev/file1
的创建和移动到发布。当然,在此文件之间进行的任何编辑。 .../dev/file2
的存在/历史应该只在完整的存储库中。更糟糕的是:某些提交修改file1
和file2
,但只发布了file1
。
git是否允许这样做?有一个“秘密”分支,但是当将文件从秘密分支推送到主分支时,所有历史记录也会被移动?或者它是否提交最终文件(没有历史记录)来发布分支?文件重命名似乎也非常糟糕。它如何处理未推送的相同提交中的其他文件?是否有一个git命令将file1提交到仅包含此文件的所有历史记录的“public”,而不是同一提交中的其他文件?
答案 0 :(得分:0)
简短回答是git mv dev /src/com/something/dev /src/com/something/main
。这保留了历史。但是你不想保留所有的历史,你想要一个不同的历史。因此,您必须将涉及未发布文件的提交的公共和私有部分分开。并且git需要知道移动(来自git mv
或因为它自动检测重定位)以便有机会将旧文件的历史与新路径相关联。即使该历史被修改。
所以一个开始的问题可能是"什么是触及/ src / com / something / dev和/ src / com / something / main的提交的交集?"
git log --reverse --pretty=oneline /src/com/something/main /src/com/something/dev >combined_commits.log
git log --pretty=oneline /src/com/something/dev >dev_commits.log
git log --pretty=oneline /src/com/something/main >main_commits.log
sort main_commits.log dev_commits.log | uniq -d >bad_history.log
因此,最终列表具有触及两者的所有提交(但不是原始提交,即combined_commits.log命令)。没有一个命令可以执行您想要的操作,但您可以编写脚本。松散的算法是:
git rebase -i $ {EARLIEST_CONFLICT_HASH} ~1
马克"编辑"对于所有糟糕的提交,例如:
...
pick c6d108f Auto-detect catkey vs. barcode
pick 8616c0e Directory cleanup
edit ae885c6 Move registration url to '/register'
pick af5394f Initiate workflow on registration
...
保存/退出。然后在每个"编辑"相:
git commit /src/*/*/dev # commit dev stuff separately first
git add /src/*/*/main
git rebase --continue