Как я могу получить разницу между всеми коммитами, которые произошли между двумя датами с Git?


или просто все коммиты, которые произошли между двумя датами? В SVN, вы могли бы сделать что-то вроде

svn diff -r{date}:{date}

сделать это! Я не могу найти эквивалент Git для этого.

в частности, я смотрю на написание сценария для отправки ежедневных писем со всем кодом, совершенным в тот день и кем.

10 101

10 ответов:

вы могли бы использовать git whatchanged --since="1 day ago" -p

Это

предыдущие предложения имеют некоторые недостатки. В принципе, я искал что-то эквивалентное cvs diff -D"1 day ago" -D"2010-02-29 11:11". Собирая все больше и больше информации, я нашел решение.

вещи, которые я пробовал:

  • git whatchanged --since="1 day ago" -p С здесь

    но это дает diff для каждого коммита, даже если есть несколько коммитов в один файл. Я знаю, что "дата" - это немного свободная концепция в git, Я думал, что должно быть какой-то способ сделать это.

  • git diff 'master@{1 day ago}..master дает какое-то предупреждение warning: Log for 'master' only goes back to Tue, 16 Mar 2010 14:17:32 +0100. и не показывает все различия.

  • git format-patch --since=yesterday --stdout ничего не дает для меня.

  • revs=$(git log --pretty="format:%H" --since="1 day ago");git diff $(echo "$revs"|tail -n1) $(echo "$revs"|head -n1) работает как-то, но кажется сложным и не ограничивается текущей веткой.

и наконец:

забавно, что git-cvsserver не поддерживает "cvs diff-D" (без этого он где-то задокументирован).

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

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

что это, вероятно, самая полезная для ваших целей-это дата reflog на конкретного репозитория в вопрос. Если для каждой ветви включены рефлоги (см. git config core.logAllRefUpdates), то вы можете использовать ref@{date} синтаксис для ссылки на то, где ветвь была в определенном месте время.

например.

git log -p master@{2009-07-01}..master@{now}

вы также можете использовать "нечеткие" описания, такие как:

git log -p "master@{1 month ago}..master@{yesterday}"

эти команды покажут все коммиты, которые "появились" в данной ветке репозитория, независимо от того, насколько "старые" они на самом деле в соответствии с их автором и датами фиксации.

обратите внимание, что рефлог для каждой ветви специфичен для репозитория, поэтому, если вы запускаете команду log на клоне, и вы не тянете (скажем) месяц, а затем вытаскиваете все изменения за последний месяц сразу, то все изменения последнего месяца появятся в

git diff --stat @{2013-11-01}..@{2013-11-30}

или

git diff --stat @{2.weeks.ago}..@{last.week}

возможно

$ git format-patch --committer=<who> --since=yesterday --stdout

это то, что вы хотите (с или без '--stdout')?

Я считаю, что общее решение использовать:

git rev-list -n1 --first-parent --until=<a date string> <a ref>

без --first-parent вы можете получить фиксацию из ветви, которая позже была объединена в a ref но не были объединены с a date string.

вот альтернатива с помощью --children и grep вместо -n1:

mlm_git_ref_as_of() {
    # # Examples #
    #
    # Show all commits between two dates:
    #
    #     git log $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    #
    # Show diffs of all commits between two dates:
    #
    #     git diff $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    local as_of=""
    local ref="${2:-HEAD}"
    # Get the most recent commit (--children, grep -v ' ') that was on
    # the given branch ($ref, --first-parent) as of a given date
    # ($as_of)
    git rev-list --children --first-parent --until="$as_of" "$ref" | grep -v ' '
}

Я не был знаком с git whatchanged перед чтением этого Q&A, но это дает очень разные результаты для меня, поэтому я не уверен, что он делает.

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

git log --pretty="format:%H %ai" | grep `date +"%Y-%m-%d"` | awk {'print '}`

;·)

вы также можете использовать git-format-patch чтобы подготовить патчи (diffs) и отправить их по электронной почте.

используйте опции [since] или [диапазон изменений], чтобы указать диапазон коммитов.

еще один простой способ, что вы можете получить дифф всех изменений с определенной даты, это просто найти первый коммит X это произошло на или после этой даты, а затем использовать

git diff X

Это имеет то преимущество, что не зависит от записи reflog в свежий клон, в отличие от

git diff <reference>@{n}..
git log <reference>@{n}..

решения в

Я брошу в том, как я это делаю: git log для даты дает вам фиксацию хэшей для текущей ветви. Тогда я просто использую что-то вроде git diff 8fgdfg8..565k4l5 что дает мне правильную разницу, агрегированную по файлам. Надеюсь, это поможет, не проверено много, хотя