将git存储库上移一个层次结构级别


77

Git初学者问题:

我有一个小型私人Web项目,使用msysgit在本地进行版本控制。没有外部存储库,因为它仅适合我,因此我可以基本地做我想做的任何事情。

我已经在项目目录(即“ webroot”)中进行了设置。

现在必须创建第二个目录,该目录与webroot平行。我们称之为资产。

现在的结构如下:

\ project directory
----\webroot
----\assets

我很乐意将此新目录包括在git存储库中,以便对存储在其中的文件进行版本更改,但当然不能使用“ git add ../assets”。我也不希望在project_directory中创建一个新的git项目,因为这会丢失我之前的所有提交。

那么,如何在保持提交并包含“资产”的同时,将存储库从“ webroot”移到“ project_directory”?


不完全是您的要求,但是您可以创建一个分支,向其中添加资产。
L先生

Answers:


75

因此,您希望您的git repo看起来像这样:

<projectdir>
    /.git
    /webroot
    /assets

要做到这一点,必须将现有的文件在您的回购到一个新的webroot子目录。

cd <git repo root>
mkdir webroot
git mv <all your files> webroot
git commit --all -m "moved all existing files to new 'webroot' directory"

然后,在您的本地文件系统上,您想要将克隆目录移到现在所在目录的上方:

cd <projectdir>
mv webroot/* .
rmdir webroot

然后,您要将assets目录(和文件)添加到git repo中:

git add assets
git commit -m "added assets to the repo"

2
好的,显然我没有提供足够的信息。该存储库已经位于/ projectdir / webroot /中,因为它是最初创建的位置。由于资产目录通过了,如果存储库的行为就像是在/ projectdir /中创建的一样,我会更喜欢它,可惜不是。git mv不允许我将文件移动到存储库之外。
Sorcy 2011年

@Sorcy:我相信我知道你想做什么。我更新了答案以澄清它。
蒂姆·海尼根2011年

谢谢,这正是我一直在寻找的解决方案。:)
Sorcy 2011年

2
我发现此解决方案还需要帽子mv webroot/.* .,以便移动repo和.gitignore文件。
katriel 2015年

git mv * webroot将不起作用,因为bash通配符*也将被webroot代替,使命令为git mv webroot webroot。Git会失败的。它遇到问题的另一个文件夹是.git。因此,我必须使用特殊的bash env变量,GLOBIGNORE=webroot:.git以便*不会被这两个目录替代。因此,我不必制作许多手动git mv-我的目录中有很多文件夹和文件。我只需要手动移动.git文件夹。
Koshmaar '16

18

您也可以只将.git目录上移并更新工作树。

cd projectdir
mv ./webroot/.git ./.git
git config core.worktree /absolute-path-to-project-dir
git add assets
git commit -m 'adding assets folder'

不是肯定的,但我很确定core.worktree的路径必须是绝对的。


这是对我有用的命令。当我要移动.git文件的文件夹中时: mv .git / ../
anevaude 2015年

我是在类似的情况下执行此操作的,因此我不得不将文件重新添加到在先前位置时已经添加的文件中。因此,从本质上讲,我认为我丢失了这些文件的git历史记录。
aneccodeal

11

我假设您打算重写历史记录以包含所有修订中的所有文件,就像它们始终位于子目录webroot /中而不是在根目录中一样

git filter-branch手册页提供了答案,这里是一个改进的版本,它重写了所有现有的ref(分支)和标签:

time git filter-branch --index-filter 'git ls-files -s |
         sed "s-\t\"*-&webroot/-" |
         GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && 
     mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' --tag-name-filter cat -- --all

采取了谨慎措施,使其成为仅索引操作,这样即使对于大型仓库,该过程也可以快速运行。请记住(满意时)摆脱原始参考文件(.git / refs / original / *)并重新打包存储库以释放过时的树对象。


2
您能解释一下如何摆脱原始引用并重新打包存储库吗?只是GC还是其他东西?
NateS

5

您的提交未本地绑定到git repo中存储的“ webroot”文件夹。

您可以简单地删除webroot目录,然后在新位置“ / project directory”中重新检出存储库,添加资产目录并提交。

rm -Rf webroot
git clone path-to-repo
git add assets 
git commit -m "Added assets directory"
git push

0

以下命令将重写您的Git历史记录。看起来好像内容一直webroot都在。通常,如果有多个人正在使用某个存储库,则重写历史记录会很麻烦。由于您是独自工作,因此应该没问题。

git filter-branch --index-filter '
    git read-tree --prefix="webroot/" $GIT_COMMIT && \
    git ls-files \
      | sed "s/\/.*//" \
      | sort \
      | uniq \
      | grep -v "^webroot" \
      | xargs -L1 git rm -r --cached > /dev/null'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.