2013-07-01 297 views
4

我有很多提交/分支的长期(〜2年)回购,现在由于某些原因,我需要将存储库的根文件夹更改为上面的一个文件夹。GIT更改基础/根文件夹

一些例子来澄清这个概念。

我有一个文件夹中存储库:

c:\workspace\test\src\ 

所以在我的回购在上述一个的文件/子文件夹的所有变化。

我想仓库移至:

c:\workspace\test 

是从现在开始,可以添加在测试文件夹mantaining老仓库的历史所有的变化..

因此,所有的老提交被标记在文件夹"\",现在应该在文件夹"\src"

检查旧提交我能或不能有(它其实并不重要)文件夹的实际内容..

是否有可能?

我希望我解释是可以理解的..

回答

0

如果我理解正确的话你的问题,如果你从一个干净的git仓库启动(git status说:“没有什么承诺,工作目录清洁”),你只需要将.git目录从c:\workspace\test\src\移至c:\workspace\test\

然后,您必须对新布局中的所有文件执行“大”提交。 Git将把这个新的提交视为一个重大举措。不需要新的内容,因为文件是相同的。 Git只会在他的.git目录中注册新的树型布局(使用src)。


重读这个问题让我觉得你可能希望有可用的旧提交的src子目录

如果是这样的话,你需要使用的东西完全重写你的Git仓库的历史一样git filter-branch --tree-filter '...'

+0

如果可能我不希望有一个新的'大'承诺,但更改在旧的根文件夹'\'与新的'\ src' ..但我不知道是否有可能 – Marcx

+0

谢谢你为你的编辑,这就是我想要的,我会稍后尝试,如果它的工作... – Marcx

+0

我试过,但没有运气,你能告诉我一个我需要使用的命令的详细示例?谢谢.. – Marcx

0

听起来像是你应该只需要做到这一点:

  1. 命名c:\workspace\test\srcc:\workspace\src
  2. 删除目录c:\workspace\test,这大概是现在空
  3. 重命名c:\workspace\srcc:\workspace\test

git仓库不一般保持它们的父目录的轨道,所以从一个地方移动在仓库到另一个应该是无害的。现在,无论脚本/构建文件/存储库中可能包含硬编码路径的任何内容都可能是完全不同的故事......

+0

不,我需要测试目录,并在测试目录中有一些文件,从现在开始应该包含在git仓库中... – Marcx

2

我认为您的意思是您的回购顶级目录是c:\workspace\test\,并且您希望c:\workspace\test\src\成为新的顶级目录。首先,检查是这种情况:

cd c:\workspace\test\src 
git rev-parse --show-toplevel #print repo top-level directory 

应该打印出类似这样c:\workspace\test\如果这是真的是你的顶级目录。

如果是,您可以使用git filter-branch重新绑定命令使'src'目录成为新的顶层。请小心,这是你真正想要做的,因为它会破坏性地修改你的旧历史!任何影响该分支的提交将被重新设置为包含src文件夹作为新的顶层。首先备份当前分支。

cd c:\workspace\test\ 
git branch oldRoot #this backs up your current branch to a new branch called "oldRoot"  
git filter-branch --subdirectory-filter src HEAD #this modifies your history 

警告!需要注意的是:

  1. 新的历史不会干净的应用,如果你有你的更改备份到远程,你将需要:
    1. 开始使用新的远程分支(更安全),或:
    2. 执行强制推送以覆盖远程历史记录。
  2. 如果其他人与你合作购买这个回购商品,他们可能会遇到一堆麻烦。确保他们在第一个合并他们的更改合并,因为他们将很难在您进行重新绑定后合并它们。

欲了解更多信息,请阅读Git Book中的“Making a Subdirectory the New Root”和“The Perils of Rebasing”部分。

0
git filter-branch --index-filter ' 
    git read-tree $(printf "040000 tree %s\tsrc\n" `git rev-parse HEAD:` | git mktree) 
    ' -- --branches --tags 
mv .git .. 
cd .. 

不要在这些命令中看到文档;用法非常简单。 filter-branch's docs关于如何使它在tmpfs上工作的建议在两年的历史中可能值得处理。

您可能想要grep -ri c.workspace.test .git检查配置中的绝对路径等,以验证它们仍然有效。

0

首先,克隆你的回购,以便你可以孤立地处理它,并保证你的原始文件完好无损,以防出现任何问题。

git clone --no-hardlinks c:\workspace\test\src c:\sandbox 

编写一个脚本,可以在任何单个提交时进行相应的更改。我不熟悉Windows的脚本,但你会希望你的脚本来创建一个名为src新的子目录(c:\sandbox\src),然后移动以外的所有.git目录和任何.git*文件(例如,.gitignore)成那个新的子目录。确保脚本在回购中的任何提交时都能正常工作,而不仅仅是在当前状态下。然后运行:

git filter-branch --tree-filter c:\absolute\path\to\your\script 

这将导致混帐签的回购每一次提交,运行脚本,然后替换最终结果提交。接下来,如果您有任何被忽略或未提交的文件,您需要将它们复制到新回购库中的相应位置。检查以确保过滤器分支具有预期的效果,并且新回购看起来如何您想要。一旦确定自己满意,请删除c:\workspace\test,然后将c:\sandbox移动到c:\workspace\test

我喜欢使用--tree-filter,如此处所示,而不是--index-filter。效率不高(因为它必须检查每个提交而不是直接编辑索引),但我觉得它更直观。如果需要,它还将允许您更改回购中的文件内容(可能更新绝对路径)。