web-dev-qa-db-fra.com

Comment commander dans Git par date?

Je travaille sur une régression dans le code source. J'aimerais dire à Git: "vérifiez la source en fonction d'une date/heure paramétrée". Est-ce possible?

J'ai également mis en scène des changements dans ma vue actuelle que je ne veux pas perdre. Idéalement, j'aimerais basculer entre la source actuelle et une version qui m'intéresse en fonction d'une date antérieure.

269
Amir Afghani

Pour conserver vos modifications actuelles

Vous pouvez garder votre travail caché, sans le commettre, avec _git stash_. Vous utiliseriez alors _git stash pop_ pour le récupérer. Ou vous pouvez (comme carleeto dit) _git commit_ dans une branche distincte.

Commander par date en utilisant rev-parse

Vous pouvez extraire un commit à une date spécifique en utilisant _rev-parse_ comme ceci:

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

Plus de détails sur les options disponibles sont disponibles dans le git-rev-parse .

Comme indiqué dans les commentaires, cette méthode utilise le reflog pour rechercher le commit dans votre historique. Par défaut, ces entrées expirent après 90 jours . Bien que la syntaxe d'utilisation du reflog soit moins détaillée, vous ne pouvez revenir en arrière que 90 jours.

Commander par date en utilisant rev-list

L’autre option, qui n’utilise pas le reflog, consiste à utiliser _rev-list_ pour obtenir le commit à un moment donné avec:

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

Notez le - premier parent si vous voulez uniquement votre historique et non les versions apportées par une fusion. C'est ce que tu veux d'habitude.

319
Andy

La solution d'Andy ne fonctionne pas pour moi. Ici j'ai trouvé un autre moyen:

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

Git: checkout par date

110
Rocky

On dirait que vous avez besoin de quelque chose du genre: Caisse Git basée sur la date

En d'autres termes, vous utilisez rev-list pour trouver le commit, puis utilisez checkout pour le récupérer.

Si vous ne voulez pas perdre vos modifications par étapes, le plus simple est de créer une nouvelle branche et de les valider. Vous pouvez toujours basculer entre les branches.

Edit: Le lien est en panne, alors voici la commande:

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

A ceux qui préfèrent une pipe pour commander la substitution

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

Dans mon cas, l'option -n 1 ne fonctionne pas. Sous Windows, j'ai constaté que la séquence de commandes suivante fonctionne correctement:

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

Ceci retourne le SHA du commit approprié pour la date donnée, puis:

git checkout SHA
9
BartoszKP

Pour aller plus loin avec l'option rev-list, si vous voulez trouver la validation de fusion la plus récente de votre branche maître dans votre branche de production (à titre d'exemple purement hypothétique):

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

Je devais trouver le code qui se trouvait sur les serveurs de production à une date donnée. Cela l'a trouvé pour moi.

3
egerlach

La solution git rev-parse proposée par @Andy fonctionne bien si la date qui vous intéresse est le date de validation. Si toutefois vous souhaitez utiliser une commande basée sur le date de l'auteur, rev-parse ne fonctionnera pas car il ne permet pas d'utiliser cette date pour sélectionner les validations. Au lieu de cela, vous pouvez utiliser ce qui suit.

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

(Si vous souhaitez également spécifier l'heure, utilisez $1 >= "2016-04-12" && $2 >= "11:37" dans le prédicat awk.)

3
Diomidis Spinellis

Si vous voulez pouvoir revenir à la version précise du référentiel au moment de la construction, il est préférable de baliser le commit à partir duquel vous la créez.

Les autres réponses fournissent des techniques permettant de ramener le référentiel à la validation la plus récente dans une branche à partir d'un certain temps, mais elles pourraient ne pas toujours suffire. Par exemple, si vous construisez à partir d'une branche, puis supprimez la branche ou à partir d'une branche rebasée ultérieurement, la validation à partir de laquelle vous avez construit peut devenir "inaccessible" dans n'importe quelle branche en cours. Les objets inaccessibles dans git peuvent éventuellement être supprimés lorsque le référentiel est compacté.

Mettre une étiquette sur le commit signifie que celle-ci ne sera jamais inaccessible, peu importe ce que vous ferez avec les branches par la suite (sauf si vous enlevez l'étiquette).

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

prenez la chaîne imprimée (par exemple XXXX) et faites:

git checkout XXXX
1
Luca C.