Прежде всего, у вас есть опечатка в вашей команде. Это должно быть --before="$(...
, вам не хватает =
.
Поведение date
здесь не является проблемой. date +%Y-%m-01
вернет что-то вроде 2011-10-01
в виде строки, без дополнительной информации о времени. Таким образом, второй вызов даты уменьшит его на $i
количество месяцев, а также вернет строку в формате, подобном 2011-09-01
. Помимо этой строки никакая дополнительная информация не передается git-rev-list
как значение аргумента --before=
.
Есть некоторые вещи, которые вы должны рассмотреть, используя git-rev-list
:
- При использовании
HEAD
вы всегда имеете в виду ветку current . Поэтому, когда вы, например, извлекаете один из полученных идентификаторов фиксации, ваш HEAD изменится. Возможно, вы захотите использовать master
или любое другое имя ветви вместо ссылки.
- У Git нет временного порядка коммитов . Вы можете сделать коммит, созданный 1 августа иерархически, после коммита, датированного 1 сентября. Это приведет к путанице в выходных данных при использовании аргументов
--before
или --after
, поскольку они полагаются на метку времени поля коммиттера .
- Временная метка поля коммиттера также может вводить в заблуждение. Когда ваша ветвь не имеет линейной истории, трудно определить, была ли фиксация частью ветки в репозитории в определенный момент истории. Автор, возможно, сдвинул / слил свою ветку через X месяцев после выполнения коммита, поэтому он не был виден другим.
Учитывая все сказанное, у меня работает следующая команда:
$(git rev-list --after="$(date -d "$(date +%Y-%m-01) -$i months" +%Y-%m)-01 00:00:00" master | tail -n 1)
Возвращает идентификатор первого коммита после первого месяца. (Этот коммит не обязательно был сделан в течение этого месяца, возможно, в этом месяце коммитов не было).