2014-09-20 5 views
0

Я хотел бы неинтерактивно удалить нечистые коммиты, содержащие ключевое слово из моей истории (аналогично интерактивной перестановке, где строки, содержащие ключевое слово, удаляются).git remove совершает неинтерактивно

nocommit Функция в ~/.gitconfig достигает почти того, что я хочу, за исключением того, что создается новая результирующая ветвь.

nocommit = "!f() { \ 
    for i in `git log --oneline FETCH_HEAD.. |grep NOCOMMIT | awk '{ print $1 }'`; \ 
    do \ 
     git log -n1 --oneline $i; \ 
     git rebase --onto $i^ $i HEAD; \ 
    done; \ 
}; f" 

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

Edit: решаемые с помощью этой команды (Вдохновленный ответ от Andrew C):

GIT_EDITOR="sed -i '/NOCOMMIT/d'" git rebase -i @{upstream} 
+0

Возможный дубликат [Использование git filter-branch для удаления коммитов по их сообщению фиксации] (http://stackoverflow.com/questions/4558162/using-git-filter-branch-to-remove-commits-by-their -commit-message) – Jubobs

+0

Я боюсь, что это не гарантировано неинтерактивным. Всякий раз, когда вы удаляете фиксацию из истории, существует риск возникновения конфликтов, и они должны быть разрешены в интерактивном режиме. –

ответ

1

Несколько замечаний.

Вы бегаете по оборотам, от новейших до самых старых. Причина rebase от старейшего к новейшему заключается в том, что вы обрабатываете только один раз один раз.

Первая строка вашего сценария, вероятно, лучше записать в виде

for i in `git rev-list --grep=NOCOMMIT @{u}..HEAD` 

Использование FETCH_HEAD не является хорошим способом ограничить коммиты, и имеющие трубы к Grep и AWK не нужны.

Чтобы сделать его более сбалансированным, как если бы вам пришлось отслеживать ORIG_HEAD, проверьте новую ветку от git merge-base ORIG_HEAD ${u}, а затем пройдите через коммиты от самых старых до новейших (--реверсией), вишневый выбор любого, у которого не было NOCOMMIT в них, а затем обновить ветвь в конце.

Другим вариантом было бы обмануть интерактивную переработку, выполняя то, что вы хотите, сэкономив настройки редактора и заменив ее скриптом, который просто удалил строки, содержащие NOCOMMIT. Таким образом, у вас будет обычный вызов git rebase -i, но вместо получения окна редактора sed просто удалит коммиты, которые вам не нужны, и это будет продолжаться.

+0

Задание альтернативного редактора для rebase -i кажется привлекательным, но по какой-то причине я не смог заставить его работать: GIT_EDITOR = "grep -v NOCOMMIT" git rebase -i HEAD ~ 5 – badeip

+2

grep не собирается сохранять результирующий файл. попробуйте 'sed -i '/ NOCOMMIT/d'' –

+0

А, конечно. sed -i отлично работает. – badeip

Смежные вопросы