Анализ истории

Как мы уже говорили, хранилище похоже на машину времени. Оно хранит запись о любом когда-либо зафиксированном изменении и позволяет вам просмотреть его хронологию путем анализа предыдущих версий файлов и директорий, равно как и метаданных присоединенных к ним. Одной командой Subversion вы можете создать рабочую копию (или восстановить существующую) точно в том виде, в котором она была в любой момент времени или номер правки в прошлом. Однако, как правило, иногда вам просто нужно заглянуть в прошлое, вместо возвращения в прошлое.

Существует несколько команд которые могут обеспечить вас хронологической информацией из хранилища:

svn log

Показывает вам развернутую информацию: лог сообщения, присоединенные к правкам, с указаной датой изменений и их автором, а так-же измененные в правке пути файлов.

svn diff

Показывает конкретные детали того, как файл изменился с течением времени.

svn cat

Эта команда используется для получения отдельного файла в том виде, в каком он был в конкретной ревизии и вывода его на экран.

svn list

Показывает файлы в директории для любой указанной правки.

svn log

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

$ svn log
------------------------------------------------------------------------
r3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line

Added include lines and corrected # of cheese slices.
------------------------------------------------------------------------
r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line

Added main() methods.
------------------------------------------------------------------------
r1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line

Initial import
------------------------------------------------------------------------

Обратите внимание на то, что по умолчанию лог сообщения выводятся в обратном хронологическом порядке. Если вам нужно увидеть другой диапазон правок в заранее определенном порядке или только одну правку, укажите параметр --revision (-r):

$ svn log --revision 5:19    # shows logs 5 through 19 in chronological order

$ svn log -r 19:5            # shows logs 5 through 19 in reverse order

$ svn log -r 8               # shows log for revision 8

Кроме того, можно проанализировать историю лог сообщений отдельного файла или директории. Например:

$ svn log foo.c
…
$ svn log http://foo.com/svn/trunk/code/foo.c
…

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

Если вам нужно еще больше информации о файле или директории, то для svn log есть параметр --verbose (-v). Так как Subversion позволяет перемещать и копировать файлы и директории, важной является возможность отслеживания изменений путей в файловой системе, поэтому в режиме расширенного вывода, svn log включает перечень измененных в правке путей:

$ svn log -r 8 -v
------------------------------------------------------------------------
r8 | sally | 2002-07-14 08:15:29 -0500 | 1 line
Changed paths:
M /trunk/code/foo.c
M /trunk/code/bar.h
A /trunk/code/doc/README

Frozzled the sub-space winch.

------------------------------------------------------------------------

Кроме тогоsvn log имеет параметр --quiet (-q), сокращающий лог сообщение. При его объединении с --verbose выдаются только имена измененных файлов.

svn diff

Ранее, мы уже познакомились с svn diff — эта команда показывает различия файла в объединенном формате представления различий; она использовалась, для того, что бы показать локальные изменения внесенные в рабочую копию перед их фиксацией в хранилище.

Вообще, существует три возможных варианта использования svn diff:

  • Анализ локальных изменений

  • Сравнение рабочей копии с хранилищем

  • Сравнение хранилища с хранилищем

Анализ локальных изменений

Как мы уже знаем, запуск svn diff без параметров сравнивает рабочие файлы, с кешированными в .svn «первоначальными» копиями:

$ svn diff
Index: rules.txt
===================================================================
--- rules.txt (revision 3)
+++ rules.txt (working copy)
@@ -1,4 +1,5 @@
 Be kind to others
 Freedom = Responsibility
 Everything in moderation
-Chew with your mouth open
+Chew with your mouth closed
+Listen when others are speaking
$

Сравнение рабочей копии с хранилищем

Если в --revision (-r) указан один номер, то рабочая копия сравнивается с указанной правкой хранилища.

$ svn diff --revision 3 rules.txt
Index: rules.txt
===================================================================
--- rules.txt (revision 3)
+++ rules.txt (working copy)
@@ -1,4 +1,5 @@
 Be kind to others
 Freedom = Responsibility
 Everything in moderation
-Chew with your mouth open
+Chew with your mouth closed
+Listen when others are speaking
$

Сравнение хранилища с хранилищем

Если через --revision (-r) передаются две правки, разделенные двоеточием, то непосредственно сравниваются две правки.

$ svn diff --revision 2:3 rules.txt
Index: rules.txt
===================================================================
--- rules.txt (revision 2)
+++ rules.txt (revision 3)
@@ -1,4 +1,4 @@
 Be kind to others
-Freedom = Chocolate Ice Cream
+Freedom = Responsibility
 Everything in moderation
 Chew with your mouth open
$

svn diff можно использовать не только для сравнения файлов в рабочей копии, если вы укажите в качестве аргумента URL, то сможете анализировать различия между элементами, даже не имея рабочей копии. Это полезно в случае, если вы хотите проверить изменения в файла тогда когда у вас нет его рабочей копии на локальной машине:

$ svn diff --revision 4:5 http://svn.red-bean.com/repos/example/trunk/text/rules.txt
…
$

svn cat

Если вы хотите проанализировать ранние версии файла, а не различия между двумя файлами, можно воспользоваться svn cat:

$ svn cat --revision 2 rules.txt
Be kind to others
Freedom = Chocolate Ice Cream
Everything in moderation
Chew with your mouth open
$

Или вы можете перенаправить вывод прямо в файл:

$ svn cat --revision 2 rules.txt > rules.txt.v2
$

Вероятно, вам интересно почему мы не воспользовались svn update --revision, что бы обновить файл старой правкой. Есть несколько причин, почему нам предпочтительнее воспользоваться svn cat.

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

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

svn list

Команда svn list показывает содержимое директории в хранилище, при этом не закачивая его на локальную машину:

$ svn list http://svn.collab.net/repos/svn
README
branches/
clients/
tags/
trunk/

Если вам нужен более детальный листинг, тогда воспользуйтесь флагом --verbose (-v) чтобы увидеть нечто, подобное этому:

$ svn list --verbose http://svn.collab.net/repos/svn
   2755 harry          1331 Jul 28 02:07 README
   2773 sally               Jul 29 15:07 branches/
   2769 sally               Jul 29 12:07 clients/
   2698 harry               Jul 24 18:07 tags/
   2785 sally               Jul 29 19:07 trunk/

Колонки показывают правку, в которой файл или директория последний раз менялись, имя пользователя делавшего изменения, размер если это файл, дату последнего изменения и имя элемента.

Заключительное слово о истории

Дополнительно ко всем упомянутым выше командам, можно воспользоваться svn update и svn checkout с параметром --revision для того, что бы переместить рабочую копию «назад во времени»[12]:

$ svn checkout --revision 1729 # Checks out a new working copy at r1729
…
$ svn update --revision 1729 # Updates an existing working copy to r1729
…


[12] Видите? Мы же говорили вам, что Subversion это машина времени.