示例#1
0
 /// <summary>
 /// This handles merging the revisions in the event that a single check-in spans a window of time rather than an exact
 /// second in time.
 /// </summary>
 /// <returns></returns>
 private static bool MergeRevisions()
 {
     //Merge from the back of the list to move items forward
     //This could potentially merge everything into a single revision with a time of the
     //first revision if there are no comments and every version is within the mergedrevision_seconds of each other
     //however, a single person is not likely to be making that many changes on a regular basis
     if (revisions.Count <= 1 || MergeRevisionWindow == 0)
     {
         mergeLog.WarnFormat("Skipping revision merge because there is nothing to do");
         return(true);
     }
     mergeLog.InfoFormat("Starting to merge revisions with count of {0}", revisions.Count);
     //No point in checking the last revision with nothing
     //Start with the most recent files and move backward through the list
     //By moving the files to an earlier point in time (if within the window), we can keep moving them to an earlier
     //point in time thereby allowing more revisions to get merged as the time of the earliest revision
     for (int i = revisions.Keys.Count - 2; i >= 0; i--)
     {
         int         j   = i;
         VssRevProps key = revisions.Keys[i];
         while (++j < revisions.Keys.Count &&
                revisions.Keys[j].Time.Subtract(key.Time).TotalSeconds <= MergeRevisionWindow)
         {
             //Make sure we don't have any duplicate files before checking the author and/or comments.
             //If we have a duplicate file, we can't even proceed with merging to the past
             bool bDuplicate = false;
             //the i is "later" (older) than the j which is "newer" (more recent)
             foreach (VssFileVersion laterfile in revisions[key].Values)
             {
                 foreach (VssFileVersion newerfile in revisions[revisions.Keys[j]].Values)
                 {
                     if (string.Compare(laterfile.Spec, newerfile.Spec, true) == 0)
                     {
                         bDuplicate = true;
                         break;
                     }
                 }
                 if (bDuplicate)
                 {
                     break;
                 }
             }
             //We must stop if we have encountered a duplicate file because we cannot merge anything beyond this point
             if (bDuplicate)
             {
                 break;
             }
             //No duplicates; now make sure we have other matching properties for the revision
             if (string.Compare(key.Author, revisions.Keys[j].Author, true) == 0 &&
                 string.Compare(key.Comment, revisions.Keys[j].Comment, true) == 0)
             {
                 mergeLog.DebugFormat("Merging revision {0}\n\tinto\t{1}", revisions.Keys[j], key);
                 //Merge the more recent revisions into the older revision
                 foreach (var laterfile in revisions[revisions.Keys[j]])
                 {
                     revisions[key].Add(laterfile.Key, laterfile.Value);
                 }
                 revisions.Remove(revisions.Keys[j]);
                 break;
             }
         }
     }
     mergeLog.InfoFormat("Merge completed with a final revision count of {0}", revisions.Count);
     return(true);
 }
示例#2
0
        private static void GetAndAddRevision(VssRevProps properties, Dictionary <string, VssFileVersion> files,
                                              SvnClient svnClient)
        {
            string dir      = Path.Combine(repoDIR, vssPROJ.Substring(2).Replace("/", "\\"));
            string filePath = string.Empty;
            var    delkeys  = new List <string>();

            foreach (string key in files.Keys)
            {
                try
                {
                    //take care of the rare case of an item both file and label
                    if (!String.IsNullOrEmpty(files[key].Version.Label))
                    {
                        if (files[key].Version.VSSItem.Type != 0)
                        {
                            GetFileVersion(files[key].Version.VSSItem, files[key].Version, svnClient);
                            var commitArgs = new SvnCommitArgs {
                                LogMessage = properties.Comment
                            };
                            svnClient.Commit(dir, commitArgs);

                            filePath =
                                Path.Combine(
                                    Path.GetDirectoryName(
                                        string.Format("{0}{1}", repoDIR, files[key].Spec.Substring(1)).Replace("/", "\\")),
                                    files[key].Version.VSSItem.Name);

                            var uri = new Uri(string.Format("{0}{1}", svnURL, svnPROJ));
                            //svnClient.GetInfo(SvnTarget.FromString(filePath), out infoEventArgs);
                            CounterfeitRevProps(svnClient, SvnTarget.FromUri(uri), files[key].Version);
                        }

                        TagSourceUrl = String.Empty;
                        var tag = new Tag
                        {
                            fromUrlString = GenerateSourceUrl(files[key].Version.VSSItem),
                            tagString     = String.Format("{0}/{1}/{2}_{3}",
                                                          svnURL,
                                                          svnTAG,
                                                          files[key].Version.VSSItem.Name,
                                                          sanitizeLabel(files[key].Version.Label)),
                            label = files[key].Version.Label
                        };
                        ApplyTag(files[key].Version.VSSItem, svnClient, files[key].Version, tag);

                        return;
                    } //rare case end

                    GetFileVersion(files[key].Version.VSSItem, files[key].Version, svnClient);
                    //Only need one file to get the revision information from
                    if (string.IsNullOrEmpty(filePath))
                    {
                        filePath =
                            Path.Combine(
                                Path.GetDirectoryName(
                                    string.Format("{0}{1}", repoDIR, files[key].Spec.Substring(1)).Replace("/", "\\")),
                                files[key].Version.VSSItem.Name);
                    }

                    if (files[key].Deleted)
                    {
                        delkeys.Add(filePath);
                    }
                }
                catch (COMException ex)
                {
                    switch ((uint)ex.ErrorCode)
                    {
                    case 0x8004D838:     //version is corrupted and unavailable
                        migrateLog.WarnFormat("Skipping version due to corruption in file {1}:{0}",
                                              files[key].VersionNumber, files[key].Spec);
                        continue;

                    default:
                        if (IgnoreExceptions)
                        {
                            migrateLog.ErrorFormat("Error processing file {1}:{0}",
                                                   files[key].VersionNumber, files[key].Spec);
                            migrateLog.ErrorFormat(ex.ToString());
                            continue;
                        }
                        throw;
                    }
                }
            }
            //Only commit if we actually have a file that has been updated as a result of the get
            if (!string.IsNullOrEmpty(filePath))
            {
                var commitArgs = new SvnCommitArgs {
                    LogMessage = properties.Comment
                };
                migrateLog.DebugFormat("Committing revision ...");
                //SLOW!!!, change to ICollection of FilePaths (only verify updated files!)
                svnClient.Commit(dir, commitArgs);

                //delete files which are marked as deleted in vss
                foreach (string delFilePath in delkeys)
                {
                    svnClient.Delete(delFilePath);
                    migrateLog.Info(String.Format("Deleted: {0}", delFilePath));
                }
                delkeys.Clear();

                SvnInfoEventArgs infoEventArgs;
                //Use one of the committed files to determine the revision we just committed
                var uri = new Uri(string.Format("{0}{1}", svnURL, svnPROJ));
                //svnClient.GetInfo(SvnTarget.FromString(filePath), out infoEventArgs);
                svnClient.GetInfo(SvnTarget.FromUri(uri), out infoEventArgs);

                svnClient.SetRevisionProperty(new Uri(svnURL), infoEventArgs.Revision,
                                              SvnPropertyNames.SvnAuthor,
                                              properties.Author);

                string   strCfgTime;
                string[] strSplit, strSplit2;

                strSplit  = properties.Time.ToString().Split(' ');
                strSplit2 = strSplit[0].Split('/');

                strCfgTime = strSplit2[2] + '-' + strSplit2[1] + '-' + strSplit2[0] + 'T' + strSplit[1] + ".000000Z";

                svnClient.SetRevisionProperty(new Uri(svnURL), infoEventArgs.Revision,
                                              SvnPropertyNames.SvnDate,
                                              strCfgTime);
            }
        }
示例#3
0
        private static void AddRevision(IVSSVersion version, bool deleted)
        {
            var key = new VssRevProps
            {
                Author  = version.Username,
                Comment = version.Comment.Replace("\n", "").Replace("\t", "").Trim(),
                Time    = version.Date
            };
            var file = new VssFileVersion
            {
                Spec          = version.VSSItem.Spec,
                VersionNumber = version.VersionNumber,
                Version       = version,
                Action        = version.Action,
                Deleted       = deleted
            };

            //Ignore branches and the root directory
            if (version.Action.Contains("Branched at version") ||
                version.Action.ToLower().Contains("verzweigt bei version") ||
                string.Compare("$/", file.Spec, true) == 0)
            {
                return;
            }

            //if pinned add to a special (and always last) revision
            if (version.VSSItem.IsPinned)
            {
                if (!revisions.ContainsKey(pinProps))  //if there is no pinprop revision, add one ...
                {
                    revisions.Add(pinProps, new Dictionary <string, VssFileVersion>(StringComparer.CurrentCultureIgnoreCase)
                    {
                        { file.Spec, file }
                    });
                }
                else //else add file to pinprop revision
                {
                    revisions[pinProps].Add(file.Spec, file);
                }
            }


            //filter duplicate labels
            if (!string.IsNullOrEmpty(version.Label))
            {
                if (labellist.Contains(version.VSSItem.Spec))
                {
                    if (tagslist.Contains(version.Label))
                    {
                        return;
                    }
                    tagslist.Add(version.Label);
                }
                else
                {
                    labellist.Add(version.VSSItem.Spec);
                    tagslist.Add(version.Label);
                }
            }

            //if revision is the same but file was not added yet, then ...
            if (revisions.Keys.Contains(key) && (!revisions[key].ContainsKey(file.Spec)))// || version.VSSItem.Type == (int) VSSItemType.VSSITEM_PROJECT))
            {
                //Add the file to the existing revision if it exists
                searchLog.DebugFormat("Adding {0}:{1} to {2}", file.Spec, file.VersionNumber, key);
                revisions[key].Add(file.Spec, file);
                return;
            }

            if (revisions.Keys.Contains(key) && (revisions[key].ContainsKey(file.Spec)))
            {
                return;
            }

            //else revision has not been added yet, so ...
            var files = new Dictionary <string, VssFileVersion>(StringComparer.CurrentCultureIgnoreCase)
            {
                { file.Spec, file }
            };

            searchLog.DebugFormat("New revision {0} {1}:{2}", key, file.Spec, file.VersionNumber);
            revisions.Add(key, files);
            return;
        }