'Use git filter-repo to move a subdirectory to root while retaining files in root

I am attempting to split up a repository that contains a client and server into two repositories, and I want to move the respective folders to the root while also keeping the files I already had in root - project readmes, .gitlab-ci.yml, .gitignore, .gitattributes` and so on.

I tried the following line with no luck:

git filter-repo --path .gitattributes --path .gitignore [...] --subdirectory-filter server

The result was something I still don't quite understand; the subdir filter seemed to have worked, but whole commits full of changes ended up missing. The above clearly wasn't the correct way to do this, assuming there even is a correct way.

I hacked my way out of it by using separate calls with --path-rename-match to first move the root files to the server subdir so that they would be moved back to root by a final call with --subdirectory-filter server, but that doesn't seem right at all.



Solution 1:[1]

If I understand you correctly, you have something similar to the following project structure.

client/
server/
.gitlab-ci.yml
.gitignore

If you want to extract the client and server directories each to a dedicated project but retain the files in the root directory for each, you could use the --invert-paths option.

Using a fresh clone of the original, remove the server directory, set the origin to the new client project and push to the main branch.

git filter-repo --path server --invert-paths

Take a new clone of the original, remove the client directory, and push to the new server project.

git filter-repo --path client --invert-paths

If you want to update the path, use --path-rename. This could be used to rename a child directory or to move a child directory up in the hierarchy. For example, if you wanted to remove the enclosing server directory and move the content to the root of the project.

git filter-repo --path-rename server/foo:foo

Depending on your structure there are probably more elegant ways to achieve what you're looking for, but a combination of the above should solve for your use case.

Don't forget to process and push any tags you might have as well.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gofestive