Как использовать SharpSVN для изменения файла XML и фиксации измененного файла

Я новичок в SharpSVN.

В настоящее время мы заняты ребрендингом, и это влечет за собой обновление всех наших отчетов новыми цветами и т. Д. Слишком много отчетов нужно делать вручную, поэтому я пытаюсь найти способ найти и заменить цвета / шрифты и т. Д. За один раз. Наши отчеты сериализуются и хранятся в базе данных, которую легко заменить, но мы также хотим применить изменения в отчетах.rdl в нашем контроле исходного кода, который является Subversion.

Мой вопрос заключается в следующем: я знаю, что вы можете записывать файлы в поток с SharpSVN, что я и сделал, теперь я бы хотел перенести обновленный XML обратно в Subversion в качестве последней версии. Это вообще возможно? И если так, как бы я поступил так? Я много гуглил, но не смог найти однозначного ответа на это.

Мой код до сих пор (имейте в виду, что это разовая вещь, поэтому я не слишком обеспокоен чистым кодом и т. Д.):

    private void ReplaceFiles()
    {
        SvnCommitArgs args = new SvnCommitArgs(); 
        SvnCommitResult result;
        args.LogMessage = "Rebranding - Replace fonts, colours, and font sizes";

        using (SvnClient client = new SvnClient())
        {
            client.Authentication.DefaultCredentials = new NetworkCredential("mkassa", "Welcome1");
            client.CheckOut(SvnUriTarget.FromString(txtSubversionDirectory.Text), txtCheckoutDirectory.Text);
            client.Update(txtCheckoutDirectory.Text);
            SvnUpdateResult upResult;
            client.Update(txtCheckoutDirectory.Text, out upResult);
            ProcessDirectory(txtCheckoutDirectory.Text, args, client);
        }
        MessageBox.Show("Done");
    }

    // Process all files in the directory passed in, recurse on any directories  
    // that are found, and process the files they contain. 
    public void ProcessDirectory(string targetDirectory, SvnCommitArgs args, SvnClient client)
    {
        var ext = new List<string> { ".rdl" };

        // Process the list of files found in the directory. 
        IEnumerable<string> fileEntries = Directory.EnumerateFiles(targetDirectory, "*.*", SearchOption.AllDirectories)
                                        .Where(s => ext.Any(e=> s.EndsWith(e)));
        foreach (string fileName in fileEntries)
            ProcessFile(fileName, args, client);
    }


    private void ProcessFile(string fileName, SvnCommitArgs args, SvnClient client)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            SvnCommitResult result;
            if (client.Write(SvnTarget.FromString(fileName), stream))
            {
                stream.Position = 0;
                using (var reader = new StreamReader(stream))
                {
                    string contents = reader.ReadToEnd();

                    DoReplacement(contents);

                    client.Commit(txtCheckoutDirectory.Text, args, out result);

                    //if (result != null)
                    //    MessageBox.Show(result.PostCommitError);
                }
            }
        }
    }

Спасибо всем, кто может дать некоторое представление об этом!

2 ответа

Решение

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

Если вы не можете просто извлечь все дерево и заменить на него + коммит, вы можете использовать что-то на основе:

string tmpDir = "C:\tmp\mytmp";
using(SvnClient svn = new SvnClient())
{
     List<Uri> toProcess = new List<Uri>();
     svn.List(new Uri("http://my-repos/trunk"), new SvnListArgs() { Depth=Infinity }),
     delegate(object sender, SvnListEventArgs e)
     {
         if (e.Path.EndsWith(".rdl", StringComparison.OrdinalIgnoreCase))
             toProcess.Add(e.Uri);
     });

     foreach(Uri i in toProcess)
     {
         Console.WriteLine("Processing {0}", i);
         Directory.Delete(tmpDir, true);

         // Create a sparse checkout with just one file (see svnbook.org)
         string name = SvnTools.GetFileName(i);
         string fileName = Path.Join(tmpDir, name)
         svn.CheckOut(new Uri(toProcess, "./"), new SvnCheckOutArgs { Depth=Empty });
         svn.Update(fileName);

         ProcessFile(fileName); // Read file and save in same location

         // Note that the following commit is a no-op if the file wasn't
         // changed, so you don't have to check for that yourself
         svn.Commit(fileName, new SvnCommitArgs { LogMessage="Processed" });
    }
}

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

Мне удалось это сделать. Размещение ответа для дальнейшего использования.

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

                    string contents = reader.ReadToEnd();

                    contents = DoReplacement(contents);

                    // Create an XML document
                    XmlDocument doc = new XmlDocument();
                    string xmlData = contents;
                    doc.Load(new StringReader(xmlData));
                    //Save XML document to file
                    doc.Save(fileName);

                    client.Commit(txtCheckoutDirectory.Text, args, out result);

Надеюсь, это поможет всем, кто хочет сделать то же самое.

Другие вопросы по тегам