Просмотр истории удаленного файла

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
163
0
87 595
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

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

svn log -r <revision> <deleted file>

Это дает ошибку. Пример: svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' путь не найден

Jeremy 27.03.2009 21:24

Вы уверены, что он существовал в той версии? Вы должны указать ревизию, в которой фактически существовал файл.

Jack M. 27.03.2009 23:16

См. Ответ Берта Хейбена о странных различиях между -r37428 и добавлением @ 37428 к URL-адресу SVN.

dubek 20.01.2011 09:31
Ответ принят как подходящий

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

svn log -r lastrevisionthefileexisted

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

svn copy url/of/file@lastrevisionthefileexisted -r lastrevisionthefileexisted path/to/workingcopy/file

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

svn cat url/of/file@lastrevisionthefileexisted -r latrevisionthefileexisted > file

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

Вы также можете восстановить файл, выполнив обратное слияние ревизии, в которой вы его удалили. Это процедура, рекомендованная в документации SVN. Что касается использования «svn up», это не столько вопрос «не делай этого», сколько «он не будет делать то, что вы хотите».

rmeador 30.12.2008 23:18

Но как я могу увидеть всю историю файла?

Benjamin Peterson 30.12.2008 23:41

Я бы отредактировал ответ, если бы мог, но так как я не могу, способ получить весь журнал - использовать диапазон ревизий в форме 1: lastrevisionfileexisted (или, возможно, он начинается с нуля ... не могу вспомнить )

rmeador 31.12.2008 00:15

Просто: покажите журнал родительской папки с помощью переключателя '-v': для каждой записи вы получите список измененных путей. Найдите файл с буквой D впереди и именем вашего удаленного файла. Это ревизия, из которой был удален файл.

Stefan 27.03.2009 22:58

Похоже, это не работает для удаленных файлов. Если я попробую это сделать, я получу следующее сообщение об ошибке: svn cat [url] /trunk/include/syeka/poster_funk.incl.php -r 50> out.txt svn: '/ admintools /! Svn / bc / 131 / trunk / include / syeka / poster_funk.inc‌ l.php 'путь не найден См. ответ @Bert Huijben далее в этой ветке для рабочего решения.

Keith Palmer Jr. 08.01.2010 18:55

Если у меня есть репо со 100 000 коммитов, "lastrevisionthefileexisted" найти нелегко!

Jon Watte 06.07.2016 22:55

Если вы знаете имя файла или его часть, но не помните, когда вы его удалили, вы можете использовать этот быстрый сценарий, который я собрал несколько лет назад: github.com/inquam/svn-find-deleted-file

inquam 26.05.2017 23:15

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

svn log -v > log.txt

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

D <deleted file>

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

svn log -v | grep D "имя_файла"

abatishchev 31.12.2008 00:19

+1 за то, что первым правильно ответил на вопрос. Вы не можете просмотреть содержимое, если не знаете версию до ее удаления.

Cerin 27.07.2010 21:58

@abatishchev получает список удаленных файлов, но отбрасывает информацию о ревизии, так что это бесполезно. Также это медленно, если вы работаете с большим / старым репозиторием с большой историей изменений.

tchen 28.10.2011 20:37

Хорошо, отлично с улучшением @abatishchev. tchen: легко исправить с помощью аргумента -B50 или около того для grep, см. мой ответ.

Jonas Byström 06.09.2012 11:36

Еще один хороший способ ограничить вывод svn log -v для очень больших / старых репозиториев - это опция -l. Итак, вы можете использовать svn log -v -l 100 | grep D "имя_файла"

mindmatters 09.10.2013 19:52

В 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

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

Замечательный ответ. Проблема только в том, что речь идет о svn!

JohnK 14.07.2017 00:13

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

$ git show 8d4a1f^:slosh.tac

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

Ах, очень верно. Раньше я делал это очень, очень тяжело. :)

Dustin 31.12.2008 01:31

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

Пытался:

> 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)).

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

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

а также

svn cat http://server/svn/project/file@1234

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

Второй синтаксис получает файл, который был доступен как http: // сервер / svn / проект / файл в ревизии 1234. Таким образом, этот синтаксис ДЕЛАЕТ работает с удаленными файлами.

Вы даже можете комбинировать эти методы для получения файла, который был доступен в версии 2345 как http: // сервер / svn / проект / файл, но с содержимым, как в 1234, с помощью:

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

Ага, спасибо! В текущем верхнем ответе в этой ветке об этом не упоминается, это здорово!

Keith Palmer Jr. 08.01.2010 18:53

Это все еще не помогло мне, если я не использовал абсолютные пути, поскольку мой локальный клиент svn выдавал ошибку, когда не мог разрешить ./local/file, когда каталог ./local не существовал. Это может не быть проблемой для более новых версий SVN.

Derrick Rice 06.06.2013 22:00

@DerrickRice: В этом случае пригодится нотация ^: она относится к корню репозитория, поэтому вы можете сказать svn cat ^/local/file@REV (в зависимости от расстояния между корнем репозитория и URL-адресом).

musiphil 12.09.2013 02:49

Это в принципе отлично работает. По папкам получаю следующее: svn: E200009: Could not cat all targets because some targets are directories

Barney 23.04.2014 21:07

Это лучший ответ. Также имеет наибольшее количество голосов.

Felipe Alvarez 19.05.2014 05:21

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

wytten 20.05.2014 23:44

для оборотов в {900..600}; делать, если svn cat server/repo/file.ext@$rev> / dev / null 2> & 1; затем echo "Последний раз видели на ревизии: $ rev"; перерыв; fi; Выполнено

Kevin 15.03.2017 22:36

Решение, использующее только графический интерфейс:

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

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

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

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

Грубая сила - это не всегда дерьмо. Особенно на больших репо.

Jonas Byström 06.09.2012 11:32

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

Mir 18.10.2012 02:28

Обратите внимание, что приведенный выше ответ предназначен для графического интерфейса TortoiseSVN.

Georg Muehlenberg 26.11.2019 11:27

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

git log --follow -- current_file_name

На самом деле плакат задал здесь 3 вопроса:

  1. Как посмотреть историю удаленного файла в Subversion?
  2. Как посмотреть содержимое удаленного файла в Subversion?
  3. Как мне воскресить удаленный файл в Subversion?

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

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

svn log http://server/svn/project/file@1234

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

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

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.

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

svn log -v | grep -B50 YourDeletedFileName

Получу вам путь и доработку. В git (также проверяет переименования):

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

Что делает -B50? Я могу довольно легко получить список файлов с помощью svn log и grep, используя приведенные здесь советы, но я не могу вообще легко отобразить номера ревизий, поскольку они отображаются в другой строке. Я попробовал B50, и мне показалось, что он не так уж хорош.

cedd 30.07.2015 17:12

Он выводит совпадающую строку и 50 строк выше, на случай, если кто-то еще это прочитает.

cedd 30.07.2015 17: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, так что он может быть нетрадиционным.

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

svn log --search <deleted_file_or_pattern> -v

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

svn log --search _test2.php -v ... svn: недопустимая опция: --search ... :(
thinsoldier 26.03.2015 20:18

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

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

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"
}

Предположим, ваш файл был назван ~ / 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 URL_of_deleted.file@90439 .

Другие вопросы по теме