How can I move a directory and files to a sub-directory along with commit history?
For example:
Source directory structure:
[project]/x/[files & sub-dirs]
Target directory structure:
[project]/x/p/q/[files & sub-dirs]
How can I move a directory and files to a sub-directory along with commit history?
For example:
Source directory structure: [project]/x/[files & sub-dirs]
Target directory structure: [project]/x/p/q/[files & sub-dirs]
To add to bmargulies's comment, the complete sequence is:
Try it first to see a preview of the move:
Wolfgang comments:
Captain Man reports in the comments having to do:
Context:
As an alternative, spanky mentions in the comments the
-k
option ofgit mv
:That would avoid the "
can not move directory into itself
" error.The git mv command is the simplest way. However, at least on my Linux box, I needed to supply the -k flag to avoid getting an error back that a folder cannot be moved into itself. I was able to perform the action by using...
As a warning, this will skip all moves which would lead to an error condition, so you will probably want to check that everything worked properly after the move and before a commit.
Git does a very good job to track content even if it is moved around, so
git mv
is clearly the way to go if you move files because they used to belong inx
, but now they belong inx/p/q
because the project evolved that way.Sometimes, however, there is a reason to move files to a subdirectory throughout the history of a project. For example if the files have been put somewhere by mistake and some more commits have been made since, but the intermittent commits don't even make sense with the files in the wrong place. If all that happened on a local branch, we want to clean up the mess before pushing.
The question states "along with commit history", which I would interpret as rewriting the history in exactly that way. This can be done with
The files then appear in the
p/q
subdirectory throughout the history.Please note that the result should not be pushed to a public server if the rewrite touches commits which were already pushed before.
I can see this is an old question, but I still feel obliged to answer With my current solution to the problem, that I have derived from one of the examples in the git book. In stead of using an inefficient
--tree-filter
I move the files directly on the index With an--index-filter
.this is a specialization of one of the examples from the book I've also used the same example to mass rename files in the commit history in one special case. if moving files in subdirectories: remember to escape the / character in the paths With a \ to make the sed command work as expected.
Example:
to move the b directory to the project root:
Result: