2015-05-01 3 views
8

Почему-то никто не установил приличные svn:ignore свойства в нашем репозитории, и когда я спросил об этом, ответ был «никто не жаловался на это раньше, не могли бы вы просто оставить «неверуемые предметы» непроверенными? » (Мы почти во всем мире используем TortoiseSVN).Игнорировать определенные каталоги или файлы без использования svn: ignore

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

Я знаю о глобальном списке игнорирования, но the global ignore list does not accept specific paths, только простые одноуровневые шаблоны файлов. Я прочитал question about a local ignore list, но этот вопрос на самом деле не спрашивает об «игнорировании» неверсированных файлов, но на самом деле спрашивает о блокировке коммитов на определенных версиях файлов. Я прочитал еще один question about ignoring a directory locally, как я хочу, но принятый ответ на этот вопрос использует глобальный список игнорирования, который не работает для меня из-за невозможности указать конкретные пути в моей рабочей копии.

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

Есть ли способ локально игнорировать определенные неверсированные каталоги или файлы в моем рабочем дереве копий, не используя svn:ignore?


Update: Текущий топ ответ получает меня очень близко к тому, что я хочу. Это позволяет мне отфильтровывать произвольные файлы в диалоговом окне «проверка изменений» или «фиксации». Однако, если я хочу включить каталог изменений (т. Е. Изменений в версиях свойств каталога), то TortoiseSVN также будет включать все файлы в каталог автоматически (т.е. я не могу оба включить каталог в список, и отфильтровать файлы в каталоге).

ответ

5

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

Можно вручную призывают TortoiseSVN Commit диалога, обеспечивая пути для того, чтобы найти файлы, чтобы совершить, например:

C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe /command:commit /pathfile:"<a file containing paths>" 

Итак, так как вы знаете, какие каталоги & файлов, которые вы хотите игнорировать, вы можете предоставить файл путей, содержащий только те каталоги & файлов, которые вы хотите зафиксировать.

Имейте в виду, что файл пути должен быть в кодировке UTF-16 (little-endian), без спецификации. Пути разделяются новыми строковыми символами. Вы можете создать такой правильный тракты файл (в C#), как это:

string[] paths = { @"c:\code\1\dir1", @"c:\code\1\dir2", @"c:\code\1\dir3\file1.txt" }; 
UnicodeEncoding encoding = new UnicodeEncoding(false, false); 
System.IO.File.WriteAllText(@"C:\temp\pathslist.txt", string.Join("\n", paths), encoding); 

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

Есть пара дополнительных параметров командной строки для TortoiseProc /command:commit, которые вы можете найти here.

Тот же метод будет работать для «Проверить на наличие изменений», заменив /command:repostatus вместо /command:commit. В итоге:

  1. Создать скрипт, который захватывает все имена файлов, представляющие интерес
  2. отфильтровывать все имена файлов, которые не интересны (возможно, от «игнорировать файл» где-то на вашем компьютере).
  3. Запишите список файлов в формате UTF-16 LE (без спецификации).
  4. Вызов TortoiseProc с аргументом /pathfile с указанием списка файлов и /command либо repostatus, либо commit.
  5. При необходимости удалите список файлов.

Дополнительно - Интеграция с «Commit», используя скрипт ловушки

Как в стороне, я нашел один путь «интеграции» путем использования опций Hook сценария TortoiseSVN в настройках , Он по-прежнему использует описанную выше процедуру TortoiseProc, но дополнительно предоставляет возможность использовать контекстное меню TortoiseSVN Commit (с одним причудой).

Определенный язык, который вы используете для скрипта hook, не важен, только чтобы он мог обрабатывать аргументы командной строки и возвращать код выхода. Из документации (here):

Это может быть пакетный файл, исполняемый файл или любой другой файл , который имеет действительный ассоциации файлов Windows, например, скрипт perl.

В этом примере я использовал C#:

static void Main(string[] args) 
{ 
    // Process the three command-line arguments 
    string PATH = args[0] 
     , MESSAGEFILE = args[1] 
     , CWD = args[2]; 

    const string tortoiseProcPath = @"C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe"; 
    const string someArgForOurUse = @"/2E040D90-E3AD-4AC5-AA46-E6D9F1034E55"; 
    const string wantedPathsFile = @"C:\temp\svn_paths_list.txt"; 

    //System.Diagnostics.Debugger.Launch(); 

    System.Diagnostics.Process parentProc = ParentProcessUtilities.GetParentProcess(); 

    // If the parent process isn't what is expected or it has the proprietary argument then exit. 
    if ((parentProc == null) || (!parentProc.MainModule.FileName.Equals(tortoiseProcPath, StringComparison.InvariantCultureIgnoreCase)) 
     || GetProcessCommandLine(parentProc.Id).Contains(someArgForOurUse)) 
     return; 

    // Read all selected path from passed-in the temp file 
    // Each line contains a file/directory selected in Explorer 
    string[] fileLines = System.IO.File.ReadAllLines(PATH); 
    IEnumerable<string> wantedPaths = GetWantedPaths(fileLines); 

    UnicodeEncoding encoding = new UnicodeEncoding(false, false); 
    System.IO.File.WriteAllText(wantedPathsFile, string.Join("\n", wantedPaths), encoding); 

    System.Diagnostics.Process.Start(tortoiseProcPath, "/command:commit /pathfile:\"" + wantedPathsFile + "\" " + someArgForOurUse); 

    Console.Error.WriteLine("Don't worry. Everything will be ok."); 
    Environment.Exit(1); 
} 

private static IEnumerable<string> GetWantedPaths(string[] selectedPaths) 
{ 
    // Do whatever you want here to filter directories and files 
    return selectedPaths; 
} 

// Add System.Management reference 
private static string GetProcessCommandLine(int processId) 
{ 
    System.Management.SelectQuery wmiQuery = new System.Management.SelectQuery("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + processId.ToString()); 
    System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(wmiQuery); 

    foreach (System.Management.ManagementObject obj in searcher.Get()) 
     return obj["CommandLine"].ToString(); 
    return null; 
} 

Для краткости, ParentProcessUtilities.GetParentProcess, который я использовал от другого SO поста, можно найти here.

Объяснение:

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

В конце мы возвращаем код выхода, отличный от 0, что предотвращает появление исходного окна TortoiseSVN Commit с одной оговоркой. Появится диалоговое окно «Ошибка», отображающее сообщение, записанное в stderr; о котором я говорил. Одной из наиболее важных частей этого кода является проверка родительского процесса для проприетарного аргумента, прежде чем выполнять всю эту работу. Эта проверка предотвращает бесконечное количество попыток крюка, потому что, когда TortoiseProc перезаписывается вышеуказанным кодом, скрипт hook будет снова запущен и, впоследствии, снова вызовет этот код.

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

+0

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

+0

Хм, подумав об этом, моя главная проблема заключалась в диалоге «проверка изменений». Я могу попробовать изучить это решение для этой области, но похоже, что для запуска диалога потребуется какой-то пользовательский скрипт, поскольку, похоже, нет никаких перехватов для «проверки изменений». – Ben

+0

Правильно, нет способа перехватить «проверку на модификацию», как это может быть сделано с помощью «commit». Однако, если вы хотите изучить маршрут пользовательского сценария, вы можете заменить команду «/ command: commit» на «/ command: repostatus», чтобы отобразить «check for modiciations». Обе команды используют аргумент/pathfile для определения файлов для отображения. – cokeman19

Смежные вопросы