Como fazer check-in no Git por data?

Eu estou trabalhando em uma regressão no código-fonte. Eu gostaria de dizer ao Git: “confira a fonte com base em uma data / hora parametrizada”. Isso é possível?

Eu também tenho encenado mudanças na minha visão atual que eu não quero perder. Idealmente, gostaria de alternar entre a fonte atual e alguma versão em que estou interessado com base em uma data anterior.

Para manter suas alterações atuais

Você pode manter seu trabalho escondido, sem comprometê-lo, com git stash . Você poderia usar git stash pop para recuperá-lo. Ou você pode (como disse o carleeto ) git commit enviá- lo para um ramo separado.

Checkout por data usando rev-parse

Você pode verificar um commit por uma data específica usando rev-parse como esta:

 git checkout 'master@{1979-02-26 18:30:00}' 

Mais detalhes sobre as opções disponíveis podem ser encontrados no git-rev-parse .

Como observado nos comentários, este método usa o reflog para encontrar o commit no seu histórico. Por padrão, essas inputs expiram após 90 dias . Embora a syntax para usar o reflog seja menos detalhada, você só pode voltar 90 dias.

Checkout out por data usando rev-list

A outra opção, que não usa o reflog, é usar o rev-list para obter o commit em um determinado momento:

 git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master` 

A solução de Andy não funciona para mim. Aqui encontrei outro caminho:

 git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master` 

Git: checkout por data

Parece que você precisa de algo ao longo das linhas deste: Git checkout com base na data

Em outras palavras, você usa o rev-list para encontrar o commit e então usa o checkout para obtê-lo.

Se você não quer perder suas alterações em etapas, o mais fácil seria criar uma nova ramificação e enviá-las para essa ramificação. Você sempre pode alternar entre filiais.

Edit: O link está inativo, então aqui está o comando:

 git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master` 

Para aqueles que preferem um pipe para comandar a substituição

 git rev-list -n1 --before=2013-7-4 master | xargs git checkout 

No meu caso, a opção -n 1 não funciona. No Windows, descobri que a seguinte sequência de comandos funciona bem:

 git rev-list -1 --before="2012-01-15 12:00" master 

Isso retorna o SHA do commit apropriado para a data especificada e, em seguida:

 git checkout SHA 

Indo mais além com a opção de rev-list revisões, se você quiser encontrar o commit de mesclagem mais recente de sua ramificação master em sua ramificação de produção (como um exemplo puramente hipotético):

 git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production` 

Eu precisava encontrar o código que estava nos servidores de produção a partir de uma determinada data. Isso encontrou para mim.

A solução git rev-parse proposta por @Andy funciona bem se a data em que você está interessado é a data do commit . Se, no entanto, você quiser fazer o checkout com base na data do autor , rev-parse não funcionará, pois não oferece uma opção para usar essa data para selecionar os commits. Em vez disso, você pode usar o seguinte.

git checkout $( git log --reverse --author-date-order --pretty=format:'%ai %H' master | awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 } )

(Se você também quiser especificar o tempo use $1 >= "2016-04-12" && $2 >= "11:37" no predicado awk .)

Se você quiser ser capaz de retornar à versão precisa do repository no momento em que faz uma compilation, é melhor marcar o commit do qual você faz a compilation.

As outras respostas fornecem técnicas para retornar o repository ao commit mais recente em um branch a partir de um certo tempo – mas elas nem sempre são suficientes. Por exemplo, se você criar a partir de uma ramificação, e depois excluir a ramificação, ou compilar a partir de uma ramificação que depois é rebaixada, a consolidação da qual você criou pode se tornar “inacessível” no git de qualquer ramificação atual. Objetos inacessíveis no git podem eventualmente ser removidos quando o repository é compactado.

Colocar uma tag no commit significa que ela nunca fica inacessível, não importa o que você faça com as ramificações depois (exceto a remoção da tag).

 git rev-list -n 1 --before="2009-07-27 13:37" origin/master 

pegue a string impressa (por exemplo XXXX) e faça:

 git checkout XXXX