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

Как мы уже говорили, хранилище похоже на машину времени. Оно хранит запись о любом когда-либо зафиксированном изменении и позволяет вам просмотреть его хронологию путем анализа предыдущих версий файлов и каталогов, а также присоединенных к ним метаданных. Одной командой 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 — это машина времени.