Como posso obter o diff entre todos os commits que ocorreram entre duas datas com o Git?

Ou apenas todos os commits que ocorreram entre duas datas? No SVN, você poderia fazer algo como

svn diff -r{date}:{date} 

fazer isso! Eu não consigo encontrar um Git equivalente a isso.

Especificamente, estou olhando para escrever um script para enviar e-mails diários com todo o código comprometido naquele dia e por quem.

Você poderia usar o git whatchanged --since="1 day ago" -p

Também leva um argumento – até.

Docs

As sugestões anteriores têm algumas desvantagens. Basicamente, eu estava procurando por algo equivalente ao cvs diff -D"1 day ago" -D"2010-02-29 11:11" . Enquanto coletava mais e mais informações, encontrei uma solução.

Coisas que eu tentei:

  • git whatchanged --since="1 day ago" -p daqui

    Mas isso dá um diff para cada commit, mesmo que existam vários commits em um arquivo. Eu sei que “data” é um conceito um pouco solto no git , eu pensei que deve haver alguma maneira de fazer isso.

  • git diff 'master@{1 day ago}..master dá um aviso warning: Log for 'master' only goes back to Tue, 16 Mar 2010 14:17:32 +0100. e não mostra todos os diffs.

  • git format-patch --since=yesterday --stdout não dá nada para mim.

  • revs=$(git log --pretty="format:%H" --since="1 day ago");git diff $(echo "$revs"|tail -n1) $(echo "$revs"|head -n1) funciona de alguma forma, mas parece complicado e não se restringe ao ramo atual.

Finalmente:

  • git diff $(git rev-list -n1 --before="1 day ago" master) parece funcionar e uma maneira padrão de fazer coisas semelhantes , embora mais complicado do que eu pensava.

Engraçado, o git-cvsserver não suporta “cvs diff -D” (sem que isso esteja documentado em algum lugar).

“date” é um conceito um pouco solto no git. Um commit terá uma data de autor que pode ter passado algum tempo antes de alguém realmente puxar / commitar o commit em seu repository, também o commit pode ser rebaixado e atualizado para estar no topo de um commit aparentemente mais recente.

Um commit também tem uma data de confirmação que é atualizada se um commit for rebaixado ou alterado de alguma forma. É mais provável que esses commits estejam em algum tipo de ordem cronológica, mas você ainda está à mercê do committer ter o horário correto configurado em seu computador e, mesmo assim, um commit não modificado pode ficar indefinidamente em um branch de resources em um repository remoto. sendo mesclado no ramo mestre de um repository central.

O que provavelmente é mais útil para seus propósitos é a data de reflogação no repository específico em questão. Se você tiver os reflogs por ramificação ativados (consulte git config core.logAllRefUpdates ), então você pode usar a syntax ref@{date} para se referir a onde uma ramificação estava em uma hora específica.

Por exemplo

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

Você também pode usar descrições ‘difusas’ como:

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

Esses comandos mostrarão todos os commits que ‘apareceram’ na ramificação do repository, independentemente de quão “antigos” eles realmente estejam de acordo com suas autorias e datas de commit.

Observe que o reflog por ramificação é específico de um repository, portanto, se você estiver executando o comando log em um clone e não for pressionado por (digamos) um mês, puxe todas as alterações do último mês de uma vez, então todas as alterações do último mês aparecerão em um intervalo @{1 hour ago}..@{now} . Se você conseguir executar o comando log no repostório ‘central’ para o qual as pessoas o pressionam, ele poderá fazer o que quiser.

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

ou

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

Possivelmente

 $ git format-patch --committer= --since=yesterday --stdout 

é o que você quer (com ou sem ‘–stdout’)?

Eu acredito que a solução geral é usar:

 git rev-list -n1 --first-parent --until=  

Sem –first-parent, você pode obter um commit de um branch que foi posteriormente mesclado em a ref mas não foi fundido a partir de a date string .

Aqui está uma alternativa usando --children e grep vez de -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="$1" 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 ' ' } 

Eu não estava familiarizado com o git whatchanged antes de ler este Q & A, mas isso dá resultados muito diferentes para mim, então não tenho certeza do que está fazendo.

Esta é uma resposta mais engraçada, porque provavelmente existe uma maneira melhor. Isso mostrará todos os hashes de commit para hoje.

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

😉

Você também pode usar o git-format-patch para preparar patches (diffs) e enviá-los por email.

Use as opções [since] ou [range de revisão] para especificar o intervalo de confirmações.

Outra maneira simples que você pode obter um diff de todas as alterações desde uma determinada data é simplesmente encontrar o primeiro commit X que ocorreu em ou após essa data, então use

 git diff X 

Isso tem a vantagem de não depender de inputs de reflog em um novo clone, ao contrário do

 git diff @{n}.. git log @{n}.. 

soluções em

Eu vou jogar do jeito que eu faço: git log para uma data lhe dá hashes de commit para o branch atual. Então eu uso apenas algo como git diff 8fgdfg8..565k4l5 que me dá a diferença adequada agregada por arquivos. Espero que isso ajude, não testou muito embora