Як оформити замовлення в Git за датою?


314

Я працюю над регресією у вихідному коді. Я хотів би сказати Git: "замовити джерело на основі параметризованої дати / часу". Чи можливо це?

Я також змінив свої зміни в поточному погляді, які не хочу втрачати. В ідеалі я хотів би перемикатися вперед і назад між поточним джерелом і якоюсь цікавою для мене версією на основі попередньої дати.


9
На випадок, якщо ви не знаєте про це, git bisect дуже чудово підходить для пошуку регресій. Я б сказав, використовуйте синтаксис {1 рік тому}, як сказав Енді, щоб знайти добре відомий фікс, а потім використовуйте це як свій початковий git bisect goodпункт.
MatrixFrog

Я відчуваю, що це хороший випадок для використання tags.
Джесс

Відповіді:


365

Щоб зберегти ваші поточні зміни

Ви можете тримати свою роботу в прихованому порядку, не скориставшись її git stash. Ви б хотіли використовувати git stash popйого для повернення. Або ви можете (як сказав Карлето ) git commitце окрему гілку.

Оформити замовлення за датою за допомогою rev-розбору

Ви можете взяти на себе зобов’язання до конкретної дати, використовуючи rev-parseтакий:

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

Більш детальну інформацію про доступні параметри можна знайти в git-rev-parse.

Як зазначається в коментарях, цей метод використовує рефлог, щоб знайти фіксацію у вашій історії. За замовчуванням ці записи закінчуються через 90 днів . Незважаючи на те, що синтаксис використання reflog є менш багатослівним, ви можете повернутися лише за 90 днів.

Оформити замовлення за датою за допомогою rev-list

Інший варіант, який не використовує рефлог, полягає у використанні rev-listдля здійснення фіксації в певний момент часу за допомогою:

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

Зверніть увагу на - перший батько, якщо ви хочете лише вашу історію, а не версії, внесені об'єднанням. Ось що ти зазвичай хочеш.


2
@Rocky Ви можете дати нам більше деталей Rocky? Що ви вводите в командному рядку і чому ви вважаєте, що він не працює? Ви отримуєте повідомлення про помилку?
Енді

8
@Rocky: Проблема полягає в тому, що параметр потрібно укласти в лапки, інакше bash розділяє аргументи на пробіли. Спробуйте git co 'master@{2 days ago}'.
Марк Вілден

13
Примітка. Залежно від того, як далеко ви йдете, це може не спрацювати, оскільки використовується рефлог (який закінчується через деякий час). Ви побачите "попередження: Журнал" master "повертається лише до ...". Рішення Рокі буде працювати завжди. git checkoutgit rev-list -n 1 --before="2009-07-27 13:37" master
Марк Надіг

3
Я відредагував вашу відповідь, тому що основи застаріли і їх важко читати. Бажані передплати $(...).
Амедей Ван Гассе

1
@Andy З днем ​​народження 40, Енді! (якщо припустити, що це означало 1979-02-26 :))
Девід Блевінс


15

Схоже, вам потрібно щось за цим: Git checkout на основі дати

Іншими словами, ви використовуєте rev-listдля пошуку комісії, а потім використовуєте замовлення, щоб фактично її отримати.

Якщо ви не хочете втрачати поетапні зміни, найпростіше було б створити нову гілку та привласнити їх до цієї гілки. Ви завжди можете перемикатися між гілками вперед і назад.

Редагувати: посилання не працює, ось ось команда:

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

2
Чудове посилання! Тому git checkout branch@{date}перестає працювати, коли закінчується термін відмови, але ви можете використовувати git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`.
cdunn2001

10

Тим, хто віддає перевагу трубі для заміни команд

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

9

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

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

Це повертає відповідний SHA комісії для даної дати, а потім:

git checkout SHA

4

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

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

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

Мені потрібно було знайти код, який на даній даті був на виробничих серверах. Це знайшло це для мене.


2

Якщо ви хочете мати можливість повернутися до точної версії сховища під час створення збірки, найкраще позначити коміту, з якої ви створюєте збірку.

Інші відповіді пропонують методи повернення сховища до останньої версії у філії за певний час - але їх не завжди може бути достатньо. Наприклад, якщо ви будуєте з гілки, а пізніше видаляєте гілку або будуєте з гілки, яка пізніше перезавантажується, комісія, яку ви створили, може стати "недосяжною" в git з будь-якої поточної гілки. Недоступні об’єкти в git можуть врешті-решт видалятися, коли сховище ущільнюється.

Якщо помістити тег на коміт, це означає, що він ніколи не стає недосяжним, незалежно від того, що ви робите з гілками згодом (заборона видалення тегу).


Хоча це не дає мені відповіді, яку я шукаю, але це заслуговує на гарну згадку за вказівкою на аспект, не згаданий досі. Це може стати джерелом проблем, які заважають вам дійти до потрібної версії.
manuelvigarcia

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

візьміть надрукований рядок (наприклад, XXXX) і зробіть:

git checkout XXXX

2
Це не дублікат відповіді @bartoszkp? просто додавши посилання на походження, має бути коментар до іншої відповіді ...
manuelvigarcia

так, насправді майже, просто прояснюючи, що скопіювати для того, хто не знає, що таке SHA (як я), у моєму випадку цей текст був не зрозумілий, і це мій код після пошуку рішення, а не скопійований, адже ви можете бачити варіанти теж дещо різняться
Лука C.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.