GIT更改基本/根文件夹

时间:2013-07-01 20:44:12

标签: git rebase

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

澄清概念的一些例子。

我的存储库位于文件夹中:

c:\workspace\test\src\

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

我想将存储库移动到:

c:\workspace\test

从现在开始可以添加测试文件夹中保存旧存储库历史记录的所有更改。

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

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

可能吗?

我希望我解释的内容是可以理解的。

5 个答案:

答案 0 :(得分: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-branch rebasing命令使'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. 如果其他人在这个回购中与你合作,他们可能会遇到麻烦。确保他们将更改合并到第一个中,因为在您执行rebase后,他们很难将它们合并。
  3. 有关详细信息,请阅读Git Book中的“Making a Subdirectory the New Root”和“The Perils of Rebasing”部分。

答案 1 :(得分:0)

如果我理解你的问题,如果你从一个干净的git repo开始(git status说'没有提交,工作目录清理'),你只需要移动.git目录{ {1}}至c:\workspace\test\src\

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


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

如果是这种情况,您需要使用类似src

的内容完全重写您的Git存储库历史记录

答案 2 :(得分:0)

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

  1. c:\workspace\test\src重命名为c:\workspace\src
  2. 删除目录c:\workspace\test,这可能是空的
  3. c:\workspace\src重命名为c:\workspace\test
  4. git存储库通常不会跟踪其父目录,因此将存储库从一个位置移动到另一个位置应该是无害的。现在,无论您的存储库中包含硬编码路径的脚本/构建文件/任何内容都可能是完全不同的故事...

答案 3 :(得分: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检查配置中的绝对路径,以确认它们仍然有效。

答案 4 :(得分:0)

首先,克隆您的仓库,以便您可以单独处理它,以便原本保持原样,以防万一出现问题。

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

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

.gitignore

这将导致git检出repo中的每个提交,运行您的脚本,然后用最终结果替换commit。接下来,如果您有任何被忽略或未提交的文件,您将需要将它们复制到新仓库中的相应位置。检查以确保filter-branch具有预期效果,并且新repo看起来如何。确定您满意后,请删除git filter-branch --tree-filter c:\absolute\path\to\your\script ,然后将c:\workspace\test移至c:\sandbox

我更喜欢使用c:\workspace\test,而不是--tree-filter。效率较低(因为它必须检查每个提交而不是直接编辑索引),但我发现它更直观。如果需要,它还允许您更改仓库中的文件内容(可能更新绝对路径)。