2015-06-12 6 views
0

Я пытаюсь идентифицировать все коммиты с сообщением, но не с [core]. Это мои неудачные попытки:git: идентифицировать все коммиты, не соответствующие шаблону

  1. Простой подход

    git rev-list --grep '^(?!(\[core\]).).+' "branch1...branch2" 
    
    • пустой результат
  2. Включить расширенный флаг

    git rev-list -E --grep '^(?!(\[core\]).).+' "branch1...branch2" 
    
    • Сообщение об ошибке fatal: command line, '^(?!(\[core\]).).+': Invalid preceding regular expression.

    • Похоже, что негативный прогноз не поддерживается git grep.

  3. Сравнивая список всех фиксаций в список тех, с тегом (cf. this answer):

    git rev-list "branch1...branch2" | grep -Fxv <(git rev-list -E --grep '^\[core\].+' "branch1...branch2") 
    
    • Результаты в sh: syntax error near unexpected token `('

PS: Я не могу перейти на Git 2.x, поэтому --invert-grep не является опцией

+0

Ошибка в трех - это пространство, которое вы добавили между '<' и '('. Удалить это. Но если это регулярное выражение не работает с 'rev-list' в первых двух попытках, почему вы думаете, что это сработает в третьей попытке? –

+0

ой, я фактически использовал отрицательный эквивалент в третьей попытке. e проблема, когда вы пытаетесь предоставить минимальный пример для своего вопроса, а не вашу оригинальную проблему :-). Удаление пространства ничего не изменило – PhilLab

+1

Какую оболочку вы используете? '<(...)' является замещением процесса и должно работать нормально в bash, но не будет в ash/dash/csh/etc. –

ответ

1

Что-то вроде этого может работать.

git rev-list "branch1...branch2" --not $(git rev-list --grep '^\[core\]') 

Выбрать ревизии в этом списке, которые соответствуют шаблону вы не хотите, и затем использовать --not отрицать, что список изменений в другом вызове rev-list.

Вы также могли бы избежать замены процесса в вашей третьей попытки, используя фактический файл, как это:

git rev-list -E --grep '^\[core\].+' "branch1...branch2" > core.list 
git rev-list "branch1...branch2" | grep -Fxvf core.list 
+0

Это приводит к тому, что вариант использования git rev-list ('' --not'' кажется неизвестным), а затем хэши всех коммитов в диапазоне. Какая версия git необходима для этого? Сейчас я должен оставаться ниже 2.0. – PhilLab

+1

Я использую 1.8.2.1, но это также помогает в 1.7.1. Какую версию ты используешь? Но в быстрой проверке теории этот список, возможно, не совсем корректно, и я не уверен, почему. –

+0

Теперь я решил проблему, используя файл bash (см. Http://stackoverflow.com/a/30829547/1531708), но поскольку я не полностью удовлетворен, я все еще оставляю этот вопрос без ответа. – PhilLab

0

Если он соответствует вашим требованиям, использовать пакетный файл, это одно решение:

#!/bin/sh 
range="branch1...branch2" 
validCommits=`git rev-list -E --grep '^\[core\]' "$range"` 
badCommits=`git rev-list "$range" | grep -Fxv "$validCommits"` 
+0

На самом деле это не работает? Это не будет игнорировать любой из коммитов правильно, потому что вы даете grep только один аргумент (из всех коммитов, разделенных символами новой строки, как поисковый запрос). –

+0

Это действительно сопоставимо с вашим вторым решением, и причина, по которой он работает, заключается в том, что $ validCommits - это новый список списков, связанных с новой строкой. Обертывание его с помощью '' '' сохраняет их, а 'grep -Fx' разрешает сопоставление по каждой строке – PhilLab

+0

Это, безусловно, похоже на работу, хотя я не могу на всю жизнь понять, почему. '-x' означает, что совпадения (из шаблона) должны совпадать со всей строкой в ​​исходном тексте. Я не вижу, что приводит к тому, что grep разбивает входные данные на строки так, чтобы они могли сопоставляться независимо друг от друга ... если это не случайность или побочный эффект индивидуального характера того, как матчи работают в grep. Но хорошо. –