Move files / folders from one git repo to another

2019-09-17 19:47发布

I have an existing repository with folders and files on Github and I have just created four new repositories.

I wish to distribute the files/folders in the existing repository into the new repositories I have just created.

Is there a way I can do this using either the GUI or CMD (Macbook)?

标签: macos git github
1条回答
相关推荐>>
2楼-- · 2019-09-17 20:02

I don't know if there's any way to do it with a GUI.

If the things you want to extract are contained in their own folders, it's pretty easy on the command line. One method using git filter-branch --subdirectory-filter is explained here:

https://stackoverflow.com/a/12818479/955926

If your files and folders are not so nicely contained, or don't match a simple pattern (i.e. keep only the *.py files, etc), one method - which I call 'grooming' - is to just keep running simple filter-branch commands - on a clone, not the original! - to keep stripping away parts of it, until your history only contains what you want.

Of course, we always want to be able to verify what we're doing. This will show a sorted, uniqued listing of all the relative file/folder paths that have ever existed in your repo:

$ git log --pretty='format:' --name-only | grep -v '^$' | sort -u

Let's say in that list you see foo and bar/baz folders that you want gone from history (i.e. get rid of baz, which is in bar, and foo):

$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch foo bar/baz'

Now you can run the previous log command to verify that those links don't exist anywhere in time, and choose more things from that smaller list to get rid of. Or you can stick every path into that one call to filter-branch. I just feel better taking smaller steps and verifying, in the same way that I'm more comfortable committing granularly.

Filter-branch makes a backup each time through, and the second run would be halted by its existence. That's what the -f is for. You'll be overwriting your backup each time you filter again, but it's okay, because you're doing this on a clone (right!?), and you can always do it again on a new clone if you screw up very badly.

In the end you'll want to clear out the refs/original/* heads, which will point to the last head of the branch you're filtering after each pass. If you filter-branched the master branch, you'd have a refs/original/refs/heads/master file pointing to the old head of master, pre-filtering. When you force the next pass, you'll be pointing to that to the new one. If for some reason you want to keep pointers to each backup after each filtering, just drop a branch or tag at those 'original' refs after each pass. Or drop a tag/branch before filtering, or just use the reflog.

查看更多
登录 后发表回答