Filter-branch для удаления дополнительной директории

Я переношу несколько репозиториев Subversion на Git, но они были настроены немного странно: стандартная структура trunk/branches/tags живет в нескольких подкаталогах репозитория./ветки и/теги являются пустыми, поэтому импорт git -svn завершился только с каталогами соединительных линий.

svn/
  proj1/
    trunk/
      src/
  proj2/
    trunk/
      src/

Я хотел бы использовать git filter-branch для удаления дополнительных папок для внешних линий, но остальное оставалось неизменным:

svn/
  proj1/
    src/
  proj2/
    src/

Основываясь на последнем примере в документации, это то, что у меня есть до сих пор:

git filter-branch --index-filter \
    'git ls-files -s | sed "s-/trunk/-/-" |
        GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
            git update-index --index-info &&
     mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

Мне кажется, что sed выполняет свою работу, так как этот ввод:

100644 fa3dcf79717e9aca85ad745078a2fb2a2ce2b900 0       proj1/trunk/src/file1.txt

Производит этот вывод:

100644 fa3dcf79717e9aca85ad745078a2fb2a2ce2b900 0       proj1/src/file1.txt

Однако, когда я запускаю всю команду, я получаю следующую ошибку:

Rewrite e00c119cfb755f741dc0e17c36d36bc2ddd27562 (1/42)mv: cannot stat `/c/dev/R
epo/.git-rewrite/t/../index.new': No such file or directory
index filter failed: git ls-files -s | sed "s-/trunk/-/-" |
            GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                git update-index --index-info &&
         mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"

Любые идеи? Я использую git версию 1.7.3.1.msysgit.0 в Windows.

Обновление: Теперь, используя git version 1.9.0.msysgit.0, аналогичная ситуация дает другую ошибку (примечание .git-rewrite не существует перед выполнением команды):

rm: cannot remove `c:/Path/to/svn/.git-rewrite/revs': Permission denied
rm: cannot remove directory `c:/Path/to/svn/.git-rewrite': Directory not empty

То же самое исправить в конечном итоге сработало.

Ответ 1

Выяснил это на основе комментария здесь. Кажется, проблема связана с тем, как git -svn представляет "пустой" (только для каталога). Он работает нормально, если я начинаю с обычной фиксации:

git filter-branch --index-filter \
    'git ls-files -s | sed "s-/trunk/-/-" |
        GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
            git update-index --index-info &&
     mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' 83df928c..HEAD

Ответ 2

Хм. Я не вижу ничего плохого в том, что вы используете, и он отлично работает для меня в репозитории примеров:

$ git init
Initialized empty Git repository in /Users/bcampbel/tmp/git-subdir/.git/
$ mkdir -p proj1/trunk
$ echo "hello" > proj1/trunk/test.txt
$ git add .
$ git commit -m "initial commit"
[master (root-commit) cd431f3] initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 proj1/trunk/test.txt
$ echo "foo" > proj1/trunk/another.txt
$ git add .
$ git commit -m "add a file"
[master 84139f2] add a file
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 proj1/trunk/another.txt
$ git filter-branch --index-filter \
>     'git ls-files -s | sed "s-/trunk/-/-" |
>         GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
>             git update-index --index-info &&
>      mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Rewrite 84139f26c7921721190b3c5dd57e2b49a41034aa (2/2)
Ref 'refs/heads/master' was rewritten
$ ls proj1/
another.txt test.txt

Похоже, что по какой-то причине файл index.new не был выписан в вашей системе или не мог быть прочитан командой mv. Я не уверен, почему это было бы, но мне интересно, может ли это быть связано с тем, что вы используете msysgit в Windows. У вас есть ящик Linux или Mac, на который вы можете попробовать?