2016-04-27 4 views
0

Я пытаюсь использовать ветвь git filter и разрешить ввод в действие моей внутренней фиксации, состоящей из .gitignore (переустановленного в ветку впоследствии).git filter-branch, который уважает мои первоначальные коммиты .gitignore

Это то, что я бегу:

git filter-branch -f --tree-filter 'git rm -r --cached . && git add .' --prune-empty 

Эта команда, однако оставляет репозиторий без изменений.

Почему?

Я также задаюсь вопросом, почему следующая команда не удаляет все файлы в хранилище:

git filter-branch -f --tree-filter 'git rm -r --cached .' 

ответ

2

--tree-filter не работает на/с индексом. Вместо этого он копирует каждую фиксацию во временную директорию, используемую в качестве рабочего дерева, запускает вашу команду во временном каталоге и делает новый коммит из всех оставшихся файлов и/или является новым во временном каталоге. Изменения, которые вы делаете для самого индекса во время этого процесса, фактически игнорируются.

Это означает, что вы должны удалить из дерева именно те файлы, которые ваш новый .gitignore не смог добавить. Вы можете сделать это вручную с помощью git rm --cached в --index-filter, что было бы намного быстрее, но если вы хотите получить git, чтобы выполнить работу для вас в --tree-filter, вы можете использовать тот же самый трюк git, который использует (см. Сноску): use git clean-x), чтобы очистить временный каталог.


Это не совсем верно: --tree-filter кода filter-branch «s использует git read-tree для заполнения индекса до (ре) Наполнение временного каталога (который, в свою очередь, означает, что он должен сделать какую-то работу, чтобы вычистить временный каталог из предыдущих коммитов, для которого он использует git clean). Затем, после фильтра eval, он снова использует индекс для проверки того, что было сделано во временном каталоге. Когда вы git rm -r --cached ., а затем git add ., он сравнивает результирующий индекс, который больше не имеет ваших проигнорированных файлов, к дереву рабочих и ... добавляет ваши проигнорированные файлы. Argh!

0

Это решение работает, за исключением того, что не поддерживает пробелы в именах файлов:

git filter-branch -f --tree-filter 'ls -r | xargs --no-run-if-empty \ 
git check-ignore --no-index | xargs --no-run-if-empty rm' --prune-empty 

Он также производит чрезвычайно длинные линии к git check-ignore, а именно список всех файлов в рабочем каталоге (рекурсивный). Can't git check-ignore дескриптор рекурсивности сам по себе? И пробелы в именах файлов, как их поддерживать?