2012-08-29 1 views
5

У меня есть проект агента SNMP, в котором вместе с ним были разработаны связанные файлы MIB (файлы * .smiv2), но теперь я хочу, чтобы они были в отдельный репозиторий git.Правильный способ удаления нежелательных файлов с помощью git filter-branch без git rm failing

Чтобы не потерять ни одну из истории файлов MIB, поскольку они не запускались в том же каталоге, что и сейчас, я не мог использовать только фильтр-ветвь --subdirectory-filter, поэтому я попытался использовать метод --filter-index, основанный на this question. Идея заключалась бы в том, чтобы удалить каждый файл, который не заканчивается .smiv2 (очевидно, на новом клоне исходного проекта, который должен быть перенесен на мой новый MIB-репо к концу процесса).

Чтобы сделать это проще, я выбрал с помощью ls-files над ls-tree, поэтому вместо того, чтобы:

git filter-branch --prune-empty --index-filter 'git ls-tree -r --name-only \ 
--full-tree $GIT_COMMIT | grep -v ".smiv2$" | xargs git rm --cached \ 
--ignore-unmatch -r' 

Я использовал это:

git filter-branch --prune-empty --index-filter 'git ls-files | \ 
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch' 

но ни один из них не удалось в первом совершить, так как оно появляется git rm не было никаких аргументов вообще (я полагаю, --ignore-unmatch будет работать нормально, если предоставленные аргументы не найдены, но не в том случае, если аргументы не указаны):

$ git filter-branch --prune-empty --index-filter 'git ls-files | \ 
>  grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch' 
Rewrite 4cd2f1c98dbaa96bc103ae81fbd405bd1d991d9a (1/418)usage: git rm [options] [--] <file>... 

    -n, --dry-run   dry run 
    -q, --quiet   do not list removed files 
    --cached    only remove from the index 
    -f, --force   override the up-to-date check 
    -r     allow recursive removal 
    --ignore-unmatch  exit with a zero status even if nothing matched 

index filter failed: git ls-files | \ 
    grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch 

Я получил это работает оберточную git rm в скрипте, который возвращает успех, даже если он выходит из строя из-за отсутствие аргументов (сохранил его в /usr/local/bin/gitrm_alt):

#!/bin/sh 
git rm --cached --ignore-unmatch "[email protected]" 
exit 0 

, а затем вызов, что вместо git rm:

git filter-branch --prune-empty --index-filter 'git ls-files | \ 
    grep -v ".smiv2$" | xargs gitrm_alt' 

но я обнаружил, что очень уродливый и неуклюжий, поэтому я хотел бы спросить, есть ли более прямой/правильный способ сделать это.

+0

Почему бы не передать дополнительный фиктивный аргумент, который никогда не существует для 'git rm --ignore-unmatched', например. '| xargs rm --cached --ignore-unmatched DoesNotExistInMyProject'? –

+0

Хехе .. отлично @ Чарльз Бейли, как я не мог этого видеть? Разве вы не хотите превратить это в ответ, чтобы я мог принять его? Благодаря! – Claudio

ответ

7

Простейшим решением было бы добавить фиктивный аргумент в git rm, чтобы он всегда имел как минимум один параметр файла.

E.g.

... | xargs git rm --cached --ignore-unmatch DoesNotExistInMyProject 
2

Полный ответ, для дальнейшего использования

git filter-branch --prune-empty --index-filter 'git ls-files | \ 
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch DoesNotExistInMyProject' 
2

xargs «ы -r | --no-run-if-empty флаг может быть чище:

... | xargs--no-run-if-emptygit rm --cached --ignore-unmatched

0

-I переключатель также может быть использован.

some command | xargs -I % rm %