背景:我正在接近开源个人研究代码我已经工作了两年多。 它开始作为一个SVN仓库,但我提出到Git大约一年前,我想在GitHub上共享代码。 然而,积累了大量的克鲁夫特多年来,我更喜欢的是公版开始它的生命在其当前状态。 不过,我还是想作出贡献,并纳入其他人的潜在贡献。
问题:有没有办法为“叉”一个Git仓库,使得没有历史保留在叉(其中居住在GitHub上),但我的本地库仍然有一个完整的历史,我可以推/拉至GitHub上?
我还没有在大型的仓库里面的给药结束的任何经验,所以细节是非常赞赏。
背景:我正在接近开源个人研究代码我已经工作了两年多。 它开始作为一个SVN仓库,但我提出到Git大约一年前,我想在GitHub上共享代码。 然而,积累了大量的克鲁夫特多年来,我更喜欢的是公版开始它的生命在其当前状态。 不过,我还是想作出贡献,并纳入其他人的潜在贡献。
问题:有没有办法为“叉”一个Git仓库,使得没有历史保留在叉(其中居住在GitHub上),但我的本地库仍然有一个完整的历史,我可以推/拉至GitHub上?
我还没有在大型的仓库里面的给药结束的任何经验,所以细节是非常赞赏。
你可以在Git中很容易地创建一个新的,新的历史。 比方说,你希望你的master
分支是被存储在一个你会推到GitHub上,你的全部历史old-master
。 您只需将您的master
分支old-master
,然后使用开始没有历史一个全新的分支git checkout --orphan
:
git branch -m master old-master
git checkout --orphan master
git commit -m "Import clean version of my code"
现在你有一个新的master
分支没有历史,你可以推到GitHub上。 但是,正如你说,你希望能够看到所有的老史在本地资源库中; 而且很可能像它不会断开。
为此,您可以使用git replace
。 的替换裁判是指定备用提交任何时间GIT中着眼于指定的提交的方式。 所以,你可以让Git来看看最后一次提交这个旧的分支,看着历史的时候,而不是在第一次提交的新分支的。 为了做到这一点,你需要在断开连接的历史,使从旧的回购。
git replace master old-master
现在,你有你的新的分支,在其中您可以看到所有的历史,但实际提交从旧的历史断开对象,这样你就可以推新提交到GitHub上不老的提交磨磨蹭蹭。 把你的master
分支GitHub上,而只有新提交会去GitHub上。 但是看看在历史gitk
或git log
,你会看到完整的历史。
git push github master:master
gitk --all
陷阱
如果你立足于旧提交任何新的分支,你必须要小心,以保持历史分开的; 否则,在这些分支新的提交将真的有其历史的老提交,所以你会拉动整个历史沿,如果你将其推到GitHub上。 只要你保留所有的基于新新提交的master
,不过,你会没事的。
如果你运行git push --tags github
,这将推动所有的标签,包括旧的,这将导致所有旧的历史与它一起被拉出。 您可以通过删除所有的旧标签的解决这个问题( git tag -d $(git tag -l)
或者通过使用从未git push --tags
但永远只能手动按标签,或者通过使用如下述两种资源库。
基本这两个陷阱的基本问题是,如果你推它连接到任何旧的历史(不是通过更换提交除外)的任何裁判,你会推高所有的旧的历史。 可能避免这种最好的方式是通过使用两个库,其中一个仅包含新的提交,以及一个包含新旧历史,对检查的全部历史的目的。 你做你的工作,你的承诺,你推从GitHub拉,与刚刚新提交回购; 这样一来,你不可能不小心把你的旧犯了。 然后,把所有新提交到您的回购是有充分的历史,每当你需要看整个事情。 您可以从GitHub或您的其他本地回购,取其更方便拉。 这将是你的存档,但要避免意外发布您的悠久历史,你永远不要推到GitHub的从它。 这里是你如何可以设置它:
~$ mkdir newrepo ~$ cd newrepo newrepo$ git init newrepo$ git pull ~/oldrepo master # now newrepo has just the new history; we can set up oldrepo to pull from it newrepo$ cd ~/oldrepo oldrepo$ git remote add newrepo ~/newrepo oldrepo$ git remote update oldrepo$ git branch --set-upstream master newrepo/master # ... do work in newrepo, commit, push to GitHub, etc. # Now if we want to look at the full history in oldrepo: oldrepo$ git pull
如果你对Git的年纪比1.7.2
你没有git checkout --orphan
,所以你必须通过从现有资料库的当前版本创建一个新的仓库,然后拉在你的旧断开的历史做手工。 你可以做到这一点,例如:
oldrepo$ mkdir ~/newrepo oldrepo$ cp $(git ls-files) ~/newrepo oldrepo$ cd ~/newrepo newrepo$ git init newrepo$ git add . newrepo$ git commit -m "Import clean version of my code" newrepo$ git fetch ~/oldrepo master:old-master
如果你对Git的年纪比1.6.5
git replace
,更换裁判在1.6.5加入,所以你必须使用被称为老,少了几分灵活的机制移植 ,它允许您为给定提交指定替代的父母。 取而代之的是的git replace
命令,运行:
echo $(git rev-parse master) $(git rev-parse old-master) >> .git/info/grafts
这将使它看起来,在当地,仿佛master
犯有old-master
承诺作为其母公司,所以你会看到比你多一个犯git replace
。
上述布赖恩的答案似乎是完整的,知识渊博,又有点复杂。
最简单的(IER)的解决办法是保持两个储存库。
你的工作在一个私人github上存储库。 你做的所有全历史推到仓库。
第二个仓库只有当你想“释放”的新版本向公众发布其公共GitHub的仓库。 您可以通过使用简单的差异+补丁发布到它,然后提交+推。
一个非常简单而有趣的这样做的方法是如下 -
假设你有REPO-A犯的C1〜C10,其中C1为初始提交和C10是最新的HEAD。 而你要创建一个新的REPO-B,使得其具有提交C4到C8(子集)。
注意:使用此方法会改变提交的SHA(如:C4'至C8'在这种情况下),但每个提交更改持有将保持不变,你的第一次提交,现在将与您的较早提交的,直到这一点,所有的变化开始结合。
该怎么办?
递归在你的本地计算机上的所有内容复制
cp -R REPO-A REPO-B
有选择地删除从REPO-B的所有遥控器,因为很可能你想用这个作为一个单独的存储库。
cd REPO-B
git remote -v
git remote remove REMOTE_NAME
部队的分支指针移动到你的子集的后结束。 对于受C4到C8,这将是C8。 但最有可能的,你需要的子集,直到HEAD(如:表格C4-C10的或C6到C10),在这种情况下不需要下面的步骤。
git checkout -b temp
git branch -f master C8
git checkout master
git branch -D temp
输入提交在该文件的子集的较早结束的SHA .git/info/grafts
目录。 在这种情况下,它是SHA的承诺C4。
git rev-parse --verify C4 >> .git/info/grafts
做一个Git分支过滤不带任何参数
git filter-branch
或者,它不工作
git filter-branch --all
现在,你可以把这个到一个单独的/新的远程,如果你想
git remote add origin NEWREMOTE
git push -u origin master
这个怎么运作?
此链接将告诉您如何它实际上真正起作用- http://git.661346.n2.nabble.com/how-to-delete-the-entire-history-before-a-certain-commit-td5000540.html
你可以阅读在GIT中过滤器分支的移植物(1)手册页,在gitrepository布局(5)git仓库布局描述,并在gitglossary(7)一个git词汇表。
总之,在的.git /信息/移植物的每一行包括对象的SHA1 ID,接着其有效(接枝)父母的空间分隔的列表的。 因此,削减历史如提交a3eb250f996bf5e后,你需要把只含本SHA-1的.git /信息行/移植物文件,如:
$ git的REV-解析--verify a3eb250f996bf5e >> git的/信息/移植