Subversion: запретить локальные изменения одного файла?

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

Обратите внимание, что хотя я не хочу фиксировать свои изменения, я хочу получать любые обновления, сделанные в репозитории, когда я делаю svn update. Кроме того, только в моей рабочей копии я не хочу фиксировать изменения в этом файле, другие пользователи не должны быть затронуты. Поэтому svn:ignore или фиксация фиксации не соответствуют моей цели.

В настоящее время я просто делаю:

svn commit file1 file2...

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

Однако, пока я работаю, у меня есть привычка просто писать:

svn commit -m "Log of what I just did"

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

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

Существует ли такая вещь?

Обновить: akent, спасибо, что указал на этот очень похожий вопрос.

Ответ 1

Было несколько ответов, которые могут работать:

  • Создайте крюк pre-commit script, который отклоняет фиксацию при добавлении определенного свойства. Затем вы можете добавить это свойство в файлы рабочей копии, чтобы предотвратить коммит.
  • TortoiseSVN исключает файлы в специальном списке изменений "ignore-on-commit". Однако это не выполняется клиентом командной строки SVN.

CoverosGene предположил, что команды по умолчанию, такие как svn commit, работают с списком изменений по умолчанию, поэтому вы можете исключить файл, если вы назначили его другому списку изменений, но я не могу найти ссылки на это в документации и в моем тестировании это не работает.

Поскольку нет хорошего решения для клиента командной строки SVN, я открыл здесь запрос расширения здесь. В запросе указывается, что клиент командной строки также может соблюдать список изменений "ignore-on-commit".

Обновление: теперь это issue 2858, и есть контур функции, чтобы обработать его с помощью свойства svn:hold.

Ответ 2

Я понимаю вашу проблему; вероятно, этот "запрещенный" файл содержит параметры конфигурации и тому подобное, которые имеют отношение только к вашей локальной среде сборки. Я не нашел способ напрямую SVN просто игнорировать изменения в файле с версией, но вот обходной путь, который я использовал в прошлом.

Предполагая, что ваш файл вызывается, скажем, "build.conf". Назовите файл с версией SVN, похожий на файл build.conf.example. Затем в вашем Makefile или build script или что угодно, вы можете автоматически скопировать файл build.conf.example в реальный файл build.conf, который остается неверсифицированным. Затем вы svn игнорируете build.conf, и каждый разработчик может затем внести в него любые локальные изменения.

Но "должен быть лучший способ"...

Изменить: Почти идентичный вопрос здесь: SVN: есть ли способ отметить файл как "не совершать" ,

Ответ 3

Создайте changelist с этим файлом, а затем просто не обращайте внимания на список изменений. Файл будет сидеть там, ожидая, чтобы его совершили, но ваши обычные коммиты, которые работают с списком изменений по умолчанию, никогда не подберут его.

svn changelist mylocal file1

создаст список изменений под названием mylocal и назначит ему файл file1.

Ответ 4

Собственно, pre-commit script выполнит задание.

Запишите pre-commit script, который выполняет 'svnlook diff' и отклоняет фиксацию, если в наборе изменений установлено свойство с именем nocommit.

Затем в вашей рабочей копии вы можете просто установить свойство "nocommit" в любом файле, который не должен быть зафиксирован. Любая последующая фиксация не будет выполнена, если какой-либо файл имеет свойство "nocommit" . Если позже вам нужно проверить изменения в файле, все, что вам нужно сделать, это удалить свойство "nocommit" из вашей рабочей копии.

Ответ 5

Говоря о Tortoisesvn и списках изменений, он уже поставляется с списком изменений, называемым ignore-on-commit, который делает то, что вы ищете.

Ответ 6

Из моего опыта: не помещайте этот файл под контроль версий и используйте svn: ignore на нем.

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

Для нового репо:

mkdir config
svn add config
svn propset svn:ignore '*.conf' config 

Для существующего репо: убедитесь, что у вас есть резервная копия вашей конфигурации в каждой рабочей копии, затем удалите (svn del) config из репо, зафиксируйте (обратите внимание: файл будет удален в каждой рабочей копии при следующем обновлении у вас должна быть резервная копия), а затем восстановить файл и установить свойство ignore.

Другой способ - это блокировка. Это гарантирует, что никто не фиксирует файл, но это приведет к ошибке при каждой фиксации. не очень приятно.

И третий способ - changeets, новая функция в клиентах SVN 1.5. Это аккуратно, но оно связано только с одной рабочей копией, а не с хранилищем по всему миру. И вы должны настроить их вручную, добавить каждый новый файл - его трудно поддерживать.

Ответ 7

В течение последних нескольких лет я использую простое решение, которое обеспечивает именно то, что вы ищете. Он называется ключевым словом NOCOMMIT.

Что я делаю, так это то, что у меня есть привязка pre-commit в моем репозитории SVN, который проверяет, содержит ли какой-либо файл строку NOCOMMIT, и если да, то она не выполняет commit.

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

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

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

Если вы используете окна, вы можете вставить следующий текст в файл с именем pre-commit.bat в папку hooks вашего репозитория SVN.

:: Stops commits that contain the NOCOMMIT keyword.
setlocal  
set REPOS=%1  
set TXN=%2           
SVNLook diff %REPOS% -t %TXN% | findstr /I /M /L NOCOMMIT > nul
if %errorlevel% gtr 0 (
    exit 0
) else (
    echo Your commit has been blocked because it contains the keyword NOCOMMIT. 1>&2  
    exit 1
)

В системах Unix что-то вроде следующего должно сделать трюк, хотя учтите, что я его не тестировал.

#!/bin/sh
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/local/bin/svnlook
$SVNLOOK diff -t "$TXN" "$REPOS" | grep -i "NOCOMMIT" > /dev/null && { echo "Your commit has been blocked because it contains the keyword NOCOMMIT." 1>&2; exit 1; }

Ответ 8

Блокировка, конечно же, не то, что вы хотите, и я не думаю, что какая-либо из встроенных функций сделает это за вас.

В зависимости от среды, в которой вы работаете, я напишу script, который:

  • Получает список файлов
  • Удаляет те, которые я не хочу комментировать
  • Записывает файлы

Что-то по строкам:

svn status | grep ^M | grep -v exclude.c | awk -F' ' '{print $2}' | xargs svn ci -m "I'm committing something"

Или, если список файлов действительно статичен, просто исправьте список!

Ответ 9

Этот вопрос находится в FAQ по Subversion. Но ответ не очень полезен, если вы не контролируете репозиторий.

Возможно, попробуйте управлять локальной копией с помощью git поверх подрывной деятельности. Существует простой . Затем вы можете использовать git-svn для отслеживания изменений в репозитории svn и для внесения изменений. Это потребует обучения и обучения.

Ответ 11

Добавьте все файлы в список изменений, а затем удалите файлы, которые вы не хотите совершать. Наконец, скопируйте список изменений, как показано ниже:

$ svn status
M file01 
M ...
M file100
M file_not_ready_for_commit

// This will add all working copy files, can be adjusted to add only relevant files
$ svn changelist mychangelist -R .

// Remove the nascent one(s)
$ svn changelist mychangelist --remove file_not_ready_for_commit

// Commit only the files in the changelist
$ svn commit --changelist mychangelist

Источник вышеуказанной информации - это блог, который также имеет ссылку на http://svnbook.red-bean.com для получения дополнительной информации. Все кредиты автору блога.

Ответ 12

Вы можете использовать крюк предварительной фиксации. На крючке используйте svnlook author, чтобы узнать, являетесь ли вы тем, кто совершает изменения. Если да, используйте svnlook changed, чтобы увидеть, если вы меняете один из запрещенных файлов.

Ответ 13

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

 svn cp ^/trunk ^/branches/your_name -m "Creating a personal branch."    
 cd working_copy_of_trunk/sub_path/
 svn switch ^/branches/your_name/sub_path/your_file your_file

Обратите внимание, что:

  • Вы можете проверить статус переключения с помощью "S", появляющегося в пятом столбце, с командой: svn status
  • Вы никогда не будете работать в филиале, ваш work_copy_of_trunk по-прежнему синхронизируется с каталогом соединительных линий репозитория, за исключением файлов, которые вы переключили, поэтому всякий раз, когда вы вносите изменения в свой файл, коммиты для этого файла будут выполняться на вашей ветке, а не на ствол.
  • Копия выполнена на стороне сервера, и это рекомендуется с помощью svn. Полная копия на стороне сервера мгновенно и больше не занимает места на сервере. Тем не менее, также рекомендуется, чтобы люди не проверяли верхний каталог, содержащий соединительные линии/теги/и ветки /, но напрямую trunk/иначе все файлы будут дублироваться локально при обновлении из этого верхнего каталога. Если это так, то, скорее всего, выберем первую команду с помощью:

    svn cp --parents ^/trunk/sub_path/your_file ^/branches/your_name/sub_path/your_file

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