Как передать диапазон коммитов в git log?

Хорошо, я сдаюсь, я нуб Баш.

Это:

$ git log --no-walk --oneline 6980e6ecede8e188f434f6da669c2297f28decfe 458567536c1f20498da033cb0e42da74439ef12e

печатает:

4585675 NNN bethDataFiles, allBethFiles belong to game/game/constants.py
6980e6e NNN bethDataFiles, allBethFiles belong to game/game/constants.py

Это:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

печатает мне ряд коммитов:

ba4ee4b099d23642e6cad56d9f41974f6e767781 1daaede0f4e11cae0e0bb00b9ebb43bba4f5671 ...

А теперь, зачем же эта команда отправлять в git log как:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' ' | git log --format='%h %s %ai' --no-walk

показывает только первый коммит:

ba4ee4b _load_active_plugins pre BAPI code - superseded by games.py API: 2016-04-14 19:38:41 +0200

?

$ git --version
git version 2.6.1.windows.1

3 ответа

Решение

Существует общая форма с утилитами bash и Unix:

... | ... | ... | xargs cmd

(xargs работает cmd несколько раз по мере необходимости после вставки стандартного ввода в качестве аргументов) или:

cmd $(... | ... | ...)

который запускает конвейер, а затем предоставляет свой вывод в качестве аргументов cmd,

Однако с git log вам это не нужно, так как он принимает --stdin чтобы он читал идентификаторы ревизий из стандартного ввода.

Я думаю, что мы можем упростить ваш конвейер (кстати, я не осознавал, что некоторые версии awk знают, как сравнивать даты напрямую; более старый awk этого не делал):

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' | \
    cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

Мы хотим, чтобы изменения были по одному на строку, поэтому нет необходимости tr, Мы также можем использовать оригинальный awk для проверки уникальности хеш-идентификатора. Так:

git log -g --pretty=format:'%ai %H' | \
    awk '$0 >= "2016-04-13" && $0 <= "2016-04-15" && !a[$4]++' | \
    git log --no-walk --stdin

Кстати, это только потому, что git log -g делает обход журнала (который может привести к дублированию хэшей), что нам нужен ассоциативный массив a отбросить повторяющиеся хеши.

git log не читает никаких входных данных со стандартного ввода. Попробуй сделать echo "abcd123" | git log --no-walk и вы заметите, чтоgit log будет игнорировать стандартный ввод Он будет искать хеш коммита, указанный в качестве аргумента, но его нет. Следовательно, он будет использовать заголовок по умолчанию и печатать последний коммит в вашей текущей ветке.

Чтобы напечатать диапазоны фиксации, вы можете, например, сделать:

Если вы знаете первый и последний коммит хеша:

git log abcd123..4567abc

Если вы знаете временной интервал:

git log --since="10 days ago" --until="5 days ago"

Или, если вы знаете конкретные даты:

git log --since="2016-04-13" --until="2016-04-15"
  git log --format='%h %s %ai' --no-walk \
       $(git log -g --pretty=format:'%ai %H' \
             | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'\
             | cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' '
        )

Или чуть лучше

  git log -g --pretty=format:'%ai %H' | \
        awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' |\
        cut -d' ' -f 4 | awk '!a[$0]++' | \
        xargs git log --format='%h %s %ai' --no-walk

Но мне интересно, почему вы не хотите использовать --since а также --until варианты git log?

Другие вопросы по тегам