只使用本地存储库历史记录的一部分创建GitHub存储库 [英] Creating GitHub repository with only a subset of a local repository's history

查看:73
本文介绍了只使用本地存储库历史记录的一部分创建GitHub存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:我正在接近打开采购个人研究代码我已经工作了两年多。它开始作为一个SVN仓库的生活,但我大约一年前转移到Git,我想在GitHub上分享代码。然而,这些年来它累积了很多的烦恼,我宁愿公开版本在其现状中开始其生活。但是,我仍然想为它做出贡献并纳入其他人的潜在贡献。



问题:有没有办法fork 一个git仓库,以便叉子上没有历史记录(位于GitHub上),但是我的本地仓库仍然有完整的历史记录,并且我可以将其推送到GitHub?



我在大型版本库的管理端没有任何经验,因此非常感谢详细信息。

解决方案

您可以在Git中轻松创建新的历史记录。比方说,你希望你的 master 分支是你将推送给GitHub的分支,并且你的完整历史将存储在 old-master 。您只需将您的主人分支到 old-master ,然后使用
$ b $ b

  git branch -m master old-master 
git checkout --orphan master
git commit -m导入我的代码的干净版本

现在您有一个新的 master 分支, ,你可以推送给GitHub。但是,正如您所说,您希望能够在本地存储库中查看所有旧的历史记录;并可能希望它不会被断开。



您可以使用 git replace 。替换ref是在Git查看给定提交时指定备用提交的一种方式。因此,在查看历史记录时,您可以告诉Git查看旧分支的最后一次提交,而不是新分支的第一次提交。为了做到这一点,你需要从旧的回购中引入已断开的历史记录。

  git替换master old-master 

现在您拥有了新的分支,您可以在其中查看所有历史记录,但实际提交对象与旧的历史记录断开连接,因此您可以将新的提交推送到GitHub,而不需要提交旧的提交。将你的 master 分支推送到GitHub,并且只有新的提交将会转到GitHub。但看看 gitk git log 中的历史记录,您将看到完整的历史记录。

  git push github master:master 
gitk --all
$ b

难题



如果您曾经在旧提交中创建任何新分支,你必须小心保持历史的独立;否则,在这些分支上的新提交在他们的历史中确实会有旧的提交,所以如果你把它推到GitHub上,你会把整个历史一起拉下来。不过,只要你保留所有基于新的 master> 的新提交,就没问题。



<如果你曾经运行 git push --tags github ,那么将会推动你的所有标签,包括旧标签,这会导致你的所有旧历史记录被拉用它。你可以通过删除所有旧标签( git tag -d $(git tag -l))或者从不使用 git推--tags ,但只能手动推送标签,或者使用两个存储库,如下所述。



这两个陷阱的基本问题如果你推动任何连接到任何旧历史的ref(除了通过替换的提交),你将会推高所有的旧历史。可能避免这种情况的最好方法是使用两个存储库,一个只包含新提交,另一个包含旧历史和新历史,以便检查完整的历史记录。你只需要新的提交就可以完成所有的工作,你的承诺,你从GitHub的推动和拉动,这样,你不可能不小心推动你的旧提交。然后,当您需要查看整个事件时,您将所有新提交放入具有完整历史记录的回购中。您可以从GitHub或您的其他本地回购中取出,以较方便的为准。这将是你的档案,但为了避免意外地发布你的旧历史,你永远不会从它推送到GitHub。以下是您可以设置的方式:

 
〜$ mkdir newrepo
〜$ cd newrepo
newrepo $ git init
newrepo $ git pull〜/ oldrepo master
#现在newrepo只是新的历史;我们可以设置oldrepo从它拉
newrepo $ cd〜/ oldrepo
oldrepo $ git remote add newrepo〜/ newrepo
oldrepo $ git远程更新
oldrepo $ git分支 - -set-upstream master newrepo / master
#...在newrepo中工作,提交,推送到GitHub等
#现在,如果我们想查看oldrepo中的完整历史记录:
oldrepo $ git pull

如果您使用的是1.7.2以上的Git



您没有 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导入我的代码的干净版本
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 commit将 old-master commit作为它的父项,所以您会看到比 git replace


The background: I'm moving closer to open sourcing a personal research code I've been working on for more than two years. It started life as an SVN repository, but I moved to Git about a year ago, and I'd like to share the code on GitHub. However, it accumulated a lot of cruft over the years, and I'd prefer that the public version begin its life at its current status. However, I'd still like to contribute to it and incorporate other people's potential contributions.

The question: is there a way to "fork" a git repository such that no history is retained on the fork (which lives on GitHub), but that my local repository still has a complete history, and I can pull/push to GitHub?

I've not any experience on the administrating end of large repositories, so detail is very much appreciated.

解决方案

You can create a new, fresh history quite easily in Git. Lets say you want your master branch to be the one that you will push to GitHub, and your full history to be stored in old-master. You can just move your master branch to old-master, and then start a fresh new branch with no history using git checkout --orphan:

git branch -m master old-master
git checkout --orphan master
git commit -m "Import clean version of my code"

Now you have a new master branch with no history, which you can push to GitHub. But, as you say, you would like to be able to see all of the old history in your local repository; and would probably like for it to not be disconnected.

You can do this using git replace. A replacement ref is a way of specifying an alternate commit any time Git looks at a given commit. So you can tell Git to look at the last commit of your old branch, instead of the first commit of your new branch, when looking at history. In order to do this, you need to bring in the disconnected history from the old repo.

git replace master old-master

Now you have your new branch, in which you can see all of your history, but the actual commit objects are disconnected from the old history, and so you can push the new commits to GitHub without the old commits coming along. Push your master branch to GitHub, and only the new commits will go to GitHub. But take a look at the history in gitk or git log, and you'll see the full history.

git push github master:master
gitk --all

Gotchas

If you ever base any new branches on the old commits, you will have to be careful to keep the history separate; otherwise, new commits on those branches will really have the old commits in their history, and so you'll pull the whole history along if you push it up to GitHub. As long as you keep all of your new commits based on your new master, though, you'll be fine.

If you ever run git push --tags github, that will push all of your tags, including old ones, which will cause all of your old history to be pulled along with it. You could deal with this by deleting all of your old tags (git tag -d $(git tag -l)), or by never using git push --tags but only ever pushing tags manually, or by using two repositories as described below.

The basic problem underlying both of these gotchas is that if you ever push any ref which connects to any of the old history (other than via the replaced commits), you will will push up all of the old history. Probably the best way of avoiding this is by using two repositories, one which contains only the new commits, and one which contains both the old and new history, for the purpose of inspecting the full history. You do all of your work, your committing, your pushing and pulling from GitHub, in the repo with just the new commits; that way, you can't possibly accidentally push your old commits up. You then pull all of your new commits into your repo that has the full history, whenever you need to look at the entire thing. You can either pull from GitHub or your other local repo, whichever is more convenient. It will be your archive, but to avoid accidentally publishing your old history, you don't ever push to GitHub from it. Here's how you can set it up:

~$ 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

If you're on Git older than 1.7.2

You don't have git checkout --orphan, so you'll have to do it manually by creating a fresh repository from the current revision of your existing repository, and then pulling in your old disconnected history. You can do this with, for example:

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

If you're on Git older than 1.6.5

git replace and replace refs were added in 1.6.5, so you'll have to use an older, somewhat less flexible mechanism known as grafts, which allow you to specify alternate parents for a given commit. Instead of the git replace command, run:

echo $(git rev-parse master) $(git rev-parse old-master) >> .git/info/grafts

This will make it look, locally, as if the master commit has the old-master commit as its parent, so you will see one more commit than you would with git replace.

这篇关于只使用本地存储库历史记录的一部分创建GitHub存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆