将 Git 存储库向上移动到一个层次结构级别

Git 初学者问题:

我有一个小的私人网络项目,是版本与 msysgit 本地。没有外部存储库,因为它只适合我,所以我基本上可以做任何我想要的。

我已经在项目目录中设置了这个选项(在“ webroot”中)。

现在必须创建第二个目录,它与 webroot 并行。

现在的结构如下:

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

I'd love to include this new directory in the git repository, so that I'd also version changes to files stored there, but of course I can't use "git add ../assets". Neither am I inclined to create a new git project in project_directory, as this would loose all my previous commits.

那么,如何将存储库从“ webroot”移动到“ project _ directory”,同时保持提交,然后能够包含“ asset”呢?

36325 次浏览

So, you want your git repo to look like this:

<projectdir>
/.git
/webroot
/assets

To do this, you must move the existing files in your repo into a new webroot subdirectory.

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

Then, on your local filesystem you want to relocate your clone one directory above where it is now:

cd <projectdir>
mv webroot/* .
rmdir webroot

Then you want to add the assets directory (and files) to the git repo:

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

Your commits are not locally tied to the "webroot" folder they are stored within the git repo.

You could simply remove the webroot directory recheckout the repository in the new location "/project directory" add the assets directory and commit.

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

I assume you meant to rewrite the history to contain all the files in all revisions as if they had always been in a subdirectory webroot/ instead of in the root

The git filter-branch manpage has the answer, here an improved version that rewrites all existing refs (branches) and tags:

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

Care has been taken to make this an index-only operation so that the process will run fast even for big repos. Remember to (when satisfied) get rid of the original refs (.git/refs/original/*) and repack the repo to loose the obsolete tree objects.

You can also just move your .git dir up one level and update your worktree.

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

Not positive but I'm pretty sure the path to core.worktree has to be absolute.

The following command would rewrite your Git history. It would look like as if the content was in webroot all along. Usually rewriting history is troublesome if multiple people are working with a repo. Since you are working alone on it, it should be fine.

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'