Изучение истории удалённого файла

Если я удалю файл в Subversion, как я могу просмотреть его историю и содержимое? Если я попытаюсь выполнить svn cat или svn log в несуществующем файле, он жалуется, что файл не существует.

Кроме того, если бы я хотел воскресить файл, должен ли я просто вернуть его svn add?

(я спросил конкретно о Subversion, но я также хотел бы услышать о том, как Bazaar, Mercurial и Git обрабатывают этот случай тоже.)

Ответ 1

Чтобы получить журнал удалённого файла, используйте

svn log -r lastrevisionthefileexisted

Если вы хотите воскресить файл и сохранить его историю версий, используйте

svn copy url/of/[email protected] -r lastrevisionthefileexisted path/to/workingcopy/file

Если вы просто хотите содержимое файла, но не вернули его (например, для быстрого осмотра), используйте

svn cat url/of/[email protected] -r latrevisionthefileexisted > file

В любом случае НЕ используйте 'svn up', чтобы вернуть удаленный файл!

Ответ 2

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

svn cat http://server/svn/project/file -r 1234

и

svn cat http://server/svn/project/[email protected]

В первой версии рассматривается путь сейчас, доступный как http://server/svn/project/file, и извлекает этот файл в качестве был в редакции 1234. (Таким образом, этот синтаксис работает не после удаления файла).

Второй синтаксис получает файл, который был доступен как http://server/svn/project/file в редакции 1234. Таким образом, этот синтаксис DOES работа над удаленными файлами.

Вы даже можете объединить эти методы, чтобы получить файл, доступный в редакции 2345, как http://server/svn/project/file, но с содержимым, как это было в 1234 с:

svn cat http://server/svn/project/[email protected] -r 1234

Ответ 3

Сначала найдите номер версии, где файл был удален:

svn log -v > log.txt

Затем загляните в log.txt(не гуру SVN, поэтому я не знаю лучшего способа) для строки с

D <deleted file>

и посмотрите, какая версия была. Затем, как и в других ответах, воскресете файл, используя предыдущую ревизию.

Ответ 4

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

git log -n 1 -- filename

Затем вы можете использовать эту фиксацию для получения файла, как он существовал до удаления.

git checkout [last_revision]^ filename

Пример:

dhcp-120:/tmp/slosh 587% ls -l slosh.tac
ls: slosh.tac: No such file or directory
dhcp-120:/tmp/slosh 588% git log -n 1 -- slosh.tac
commit 8d4a1f1a94e4aa37c1cb9d329a140d08eec1b587
Author: Dustin Sallings <[email protected]>
Date:   Mon Dec 15 11:25:00 2008 -0800

    Get rid of a .conf and replace it with .tac.
dhcp-120:/tmp/slosh 589% git checkout 8d4a1f^ slosh.tac
dhcp-120:/tmp/slosh 590% ll slosh.tac
-rw-------  1 dustin  wheel  822 Dec 30 12:52 slosh.tac

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

Ответ 5

svn log -v | grep -B50 YourDeletedFileName

Вы получите путь и версию. В git (также проверяет переименования):

git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName

Ответ 6

Решение с использованием только GUI:

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

  • Из браузера Repo выполните "Показать журнал" в корневом каталоге
  • Нажмите "Показать все" (внизу диалогового окна журнала)
  • Введите имя файла в текстовое поле "Фильтр" (вверху диалогового окна журнала).

Затем будут показаны только те версии, в которых файл был добавлен/изменен/удален. Это ваша история файла.

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

Ответ 7

В дополнение к ответу Дастина, если вы просто хотите изучить содержимое, а не проверить его, в его примере вы можете сделать:

$ git show 8d4a1f^:slosh.tac

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

Ответ 8

Используйте эту команду:

svn log -v | awk '/^r[0-9]+/ { rev = $1; }; / D .*filename_escaped_for_regex/ { print rev" "$2; };'

Здесь будут перечислены все версии, которые когда-либо удаляли любые файлы, соответствующие шаблону. То есть, если вы ищете файл README, то все /src/README, /src/README.first и /some/deeply/hidden/directory/READMENOT будут найдены и перечислены.

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

Ответ 9

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

svn log --search <deleted_file_or_pattern> -v

Команда, вероятно, забивает сервер так же сильно, как и без опции поиска, но, по крайней мере, остальные задействованные ресурсы (включая ваши глазные яблоки) будут немного облегчены, так как это скажет вам, в какой редакции этот файл был удален. Затем вы можете следовать другим советам (в основном, используя ту же команду svn log, но уже по определенному пути).

Ответ 10

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

Пробовал:

> bzr log -r 3 Stuff/ErrorParser.hta
bzr: ERROR: Path does not have any revision history: Stuff/ErrorParser.hta

но с любопытством (и, к счастью) я могу сделать:

> bzr cat -r 3 Stuff/ErrorParser.hta

и

> bzr diff -r 2..3 Stuff/ErrorParser.hta

и, как было предложено в приведенной выше ошибке:

> bzr log -v | grep -B 1 ErrorParser

(при необходимости отрегулируйте параметр -B (--before-context)).

Ответ 11

Плакат действительно задал здесь 3 вопроса:

  • Как посмотреть историю удаленных файлов в Subversion?
  • Как посмотреть содержимое удаленного файла в Subversion?
  • Как восстановить воскрешенный файл в Subversion?

Все ответы, которые я вижу здесь, касаются вопросов 2 и 3.

Ответ на вопрос 1:

svn log http://server/svn/project/[email protected]

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

Ответ 12

Вам нужно будет указать ревизию.

svn log -r <revision> <deleted file>

Ответ 13

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

git log --follow -- current_file_name

Ответ 14

Мне нужен был ответ. Попробуйте выполнить вывод только для удаления из svn log.

svn log --stop-on-copy --verbose [--limit <limit>] <repo Url> | \
awk '{ if ($0 ~ /^r[0-9]+/) rev = $0 }
  { if ($0 ~ /^ D /) { if (rev != "") { print rev; rev = "" }; print $0 } }'

Это фильтрует выход журнала через awk. awk буферирует каждую строку ревизии, которую он находит, выводя ее только тогда, когда найдена запись удаления. Каждая ревизия выводится только один раз, поэтому несколько удалений в ревизии группируются вместе (как в стандартном svn log выходе).

Вы можете указать --limit, чтобы уменьшить количество возвращенных записей. Вы также можете удалить --stop-on-copy, если необходимо.

Я знаю, что есть жалобы на эффективность анализа всего журнала. Я думаю, что это лучшее решение, чем grep и его "отличная широкая сеть" -B. Я не знаю, эффективнее ли это, но я не могу придумать альтернативу svn log. Он похож на @Alexander Amelkin, но не нуждается в конкретном имени. Это также мой первый awk script, поэтому он может быть нетрадиционным.

Ответ 15

Я написал php script, который копирует журнал svn всех моих репозиториев в базу данных mysql. Теперь я могу выполнять полнотекстовый поиск по моим комментариям или именам файлов.

Ответ 16

Вы можете найти последнюю версию, которая предоставляет файл, используя двоичный поиск. Я создал простой /bin/bash script для этого:

function svnFindLast(){
 # The URL of the file to be found
 local URL="$1"
 # The SVN revision number which the file appears in (any rev where the file DOES exist)
 local r="$2"
 local R
 for i in $(seq 1 "${#URL}")
  do
   echo "checkingURL:'${URL:0:$i}'" >&2
   R="$(svn info --show-item revision "${URL:0:$i}" 2>/dev/null)"
   echo "R=$R" >&2
   [ -z "$R" ] || break
 done
 [ "$R" ] || {
  echo "It seems '$URL' is not in a valid SVN repository!" >&2
  return -1
 }
 while [ "$r" -ne "$R" -a "$(($r + 1))" -ne "$R" ]
 do
  T="$(($(($R + $r)) / 2))"
  if svn log "${URL}@${T}" >/dev/null 2>&1
   then
    r="$T"
    echo "r=$r" >&2
   else
    R="$T"
    echo "R=$R" >&2
  fi
 done
 echo "$r"
}

Ответ 17

Предположим, что ваш файл был назван как ~/src/a/b/c/deleted.file

cd ~/src/a/b/c  # to the directory where you do the svn rm or svn mv command
#cd ~/src   # if you forget the correct directory, just to the root of repository
svn log -v | grep -w -B 9 deleted.file | head  # head show first 10 lines

нашел его на r90440

...
r90440 | user | 2017-02-03 11:55:09 +0800 (Fri, 03 Feb 2017) | 4 lines
Changed paths:
  M /src/a/b/c/foo
  M /src/a/b/c/bar
  D /src/a/b/c/deleted.file

скопировать его обратно в предыдущую версию (90439 = 90440-1)

svn cp [email protected] .