Как экранировать символы @ в именах файлов, управляемых Subversion?


191

Для многих операций Subversion добавление символа '@' в конец аргумента файла или URL-адреса позволяет вам указать конкретную версию этого файла. Например, «svn info test.txt@1234» предоставит информацию о test.txt, существовавшем в редакции 1234.

Однако когда имя файла содержит символ @, он неверно интерпретируется Subversion как спецификатор ревизии:

svn info 'test @ .txt' svn: синтаксическая ошибка синтаксического анализа ревизии '.txt'

Я пробовал двойные и одинарные кавычки, а также экранирование с помощью «/», «\» и «@». Как я могу сказать Subversion обрабатывать символы @ как часть имени файла?


3
С какой стати у вас есть имена файлов с @ в них? Если вы спросите меня о неприятностях ... :-)
JesperE

Очень хороший вопрос! :) Я беру проект, в котором этот символ является основным компонентом соглашений об именах файлов, и, к сожалению, это не может быть изменено в ближайшем будущем.
Уэстон

57
Apple создала это соглашение для всех своих разработчиков iOS начиная с iOS 4+. Все активы должны быть названы @ 2x, если они предназначены для отображения в высоком разрешении ...
Димитрис

2
Стандарт для гетто по старому стилю Matlab OO
Chinasaur

Кроме того, если вы сохраните свой закрытый ключ или ключ отзыва из Enigmail Thunderbird, он создаст имя файла - не без оснований, учитывая приложение - содержащее знак «at»
Питер Флинн

Ответы:


283

Из книги SVN (выделение добавлено):

В этот момент проницательный читатель, вероятно, задается вопросом, не вызывает ли синтаксис редакции разметки проблемы с путями рабочей копии или URL, которые на самом деле имеют знаки в них. В конце концов, как svn узнает, news@11является ли имя каталога в моем дереве или просто синтаксис для «редакции 11 новостей »? К счастью, хотя SVN всегда будет предполагать последнее, существует тривиальный обходной путь. Вам нужно только добавить знак в конце пути , например news@11@. svn заботится только о последнем знаке в аргументе, и не считается недопустимым опускать спецификатор ревизии буквального колышка после этого в знаке. Этот обходной путь даже применяется к путям, которые заканчиваются знаком «at» - вы бы использовалиfilename@@говорить о файле с именем имя файла @ .


4
Обратите внимание, что для использования «svn diff» вам необходимо добавить параметр ревизии. "svn up @ file @" работает, но "svn diff @ file @" не работает. Вам нужно использовать «svn diff -r HEAD @ file @»
analytik

Примечание для книги SVN: файлы могут существовать без расширений, даже в Windows, так же news@11как и файл.
trysis

1
Обратите внимание, что для некоторых команд, таких как переименование, аргумент может быть версионным элементом или локальным именем файла. В случае переименования цель также сканируется на наличие закрепленной ревизии, но впоследствии она может рассматриваться как простое имя. Например, если вы хотите переименовать , @fooчтобы @bar, svn rename @foo@ @barбудет жаловаться @bar; но если вы сделаете это svn rename @foo@ @bar@, новое имя будет буквально @bar@. Чтобы избежать этого, добавьте ./(или .\ на окнах) , чтобы сделать это ясно , что это локальный путь: svn rename @foo@ ./@bar.
Застай

82

Первоначальный ответ правильный, но, возможно, недостаточно точный. Конкретные параметры командной строки Unix:

svn info 'image@2x.png@'

или

svn info "image@2x.png@"

или

svn info image\@2x.png\@

Я только что проверил все три.


4
Я также проверил, svn info icon@2x.png@и это тоже сработало. Да, без кавычек или косой черты!
Nate

Необходимость цитирования зависит от вашей оболочки - я использую KSH и, конечно, вам нужны кавычки (так как '@' - это знак того, что вы хотите запустить процесс в фоновом режиме). YMMV в зависимости от оболочки.
Дэвид Х

Ага. Мой пробег был на bashтрассе :)
конец

1
@Nate Теперь я не могу заставить его потерпеть неудачу - он работает нормально без кавычек в ksh. Я не знаю, почему я думал, что они мне нужны - возможно, какой-то другой вопрос - это было 2 года назад, когда я опубликовал это ...
Дэвид Х

14

Решение для добавления нескольких файлов в разные подпапки:

for file in $(find ./ -type f -name "*@*.png"); do svn add $file@; done

Просто замените "png" в " @ .png" на файлы, которые вы хотите добавить.


не забудьте процитировать или экранировать имена файлов (и сопоставлять без учета регистра). Кроме того, нет никакой необходимости , чтобы лечить файлы с @их именем , как частный случай, вы можете смело добавлять в @символ на все имена файлов: for file in $(find ./ -type f -iname "*.png"); do svn add "$file@"; done. Кроме того, разве этот подход не оставляет в вашем SVN-репо структуру файлов / каталогов, несовместимую с рабочей локальной копией?
ardnew

использование execfind может быть eaiser:find . -type f -name "*@*.png" -exec svn add {}@ \;
Walty Yeung



8

В моем случае мне нужно было удалить файлы из репозитория SVN, которые содержали знак @:

Это не сработает:

svn remove 'src/assets/images/hi_res/locales-usa@2x.png'

Но это сделал:

svn remove 'src/assets/images/hi_res/locales-usa@2x.png@'

6

Чтобы добавить несколько файлов, есть альтернативное решение:

svn status | grep \.png | awk '{print $2"@"}'| xargs svn add

Пожалуйста, объясните свой ответ.
Hemang

3
Вы можете использовать awk вместо grep:svn status | awk '/\.png/ {print $2"@"}'| xargs svn add
h3dkandi

1

Для команд SVN с 2 аргументами, такими как «move», вы должны добавлять «@» только к левому (первому) параметру. Например:

$ svn add README@txt@
A         README@txt

$ svn move README@txt@ README2@txt
A         README2@txt
D         README@txt


$ svn status
A       README2@txt

$ svn commit -m "blah"
Adding         README2@txt
Transmitting file data .
Committed revision 168.

$ svn delete README2@txt@
D         README2@txt

$ svn commit -m "blahblah"
*Deleting       README2@txt

Committed revision 169.

Эта строка важна: $ svn move README @ txt @ README2 @ txt

Как видите, нам не нужно добавлять «@» в «README2 @ txt»


0

@ Дэвид Х

Я только что попробовал подобную команду без экранирования символов @, и она все еще работает нормально

svn ci splash.png splash@2x.png@

Это на GNU bash, версия 3.2.48 (1) -релиз (x86_64-apple-darwin10.0) и svn 1.6.16


0

Единственное решение, которое сработало для меня, было предложено @NPike.

SVN вернуть 'путь / к / имя файла @ ext @'


Вы уверены, что это должен быть новый ответ на оригинальный вопрос? Это должно быть скорее голосование или комментарий
Нико

извините, мой плохой, я не могу добавить комментарий
Jonyx4

0

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

Решение, использование printfопций findи расширение оболочки

 svn add  $(find . -name "*@*.png" -printf "%p@ ")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.