Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git-filter-branch: leave directory structure unchanged

Tags:

git

I have a directory structure in my repository:

|-repository/
|  |  |-repository/fileOne
|  |
|  |-subOne/
|  |  |-subOne/fileTwo
|  |
|  |-subTwo/
|     |-subTwo/fileThree

I want to move the directory subOne into a different repository. To do that, I'm separating subOne using git-filter-branch like so:

$ git filter-branch --subdirectory-filter subOne --prune-empty

This leaves me with a branch history that looks like this:

$ git log --oneline
0c0ea11 subOne history
6318bba subOne history
c96fddb Initial commit

This is exactly what I want; from another repository I can do a git fetch and git merge, which adds subOne and history into the other repository. That's great.

However, git-filter-branch has removed subOne. Checking the directory structure on my branch:

$ ls
fileOne
$ pwd
/this/is/a/path/repository

pwd should read: /this/is/a/path/repository, but ls should show subOne inside the repository. What I've got instead is the files from subOne moved upwards, and the directory removed.

How can I extract subOne without losing the directory?

like image 663
simont Avatar asked Mar 01 '12 16:03

simont


1 Answers

pwd should read: /this/is/a/path/repository, but ls should show subOne inside the repository. What I've got instead is the files from subOne moved upwards, and the directory removed.

It turns out this is the default operation of git-filter-branch --subdirectory-filter. Quoting from man git-filter-branch:

The result will contain that directory (and only that) as its project root.

To fix this, I want to shift everything in / to /subdirectory. Luckily, there's a piece of voodoo-looking code in man git-filter-branch, under EXAMPLES:

To move the whole tree into a subdirectory, or remove it from there:
       git filter-branch --index-filter \
               'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
                       GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                               git update-index --index-info &&
                mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

EDIT: THIS WILL NOT WORK ON MAC OS X. See my question here for more information. BSD sed is not the same as GNU sed, which is annoying. To run that example on OS X, change sed to gsed; the filter then works quite well.

like image 100
simont Avatar answered Sep 20 '22 01:09

simont