nyaload

Журнал Пушыстого

Журнал Пушыстого

Previous Entry Share Next Entry
Туториал по консольному svn на русском
nyaload
_winnie
Если вам вдруг понадобится работать с клиентом svn, причем с консольным, то вот краткий туториал:


Для Windows есть шикарный TortoiseSVN, в нём есть даже diff для png и doc-файлов, плюс няшный текстовый дифф после интеграции с WinMerge (дефолтный дифф - тоже хороший), удобная history и blame, ускорение работы корректным кешированием всего, настройки оптимизации для монстровых репозиториев на гигабайты ("не показывать иконки рекурсивно или на сетевых не-SSD дисках") и тд, всё для людей.

AFAIK, для макоси и линукса, таких крутых нет ( http://stackoverflow.com/questions/899/best-subversion-client-for-mac-os ), и лучше использовать консольный. Лучше таки установить какой-нибудь gui-шный, так как для просмотра истории коммитов от 10 людей, и диффов - лучше убогий gui, чем любой консольный. Для компании - веб-интерфейс WebSVN, чтобы коллега в один клик по линку в почте мог поглядеть на файл или дифф.

Основные команды консоли:
-----------------------------
Терминология:
* "рабочая копия" (working copy) - директория на вашем компьютере, в которой вы меняете файлы.
* "репозиторий" - общая база с кодом
* "ревизия" - Каждое изменение (коммит) репозитория - нумеруется. Номер каждого изменения на 1 больше предыдущего, называется "ревизией".
-----------------------------
Взять папку из репозитория в свою рабочую копию, команду нужно набирать только один раз при создании новой рабочей копии:
svn checkout https://путь-к-нужной-папке
Папку можно взять любую, не обязательно проект целиком
-----------------------------
svn up — взять чужие изменения в свою рабочую копию

положить в общий репозиторий то, что наменял в своей папке:
svn commit -m "комментарий"
или
svn commit (файлы и папки) -m "комментарий"

svn revert файл — безвозвратно отменить свои исправления в файле (только у себя, на репозиторий это не действует).
-----------------------------
SVN надо явно прописать какие файлы ты добавил и удалил в рабочей копии. И потом закоммитать, сами по себе эти команды меняют только рабочую копию.
svn add файл
svn rm файл
-----------------------------
Посмотреть, что поменял у себя:
svn stat
svn stat (файлы и папки)

Статусы svn stat:
  M: модификация файла
  D: файл удалён
  A: файл добавлен
  !: файл отсутствует, если надо закоммитать удаление, то надо явно указать svn rm
  ?: новый файл, если надо его закоммитать, то надо явно сделать svn add на него

svn diff — для просмотра изменений в содержимом файлов. В линуксе полезно отфильтровать вывод через colordiff, или перенаправить в файл, а файл открыть программистским редактором с подсветкой.
-----------------------------
История коммитов:
svn log --limit 10 — последние 10 коммитов
svn diff --summary -c 12345 — какие файлы поменяли в ревизии 12345
svn diff -c 12345 — все изменения внутри файлов в ревизии 12345.
svn blame файл | grep 'только нужная строка' - кто и когда поменял эту строчку в файле


Советы:
При любых загадочных проблемах - всегда можно взять checkout чистой копии в новую рабочую папку, и продолжить менять файлы в ней, вручную забрав изменения из старой папки.
-----------------------------
Если вам надо работать одновременно над разными задачами - лучше держать их в разных рабочих копиях.
-----------------------------
файлы лучше переименовывать "svn rename", а копировать "svn copy". Тогда сохраняется история файла.
-----------------------------
Нельзя долго держать у себя крупные незакоммиченные изменения.
-----------------------------
В идеале вывод команды svn stat должен всегда умещаться на одном экране, и все изменения - относиться к одной фиче. Временные файлы - держать вне репозитория или поставить как игнорируемые. Написание фичи организовать так, что можно её постепенно коммитать маленькими кусочками, не мешая другим людям. От переключения в конфиге до if (false). Если невозможно коммитать кусочками, то можно сделать свою "ветку" ( в SVN это неудобно, лучше придумать как дописывать в общий код ). Скопировать рядышком директорию или файл внутри проекта и закоммитать - это тоже "ветка", и может быть удобней чем глобальное копирование проекта.
-----------------------------

Более редкие команды:
Эти команды нужны реже, можно не заучивать и подглядывать только когда припечет:

Если работу клиента прервали на середине, то он оставляет временные lock-файлы, и возникают жалобы "Working copy locked".
Команда "svn cleanup" почистит эти lock-файлы.
-----------------------------
"ветки" делаются копированием директорий в общем репозитории (svn copy svn://путь_в_репозитории_откуда svn://куда -m "комментарий"), создание ветки - дешево. Типично "общая копия" - в /project/trunk, ветки - в /project/branches/my-foo-branch-1, /project/branches/my-bar-branch-2, люди забирают на компьютер только /project/trunk или свою ветку.
-----------------------------
При конфликтах при апдейте (svn up) можно выбрать полностью чужую версию файла ('tf' - theirs full), полностью свою ('mf' - mine full).
И ещё "разобраться потом" ('p' - postpone). Если "разобраться потом", то для проблемного файла "file.foobar" образуются три файла "file.foobar.mine" (где все ваши локальные изменения в нетронутом виде), "file.foobar.r123" "file.foobar.r124". В файл "file.foobar" попадает полусмерженый вариант, где "<<<< .... >>>>" выделены конфликты. Для разрешения конфликта достаточно отредактировать file.foobar в нужный вид и удалить .mine, .r123, .r124
-----------------------------
Применение патчей, универсально работает даже между разными version control systems с коннектом по флешке:
svn diff (файлы-или-url, ревизия если надо) > patch.diff
patch -i < patch.diff

Откат ревизии 123 в своей рабочей копии:
svn merge -c -123 ./файл --ignore-ancestry

Накат обратно ревизии 123 в своей рабочей копии:
svn merge -c +123 ./файл --ignore-ancestry

"--ignore-ancestry" нужно чтобы работать просто на уровне применения текстовых diff. Без этого флага образуется svn:merge мета-информация, полезная для активного сложного merge между многонедельными ветками, но вредная при простом редком откате коммитов.
В самом общем виде svn merge принимает на вход три координаты простанства+времени(пути+ревизии): считает разницу между двумя и применяет к третьей.
-----------------------------
Игнор файлов:
svn propset svn:ignore '' файл
Игнор по маске:
svn propset svn:ignore '' '*.txt' #кавычки важны
и закоммитать директорию (информация об игноре файлов в директории - это "свойство" директории)
-----------------------------
Интеграция с vimdiff:

$ cat ~/bin/svnvimdiff
    #!/bin/sh
    svn diff --diff-cmd ~/bin/_svnvimdiff_helper "$@"
$ cat ~/bin/_svnvimdiff_helper
    shift 5
    vimdiff "$@"

Tags:

  • 1
всё, что нужно знать про svn, есть в man git-svn :)

> или перенаправить в файл, а файл открыть программистским редактором с подсветкой.
svn diff | vim -

Предпочитаю view -, чтобы буфер был еще и read-only.

Да, я думаю, многие тебе за это спасибо скажут!

полезно!
svn cleanup лучше всё-таки тоже выучить)

А вот скажи лучше, как в svn делать git add -i > patch? Я вот каждый раз ржу над знакомыми, которые при попытке закоммитить часть изменений начинают судорожно делать ещё один чекаут, руками что-то править, делать кривые коммиты, и потом ещё делать патчи с фиксапами.

Про интеграцию с vimdiff тоже посмеялся, спасибо.


У меня есть TortoiseSVN, linux, bash и чуточку сумеречной гениальности, это решает все проблемы!


У TortoiseSvn есть фича "коммитать файл кусками", я её ещё не смотрел (редко приходится решать эту проблему).


Довольно легко не смешивать разные фичи в одной папке. У меня сейчас на работе код лежит в трёх разных папках.


Коммитать разные файлы по отдельности - никаких проблем. Если нужно воспроизвести список коммитаемых файлов в точности как неделю назад - мне помогает хистори bash ( Ctrl+R ). Есть ещё какие-то changelist-ы, но хистори баша хватает.


Если надо закоммитать только часть изменений файла (это охтунге, и я стараюсь просто так никогда делать, но раз в несколько месяцев почему-то приходится):
cp file file.tmp;
vimdiff file file.tmp; # оставляю в file только нужные куски
запуск-тестов-или-компиляции;
svn commit file;
mv file.tmp file


Иногда я таскаю изменения между папками как это делали 30 лет назад,
cd project_copy_A/xxx
svn diff > ~/patch
cd project_copy_B/xxx
patch < ~/patch

И согласен с теми, кто говорит, "слишком много времени уделяют VCS". У меня на заваривание чая Greenfield в пакетиках уходит больше времени, чем на SVN, так что странно оптимизировать это место.
Я жду момента, когда буду должен использовать git потому что все коллеги на нём, либо он станет няшным, как github.

BTW, любопытный факт: новые сотрудники как один ноют "почему не git", где-то десятая часть пытается проверить что будет если перенести репозиторий в git, и результат такой - что если без веток, то за несколько суток происходит конвертация в неюзабельный 50-гигабайтный репо, а с ветками - никто не дождался. После чего наиболее принципиальные остаются на git-svn.

> Если надо закоммитать только часть изменений файла (это охтунге, и я стараюсь просто так никогда делать, но раз в несколько месяцев почему-то приходится):
> cp file file.tmp;
> vimdiff file file.tmp; # оставляю в file только нужные куски
> запуск-тестов-или-компиляции;
> svn commit file;
> mv file.tmp file
>
>
> Иногда я таскаю изменения между папками как это делали 30 лет назад,
> cd project_copy_A/xxx
> svn diff > ~/patch
> cd project_copy_B/xxx
> patch < ~/patch
Да-да, именно над этим я и ржу.

> BTW, любопытный факт: новые сотрудники как один ноют "почему не git", где-то десятая часть пытается проверить что будет если перенести репозиторий в git, и результат такой - что если без веток, то за несколько суток происходит конвертация в неюзабельный 50-гигабайтный репо, а с ветками - никто не дождался. После чего наиболее принципиальные остаются на git-svn.
А это всё потому, что svn ДИКО тормозной. А также, для справки, сколько весит working dir и суммарно все .svn?

Ответил в личку

> cp file file.tmp;

Lifehack: Открыть файл в другом редакторе, отредактировать, сделать дело, переключиться в основной редактор и перезаписать файл. Плюс — не нужно придумывать имя временного файла, меньше жать клавиши, не остаётся мусора. Минус — чревато стрельбой в ногу (как и cp file file.tmp), поэтому для коммита я всё же использовать это не рискую, только для быстрого тестирования.

  • 1
?

Log in