SVN: Есть ли способ пометить файл как «не фиксировать»?


153

С помощью TortoiseSVN я могу переместить файл в список изменений ignore-on-commit, чтобы при фиксации всего дерева изменения в этом файле не фиксировались.

Есть ли способ сделать что-то подобное с помощью инструмента командной строки svn?

РЕДАКТИРОВАТЬ: Спасибо за предложения, чтобы использовать svn:ignore, но это не совсем то, что я искал.

svn:ignoreвлияет на такие вещи, как svn add& svn import. Это дает ему список шаблонов имен файлов, которые следует игнорировать.

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


1
Есть способ, использующий персональную ветку и статус переключателя. [См. Мой другой пост на эту тему.] [1] [1]: stackoverflow.com/questions/862950/…
ptitpion

Ответы:


120

Subversion не имеет встроенной функции «не фиксировать» / «игнорировать при фиксации», по состоянию на февраль 2016 г. / версия 1.9. Этот ответ - неидеальный обход командной строки

Как указывает OP, TortoiseSVN имеет встроенный список изменений «ignore-on-commit», который автоматически исключается из коммитов. У клиента командной строки этого нет, поэтому вам нужно использовать несколько списков изменений, чтобы выполнить то же поведение (с оговорками) :

  • один для работы, которую вы хотите совершить [работа]
  • один для вещей, которые вы хотите игнорировать [ignore-on-commit]

Поскольку у TortoiseSVN есть прецедент, я использую «ignore-on-commit» в моих примерах для файлов, которые я не хочу фиксировать. Я буду использовать «работу» для файлов, которые я делаю, но вы можете выбрать любое имя, которое захотите.

Сначала добавьте все файлы в список изменений с именем «работа». Это должно быть запущено из корня вашей рабочей копии:

svn cl work . -R

Это добавит все файлы в рабочей копии рекурсивно в список изменений с именем "work". В этом есть недостаток - поскольку новые файлы добавляются в рабочую копию, вам нужно будет специально добавлять новые файлы, иначе они не будут включены. Во-вторых, если вам придется запустить это снова, вам нужно будет снова добавить все ваши файлы «ignore-on-commit». Не идеально - вы можете начать поддерживать свой собственный список игнорирования в файле, как это сделали другие.

Затем для файлов, которые вы хотите исключить:

svn cl ignore-on-commit path\to\file-to-ignore

Поскольку файлы могут быть только в одном списке изменений, запуск этого дополнения после предыдущего «рабочего» добавления приведет к удалению файла, который вы хотите игнорировать, из списка «рабочих» изменений и внесению его в список изменений «ignore-on-commit».

Когда вы будете готовы зафиксировать ваши измененные файлы, которые вы хотите зафиксировать, вы просто добавите «--cl work» к вашему коммиту:

svn commit --cl work -m "message"

Вот как выглядит простой пример на моей машине:

D:\workspace\trunk>svn cl work . -R
Skipped '.'
Skipped 'src'
Skipped 'src\conf'
A [work] src\conf\db.properties
Skipped 'src\java'
Skipped 'src\java\com'
Skipped 'src\java\com\corp'
Skipped 'src\java\com\corp\sample'
A [work] src\java\com\corp\sample\Main.java
Skipped 'src\java\com\corp\sample\controller'
A [work] src\java\com\corp\sample\controller\Controller.java
Skipped 'src\java\com\corp\sample\model'
A [work] src\java\com\corp\sample\model\Model.java
Skipped 'src\java\com\corp\sample\view'
A [work] src\java\com\corp\sample\view\View.java
Skipped 'src\resource'
A [work] src\resource\icon.ico
Skipped 'src\test'

D:\workspace\trunk>svn cl ignore-on-commit src\conf\db.properties
D [work] src\conf\db.properties
A [ignore-on-commit] src\conf\db.properties

D:\workspace\trunk>svn status

--- Changelist 'work':
        src\java\com\corp\sample\Main.java
        src\java\com\corp\sample\controller\Controller.java
        src\java\com\corp\sample\model\Model.java
M       src\java\com\corp\sample\view\View.java
        src\resource\icon.ico

--- Changelist 'ignore-on-commit':
M       src\conf\db.properties

D:\workspace\trunk>svn commit --cl work -m "fixed refresh issue"
Sending        src\java\com\corp\sample\view\View.java
Transmitting file data .done
Committing transaction...
Committed revision 9.

Альтернативой было бы просто добавить каждый файл, который вы хотите зафиксировать, в «рабочий» список изменений, и даже не поддерживать список игнорирования, но это тоже большая работа. Действительно, единственное простое, идеальное решение - если / когда это будет реализовано в самом SVN. Существует давняя проблема об этом в системе отслеживания проблем Subversion, SVN-2858 , на случай, если это изменится в будущем.


1
Я добавил два файла с командой, которую вы упомянули: $svn st --- Changelist 'ignore-on-commit': M database.php M config.php и тем не менее, они были отправлены в репозиторий при коммите. Есть идеи, что я сделал не так?
Аттила Фулоп

7
Добавление файлов в список изменений «ignore-on-commit» само по себе не препятствует фиксации файлов. TortoiseSVN (клиент с графическим интерфейсом Windows) поддерживает «ignore-on-commit», а командная строка svn - нет. Единственное предложение, которое я получил в своем первоначальном ответе, состояло в том, чтобы добавить файлы, которые вы хотите зафиксировать, в список изменений, и сказать ему, чтобы это зафиксировать
Джошуа Маккиннон

7
ignore-on-commit определенно является зарезервированным списком черепах. Все, что он делает, - это предотвращает проверку элементов в графическом интерфейсе по умолчанию, так что это особенность Tortoise GUI. Вам не нужно использовать командную строку для добавления в список, если вы используете графический интерфейс. Просто контекстное меню на элементах списка коммитов, и внизу вы можете переместить их в список изменений, и игнорирование при фиксации уже определено. tortoisesvn.net/docs/release/TortoiseSVN_en/…
tjmoore

это не делало Джек. он совершил все.
Анбизкад

Не работает, вопрос специально задан о решении командной строки, а не GUI.
РИВ

26

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

Я работаю с командной строкой Linux: поэтому я решил создать скрипт / usr / bin / svnn (да, с двумя 'n'!) Следующим образом:

#! /bin/bash
DIR=/home/mike/dev/trunk

IGNORE_FILES="\
        foo/pom.xml \
        foo/src/gwt/App.gwt.xml \
        foo/src/main/java/gwt/Common.gwt.xml \
        foo/src/main/resources/context/datasource/local.xml \
        foo/src/main/resources/context/environment/local.xml"

for i in $IGNORE_FILES; do mv $DIR/$i $DIR/"$i"_; done;

svn "$@"

for i in $IGNORE_FILES; do mv $DIR/"$i"_ $DIR/$i; done;

Очевидно, это приспособлено к моей ситуации, но просто измените DIR и IGNORE_FILES в соответствии с вашими настройками разработчика. Помните, чтобы изменить сценарий на исполняемый с:

sudo chmod +x /usr/bin/svnn

..то вы просто используете «svnn» вместо «svn» для запуска subversion, не опасаясь проверять локальные изменения файлов в списке IGNORE_FILES. Надеюсь, это поможет!


Наконец, этот ответ на самом деле правильный. Вам нужно написать какой-нибудь инструмент. Это на самом деле несовершенно, потому что я хочу иметь динамическую опцию, например svnn ignore configs/*- с подстановочными знаками, а также с наворотами. Я думаю, что сам напишу что-то подобное, а потом вернусь сюда!
Томаш Гандор

это круто! Более того, создайте псевдоним в .bashrc для svn -> svnn. Более того, вместо указания файлов, которые должны игнорироваться внутри команды, он может вести себя как git, он будет проверять файл .ignore внутри папки и игнорировать каждый файл, соответствующий шаблону.
Тарек

Вместо того, чтобы заново учиться печатать svnn, подумайте над тем, чтобы вызвать его svnи поместить этот скрипт во что-то, что может быть в начале вашей PATH, например ${HOME}/bin. Из самого скрипта вы бы потом позвонили /usr/bin/svn.
Joost

17

Я не верю, что есть способ игнорировать файл в хранилище. Мы часто сталкиваемся с этим с помощью web.config и других файлов конфигурации.

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

Например, в репо есть файл с именем по web.config.defaultумолчанию. Затем создайте задачу nant, которая переименует все web.config.defaultфайлы, web.configкоторые затем можно настроить на локальные значения. Эта задача должна вызываться при получении новой рабочей копии или запуске сборки.

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


8

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

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


1
Но это именно то, что мы хотим. Например, исходный файл, который вам нужно установить defaultUserId = yourId вместо системного по умолчанию.
orbfish

4

Я пришел к этой теме в поисках способа сделать «атомарную» фиксацию только из нескольких файлов, и вместо игнорирования некоторых файлов при фиксации я пошел другим путем и зафиксировал только те файлы, которые хотел:

svn ci filename1 filename2

Может быть, это кому-то поможет.


Ваш ответ - только одно адекватное предложение в этой теме. svn ciэто просто псевдоним svn commit. Команда commit позволяет сделать конкретный коммит из указанных файлов
oxfn

3

Ребята я только что нашел решение. Учитывая, что TortoiseSVN работает так, как мы хотим, я попытался установить его под Linux - что означает запуск на Wine. Удивительно, но это работает! Все, что вам нужно сделать, это:

  1. Добавьте файлы, которые вы хотите пропустить, запустив: "svn changelist 'ignore-on-commit'".
  2. Используйте TortoiseSVN для фиксации: "~ / .wine / drive_c / Program \ Files / TortoiseSVN / bin / TortoiseProc.exe / команда: commit / path: '
  3. Исключенные файлы будут отключены для фиксации по умолчанию, в то время как другие измененные файлы будут проверены. Это точно так же, как под Windows. Наслаждайтесь!

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


2

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

Чтобы получить конфликт a-file, ваша рабочая копия (WC) не имеет обновлений a-fileиз хранилища, и что a-fileв вашем WC есть изменения, которые находятся в том же месте, что и изменения в хранилище (изменения, которые вы не обновляли) до сих пор). Если вы не хотите ждать вышеуказанных условий, вы можете создать конфликт, a-fileнапример, такой:
В рабочей копии 1 (WC1) добавьте строку текста вверху a-file, например, «создать конфликт здесь» . Используйте необходимый синтаксис, чтобы не нарушать хранилище. Зафиксировать a-fileиз WC1. В WC2 добавьте другую строку текста вверху a-file, например: «Я хочу конфликт» . Обновление с WC2, и теперь a-файл должен конфликтовать.


1

Вместо этого я бы написал вспомогательный bash-скрипт, который запускает svn commitвсе нужные вам файлы и ни один из тех, которые вам не нужны. Таким образом, у вас гораздо больше контроля.

Например, с одной линией, вы можете совершить все файлы с расширением .hи .cppк которому были внесены изменения (и который не приведет к конфликту):

svn commit -m "" `svn status | grep "^M.*[h|cpp]$" | awk '{print $2}' | tr "\\n" " "`

Изменить / добавить расширения к [h|cpp]детали. Добавьте сообщение журнала между кавычками, -m ""если это необходимо.


1

Некоторые из предложенных идей могут быть реализованы следующим образом:

На Windows в PowerShell

добавить все в default.ps1

dir -Recurse | ? { -not $_.PSIsContainer } | % { svn cl default $_.FullName }

добавить, чтобы игнорировать list.ps1

 dir file1 ... filN  % { $_.FullName } > ignore-on-commit
 cat .\ignore-on-commit | % { svn cl ignore-on-commit $_ }
 svn add ignore-on-commit

Теперь вы можете использовать псевдоним, svn ci --changelist defaultчтобы вам не приходилось указывать его каждый раз. Дополнительным преимуществом является то, что вы можете хранить список игнорируемых при фиксации (если хотите) в хранилище.

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


1

Я устал ждать, пока это встроится в SVN. Я использовал tortoiseSVN с ignore-on-commit, но при этом появляется диалоговое окно пользователя, которое вы не можете отключить из командной строки, и когда я запускаю свой скрипт сборки и собираюсь выпить чашку чая, я ненавижу его, когда Я возвращаюсь и обнаруживаю, что он ждет ввода пользователя 10% пути.

Итак, вот скрипт Windows PowerShell, который фиксирует только файлы, которых нет в списке изменений:

# get list of changed files into targets
[XML]$svnStatus = svn st -q --xml C:\SourceCode\Monad
# select the nodes that aren't in a changelist
$fileList = $svnStatus.SelectNodes('/status/target/entry[wc-status/@item != "unversioned"]') | Foreach-Object {$_.path};
# create a temp file of targets
$fileListPath =  [IO.Path]::GetTempFileName();
$fileList | out-file $fileListPath -Encoding ASCII
# do the commit
svn commit --targets $fileListPath -m "Publish $version" --keep-changelists 
# remove the temp file
Remove-Item $filelistPath

1

Обновление скрипта user88044.

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

Сценарий извлекает файлы do-not-commit из команды: svn status --changelist 'do-not-commit'

#! / bin / bash DIR = "$ (pwd)"

IGNORE_FILES = "$ (svn status --changelist 'do-not-commit' | tail -n +3 | grep -oE '[^] + $')"

для меня в $ IGNORE_FILES; do mv $ DIR / $ i $ DIR / "$ i" _; сделано;

svn "$ @";

для меня в $ IGNORE_FILES; do mv $ DIR / "$ i" _ $ DIR / $ i; сделано;

Скрипт находится в / usr / bin / svnn (sudo chmod + x / usr / bin / svnn)

svnn status, svnn commit и т.д ...


1

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

1) Нажмите «SVN Commit ...» (мы не будем фиксировать, это просто способ найти графическое меню для списка изменений). 2) В списке Щелкните правой кнопкой мыши файл, который вы хотите исключить. 3) Меню: перейти к списку изменений> игнорировать при фиксации

В следующий раз, когда вы выполните SVN Commit ... Файлы будут отображаться в конце списка, в категории ignore-on-commit.

Протестировано с: TortoiseSVN 1.8.7, сборка 25475 - 64-битная, 2014/05/05 20:52:12, Subversion 1.8.9, -релиз


1
youps, я только что видел комментарии tjmoore, которые уже дают полезную информацию для пользователя tortoiseSVN ... нет командной строки tortoisesvn.net/docs/release/TortoiseSVN_en/…
luney

Это сломано в 1.9?
Джейк Хм

1

Это поздно для игры, но я нашел самую удивительную команду командной строки для этой проблемы. Закончено с использованием bash. Наслаждаться.

svn status | grep -v excluding | sed 's/^A */"/g; s/$/"/g' | tr '\n' ' ' | xargs svn commit -m "My Message"

Итак, вот объяснение команды. Некоторые вещи необходимо будет изменить в зависимости от вашего варианта использования.

svn status

Я получаю список всех файлов. Все они начнутся с этих символов статуса (?,!, A и т. Д.). У каждого свои линии

grep -v excluding

Я использую grep для фильтрации списка. Он может использоваться как обычно (для включения), так и с флагом -v (для исключения). В этом случае он используется для исключения, а фраза «исключение» - это то, что будет исключено.

sed 's/^. */"/g; s/$/"/g'

Теперь я удаляю символ статуса и пробел в начале каждой строки, а затем цитирую каждую строку, используя sed. В некоторых моих именах файлов есть пробелы, отсюда и цитата.

tr '\n' ' '

Используя tr, я заменяю все символы новой строки пробелами. Теперь весь мой список файлов для фиксации находится в одной строке.

xargs svn commit -m "My Message"

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

В результате все в конечном итоге работает так, как я хочу. Я все еще ненавижу svn за то, что заставлял меня прыгать через эти проклятые обручи, но я могу с этим смириться. Я думаю.


0

Поскольку я столкнулся с той же самой проблемой, и мой поиск в Google продолжал давать мне ничего, я думаю, что нашел обходной путь. Вот то, что я сделал, похоже, у меня работает, но поскольку я застрял со старой версией SVN (<1.5, поскольку у нее нет опции --keep-local), и я не эксперт в этом Я не могу быть уверен, что это универсальное решение. Если это работает и для вас, пожалуйста, дайте мне знать!

Я имел дело с установкой Prestashop, которую я получил из SVN, так как другие люди уже начали работать над ней. Поскольку настройки БД были выполнены для другого сервера, я изменил их в каком-то файле в папке / config. Поскольку эта папка уже была версионной, установка ее в svn: ignore не помешает моим локальным изменениям на ней быть зафиксированными. Вот что я сделал:

cp config ../cfg_bkp              # copy the files out of the repo
svn rm config                     # delete files both from svn and "physically"
svn propset svn:ignore "config" . # as the files no longer exists, I can add my ignore rule and then...
mv ../cfg_bkp config              # ...bring'em back
svn revert --recursive config     # make svn forget any existing status for the files (they won't be up for deletion anymore)

Теперь я могу запустить svn add --force. в корне репо без добавления моего конфига, даже если он не соответствует версии репо (я думаю, мне пришлось бы пройти через все это снова, если бы я изменил его еще раз, не тестировал). Я также могу обновить svn, не перезаписывая файлы и не получая ошибок.


0

Решение, которое не игнорирует изменения в свойствах каталога

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

svn ci --cl work -m "this commits files from the work changelist only"
svn up
svn ci --depth empty DIR . -m "record merge properties"

Возможно, вам придется сделать это для нескольких каталогов (здесь я записываю свойства DIRи текущего каталога .), в основном те, которые Mво втором столбце содержат svn statusкоманду a при вводе команды.

Решение

Я использовал патчи и svn patch. В псевдокоде:

svn diff $IGNORE_FILES > MYPATCH   # get the mods to ignore
svn patch --reverse-diff MYPATCH   # remove the mods
svn ci -m "message"                # check-in files and directory properties
svn patch MYPATCH                  # re-apply the mods

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

#! /usr/bin/env bash

finish() {
    svn patch MYPATCH               # re-apply the mods
}
trap finish EXIT

IGNORE_FILES="\
sources/platform/ecmwf-cca-intel-mpi.xml \
runtime/classic/platform/ecmwf-cca.job.tmpl \
runtime/classic/platform/ecmwf-cca-intel.xml"

svn diff $IGNORE_FILES > MYPATCH # get the mods to ignore
svn patch --reverse-diff MYPATCH # remove the mods

svn "$@"

Я обычно использовал это с ciи revert -R ..


-1

svn:ignore это твой ответ.

Пример:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'

1
Обратите внимание, что в приведенном выше примере показано, как использовать предварительно настроенный файл cvsignore в качестве входных данных для свойства svnignore.
Бен Хоффштейн

1
нет SVN: игнорировать только для файлов версии. не работает с файлами версий
Sérgio

1
И тоже не местный. Это изменение свойства, которое будет зафиксировано само по себе.
Адам Бадура

-9
svn propset "svn:ignore" "*.xml" .

*.xmlявляется образцом игнорируемых файлов; Вы также можете использовать имена каталогов здесь.


3
-1, потому что вы не можете игнорировать файл, который является частью хранилища.
Зеллус
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.