move all files of current directory into subdirectory and maintain history
I just stumbled across this error message and apparently the solution is quite simple.
But first of all remember there is the mv
and the git move
.
The normal bash move usage is: mv * ./subDir
which will only produce a warning but still move your files.
Whereas the git mv
with the usage git mv * ./subDir
will produce the fatal error and abort the move:
fatal: can not move directory into itself, source=currentDir/subDir, destination=currentDir/subDir/subDir
The solution to make the git mv
work is simple:
git mv -k * ./subDir
The option -k
will simply skip all actions that would produce an error.
You need to enable Extended Globbing so you can use regular expressions.
If you're using bash
shell type this shopt
(shell option) command prior to executing the command featuring the glob:
$ shopt -s extglob
(you can also add this to your ~/.bash_profile
if you don't want type this every time)
Then you can use the following syntax:
$ git mv ./!(exclude_me|exclude_me) ./destination_folder
For example if this is your folder structure:
root
├── aardvark
├── contrib
| ├── folder1
| └── folder2
├── custom
| ├── folder1
| └── folder2
├── elephant
├── hippopotamus
└── zebra
And you run the following in the root
directory:
$ shopt -s extglob
$ git mv ./!(custom|contrib) ./contrib
You'll end up with this:
root
├── contrib
| ├── aardvark
| ├── elephant
| ├── folder1
| ├── folder2
| ├── hippopotamus
| └── zebra
└── custom
├── folder1
└── folder2
Add the -n
flag if you want to do a test run and make sure the command will execute without errors:
$ git mv -n ./!(exclude_me|exclude_me) ./destination_folder
Add the -k
flag to include files not under version control:
$ git mv -k ./!(exclude_me|exclude_me) ./destination_folder
If using zsh
shell, enable extended globbing in the following way and use ^
to negate the pattern.
$ setopt extendedglob
$ git mv ^(exclude_me|exclude_me) ./destination_folder
$ git mv ^exclude_me ./destination_folder
So, I got into the same problem and what did the job for me was
for file in $(ls | grep -v 'yourfolder'); do git mv $file yourfolder; done;