Как оформить заказ в Git по дате? - PullRequest
267 голосов
/ 09 августа 2011

Я работаю над регрессией в исходном коде. Я хотел бы сказать Git: «извлечение источника на основе параметризованной даты / времени». Это возможно?

У меня также есть изменения в моем текущем представлении, которые я не хочу терять. В идеале я хотел бы переключаться между текущим источником и какой-либо интересующей меня версией на основе предыдущей даты.

Ответы [ 9 ]

313 голосов
/ 09 августа 2011

Чтобы сохранить текущие изменения

Вы можете хранить свою работу подальше, не передавая ее, с помощью git stash. Вы чем использовать git stash pop, чтобы вернуть его. Или вы можете (как сказал carleeto ) git commit в отдельную ветку.

Оформить заказ по дате, используя rev-parse

Вы можете оформить коммит к определенной дате, используя rev-parse, например:

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

Более подробную информацию о доступных опциях можно найти в git-rev-parse.

Как отмечено в комментариях, этот метод использует reflog для поиска коммита в вашей истории. По умолчанию эти записи истекают через 90 дней . Хотя синтаксис использования reflog менее подробный, вы можете вернуться только на 90 дней назад.

Оформить заказ по дате, используя rev-list

Другой вариант, который не использует reflog, - это использовать rev-list, чтобы получить фиксацию в определенный момент времени с помощью:

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

Обратите внимание на - перво-родительский , если вам нужна только ваша история, а не версии, внесенные слиянием. Это то, что вы обычно хотите.

108 голосов
/ 15 декабря 2011

Решение Энди не работает для меня. Здесь я нашел другой способ:

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

Git: оформить заказ по дате

14 голосов
/ 09 августа 2011

Похоже, вам нужно что-то вроде этого: Git checkout на основе даты

Другими словами, вы используете rev-list, чтобы найти коммит, а затем используете checkout для фактическогополучите.

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

Редактировать: связь не работает, вот команда:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
9 голосов
/ 09 декабря 2013

Тем, кто предпочитает трубу подстановке команд

git rev-list -n1 --before=2013-7-4 master | xargs git checkout
8 голосов
/ 08 декабря 2015

В моем случае опция -n 1 не работает. В Windows я обнаружил, что следующая последовательность команд работает нормально:

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

Возвращает SHA соответствующего коммита для указанной даты, а затем:

git checkout SHA
3 голосов
/ 13 августа 2016

Решение git rev-parse, предложенное @Andy, работает нормально, если интересующая вас дата является датой коммита .Однако, если вы хотите оформить заказ на основе даты автора , rev-parse не будет работать, потому что он не предлагает возможность использовать эту дату для выбора фиксаций.Вместо этого вы можете использовать следующее.

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

(Если вы также хотите указать время, используйте $1 >= "2016-04-12" && $2 >= "11:37" в предикате awk .)

3 голосов
/ 07 октября 2013

Если продолжить с опцией rev-list, если вы хотите найти самый последний коммит слияния из вашей основной ветки в вашу производственную ветвь (в качестве чисто гипотетического примера):

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

Мне нужно былонайти код, который был на производственных серверах на определенную дату.Это нашло его для меня.

2 голосов
/ 05 декабря 2015

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

Другие ответы предоставляют методы для возврата хранилища в самый последний коммит в ветке на определенное время, но их может быть не всегда достаточно. Например, если вы строите из ветки, а затем удаляете ветку, или строите из ветки, которая позже была перебазирована, созданный вами коммит может стать «недоступным» в git из любой текущей ветки. Недоступные объекты в git могут в конечном итоге быть удалены при сжатии хранилища.

Помещение тега в коммит означает, что он никогда не станет недоступным, независимо от того, что вы делаете с ветками впоследствии (за исключением удаления тега).

1 голос
/ 05 мая 2017
git rev-list -n 1 --before="2009-07-27 13:37" origin/master

взять напечатанную строку (например, XXXX) и выполнить:

git checkout XXXX
...