5

我有一个很长(约 2 年)的存储库,其中包含很多提交/分支,现在由于某些原因,我需要将存储库的根文件夹更改为上面的一个文件夹。

一些例子来阐明这个概念。

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

c:\workspace\test\src\

所以在我的回购中有上述文件/子文件夹中的所有更改。

我想将存储库移动到:

c:\workspace\test

从现在开始能够在维护旧存储库历史记录的测试文件夹中添加所有更改..

所以所有在文件夹中标记的旧提交"\",现在应该在文件夹中检查"\src"

对于旧的提交,我可以或不可以(这真的没关系)文件夹的实际内容..

那可能吗?

我希望我解释的内容可以理解..

4

5 回答 5

3

我认为您的意思是您的仓库的顶级目录是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-branchrebasing 命令将 '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. 如果其他人在这个 repo 上与你合作,他们可能会遇到很多麻烦。确保他们首先将他们的更改合并,因为在您执行 rebase 之后他们将很难将它们合并。

有关更多信息,请阅读 Git Book 中的“使子目录成为新根”和“变基的风险”部分。

于 2014-05-15T01:41:02.287 回答
0

首先,克隆您的存储库,以便您可以单独处理它,并且您的原始存储库保持完整,以防这里出现任何问题。

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

编写一个脚本,在任何一次提交时进行适当的更改。我不熟悉 Windows 脚本,但您会希望您的脚本创建一个名为src( ie, c:\sandbox\src ) 的新子目录,然后将除该.git目录和任何.git*文件 ( eg, .gitignore ) 之外的所有内容移动到该新子目录中。确保您的脚本在 repo 中的任何提交上都能正常工作,而不仅仅是在当前状态下。然后运行:

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

这将导致 git 检查 repo 中的每个提交,运行您的脚本,然后将提交替换为最终结果。接下来,如果您有任何被忽略或未提交的文件,您需要将它们复制到新存储库中的适当位置。检查以确保 filter-branch 具有预期的效果,并且新的 repo 看起来像你想要的那样。确定自己满意后,删除c:\workspace\test然后c:\sandbox移至c:\workspace\test.

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

于 2015-03-28T18:10:13.967 回答
0

听起来你应该只需要这样做:

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

git存储库通常不会跟踪其父目录,因此将存储库从一个地方移动到另一个地方应该是无害的。现在,无论您的存储库中可能包含硬编码路径的任何脚本/构建文件/任何内容,都可能是完全不同的故事......

于 2013-07-01T21:13:37.070 回答
0

如果我正确理解你的问题,如果你从一个干净的 git repo 开始(git status说'没有提交,工作目录干净'),你只需将.git目录c:\workspace\test\src\c:\workspace\test\.

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


重新阅读问题让我觉得您可能希望在src子目录中提供旧的提交

如果是这种情况,您需要使用类似的东西完全重写您的 Git 存储库历史记录git filter-branch --tree-filter '...'

于 2013-07-01T20:50:01.597 回答
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 文档中关于让它在 tmpfs 上完成工作的建议可能是值得处理的两年历史。

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

于 2014-05-15T03:22:18.113 回答