Bobson
Bobson

Reputation: 13696

Getting "mergable revisions" with SharpSvn

When setting up a merge, the TortoiseSvn client has a wonderful checkbox labeled "Hide non-mergable revisions". I'm looking to reproduce the list of revisions that shows up when it's enabled using SharpSvn.

TortoiseSvn

The TortoiseSvn documentation explains this checkbox:

When merge tracking is used, the log dialog will show previously merged revisions, and revisions pre-dating the common ancestor point, i.e. before the branch was copied, as greyed out. The Hide non-mergeable revisions checkbox allows you to filter out these revisions completely so you see only the revisions which can be merged.

How can I reproduce this functionality in SharpSvn code? I need a list of SvnLogEventArgs (or similar) that are candidates for merging.

Current status: I've only gotten as far as pulling the logs for both branches. I can't figure out how to get the appropriate svn:mergeinfo attribute or what to do with it once I get it.

Upvotes: 2

Views: 376

Answers (2)

Zéiksz
Zéiksz

Reputation: 696

Try SvnClient.ListMergesEligible: http://sharpsvn.qqn.nl/current/html/M_SharpSvn_SvnClient_ListMergesEligible_1.htm

Edit. SharpSVN seems bugged for me, so I went for cmd.

Check this out:

    private static void mergelhetőVerziókListája()
    {
      string revíziók = cmd("svn", "mergeinfo --show-revs eligible \".../branches/dev\" \".../trunk\"");
    }

    private static string cmd(string utasítás, string paraméter)
    {
      StringBuilder eredmény = new StringBuilder();
      Process cmd = new Process()
      {
        StartInfo = new ProcessStartInfo
        {
          FileName = utasítás,
          Arguments = paraméter,
          UseShellExecute = false,
          RedirectStandardOutput = true,
          CreateNoWindow = true
        }
      };
      cmd.Start();
      while (!cmd.StandardOutput.EndOfStream)
      {
        string kimenet = cmd.StandardOutput.ReadLine();
        eredmény.AppendLine(kimenet); //...
      }
      return eredmény.ToString();
    }

Upvotes: 0

Bobson
Bobson

Reputation: 13696

I kept plugging away, and following links, and here's what I ended up with:

using (var client = new SvnClient())
{
    var release = SvnTarget.FromUri(new Uri(@"https://******/branches/Release"));
    var trunk = SvnTarget.FromUri(new Uri(@"https://******/trunk"));

    string trunkMergeinfo, releaseMergeinfo;
    client.GetProperty(release, "svn:mergeinfo", out releaseMergeinfo);
    client.GetProperty(trunk, "svn:mergeinfo", out trunkMergeinfo);
    var relInfos = releaseMergeinfo.Split("\n");
    var trunkInfos = trunkMergeinfo.Split("\n");

    // This is here because I don't know what will happen once I merge something into trunk.
    Debug.Assert(relInfos.Except(trunkInfos).Count() == 1,"Too many unknown merge paths");

    var trunklist = relInfos.SingleOrDefault(i => i.StartsWith("/trunk:"));
    var revisions = trunklist.Replace("/trunk:", "").Split(",").SelectMany(t =>
    {
        // If the log contains a range, break it out to it's specific revisions.
        if (t.Contains("-"))
        {
            var match = Regex.Match(t, @"(\d+)-(\d+)");
            var start = int.Parse(match.Groups[1].Value);
            var end = int.Parse(match.Groups[2].Value);
            return Enumerable.Range(start, end - start + 1).ToArray();
        }
        else
            return new[] { int.Parse(t) };
    }).Select(x => (long)x);

    Collection<SvnLogEventArgs> baseRevs;
    // Why can't this take "trunk" or a property thereof as an argument?
    client.GetLog(new Uri(@"https://******/trunk"), new SvnLogArgs { Start = 1725, End = SvnRevisionType.Head }, out baseRevs);
    baseRevs.Reverse().Where(r => !revisions.Contains(r.Revision) ).Select(x => x.LogMessage).Dump();
}

Hopefully, this helps someone else, although I'll note that it does not have a lot of the sanity checking that I'd put in production code - this is the quick-and-dirty version.

Upvotes: 2

Related Questions