Изучение истории удалённого файла
Если я удалю файл в 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] .