Ejemplo n.º 1
0
        private static void ProcessProjectFiles(
      CurrentOperation operation,
      string[] conflictPaths,
      DirectoryInfo folder,
      Logger logger,
      string rootFolder )
        {
            var merger = new ProjectMerger(
            operation,
            new UserConflictResolver<ProjectReference>( operation, repositoryRootDirectory: rootFolder ),
            new ReferenceConflictResolver( new UserConflictResolver<Reference>( operation, notResolveOptionText: PackageNotInstalledText, repositoryRootDirectory: rootFolder ) ),
            new UserConflictResolver<RawItem>( operation, repositoryRootDirectory: rootFolder ),
            new UserDuplicateResolver<Reference>( operation, notResolveOptionText: PackageNotInstalledText, repositoryRootDirectory: rootFolder ) );

              foreach ( var conflict in conflictPaths.Where( p => p.EndsWith( ".csproj" ) || p.EndsWith( ".fsproj" ) || p.EndsWith( ".xproj" )) ) {

            var fullConflictPath = Path.Combine( folder.FullName, conflict );
            logger.Info( $"{LogHelper.Header}{Environment.NewLine}Examining concurrent modification for {fullConflictPath}" );

            var baseContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Ancestor, conflict );
            var localContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Ours, conflict );
            var incomingContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Theirs, conflict );

            var conflictFolder = Path.GetDirectoryName( Path.Combine( rootFolder, conflict ) );

            if ( conflictFolder == null ) {
              throw new Exception( "No conflict folder" );
            }

            if ( string.IsNullOrEmpty( localContent ) || string.IsNullOrEmpty( incomingContent ) ) {
              logger.Log( LogLevel.Info, $"Skipping '{conflict}' - no content on one side" );
              continue;
            }

            var localDocument = XDocument.Parse( localContent );
            var incomingDocument = XDocument.Parse( incomingContent );
            var baseDocument = XDocument.Parse( baseContent ?? "<?xml version=\"1.0\" encoding=\"utf - 8\"?><Project/>" );

            var resolved = false;

            try {
              var projectFolder = Path.Combine( folder.FullName, conflictFolder );

              var packagesConfigFilePath = ProjectPackages.GetPackagesConfigFilePath( projectFolder );
              var packagesConfig = ProjectPackages.TryLoadPackagesConfig( packagesConfigFilePath );
              if ( packagesConfig == null ) {
            continue;
              }

              var packageIndex = new ProjectPackages( projectFolder, NuGetExtensions.FindRelativePathOfPackagesFolder( projectFolder ), packagesConfig );

              Item[] items = merger.Merge(
              conflict,
              packageIndex,
              baseDocument,
              localDocument,
              incomingDocument ).ToArray();

              // Now remove everything we have handled, to check if we are done.
              ProjectFile.DeleteItems( localDocument );
              ProjectFile.DeleteItems( incomingDocument );
              ProjectFile.DeleteItems( baseDocument );

              ProjectFile.AddItems( baseDocument, items );
              ProjectFile.AddItems( localDocument, items );
              ProjectFile.AddItems( incomingDocument, items );

              XDocument resolvedDocument = null;

              var localXml = localDocument.ToString();
              var incomingXml = incomingDocument.ToString();
              var baseXml = baseDocument.ToString();

              // Check for any project file changes outside of the references and items.
              if ( localXml == incomingXml ) {
            resolvedDocument = localDocument;
              } else if ( baseXml == localXml ) {
            resolvedDocument = incomingDocument;
              } else if ( baseXml == incomingXml ) {
            resolvedDocument = localDocument;
              }

              if ( resolvedDocument != null ) {
            // We handled all the differences
            using ( var textWriter = new StreamWriter( fullConflictPath ) ) {
              SerialisationHelper.WriteXml( resolvedDocument, textWriter );
            }
            using ( var repository = new Repository( rootFolder ) ) {
              repository.Stage( conflict );
            }

            resolved = true;
              }
            }       catch ( MergeAbortException ) {
              logger.Log( LogLevel.Info, $"Project merge aborted for {conflict}" );
              continue;
            } catch ( UserQuitException ) {
              throw;
            } catch ( Exception exception ) {
              logger.Log( LogLevel.Error, exception, $"Project merge failed for {conflict}{Environment.NewLine}{exception}" );
            }

            if ( resolved ) {
              continue;
            }

              string userQuestionText = $"Could not resolve conflict: {conflict}{Environment.NewLine}Would you like to resolve the conflict with the mergetool?";
              var userQuestion = new UserQuestion<bool>( userQuestionText, UserQuestion<bool>.YesNoOptions() );

              if ( userQuestion.Resolve() ) {

            using ( var repository = new Repository( rootFolder ) ) {
              GitHelper.ResolveWithStandardMergetool(
                repository,
                fullConflictPath,
                baseDocument,
                localDocument,
                incomingDocument,
                logger,
                conflict );
            }
              }
            }
        }
Ejemplo n.º 2
0
        private static void ProcessPackagesConfig(
      CurrentOperation operation,
      string[] conflictPaths,
      DirectoryInfo folder,
      Logger logger,
      string rootFolder )
        {
            var packagesConfigMerger = new PackagesConfigMerger(
            operation,
            new UserConflictResolver<ConfigitPackageReference>( operation, repositoryRootDirectory: rootFolder ) );

              foreach ( var conflict in conflictPaths.Where( p => Path.GetFileName( p ) == "packages.config" ) ) {

            var fullConflictPath = Path.Combine( folder.FullName, conflict );
            logger.Info( $"{LogHelper.Header}{Environment.NewLine}Examining concurrent modification for {fullConflictPath}" );

            var baseContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Ancestor, conflict );
            var localContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Ours, conflict );
            var incomingContent = GitHelper.GetConflictContent( rootFolder, StageLevel.Theirs, conflict );

            // TODO: Is this correct? if base is not null then we have a deletion of the packages config file
            if ( string.IsNullOrEmpty( localContent ) || string.IsNullOrEmpty( incomingContent ) ) {
              logger.Log( LogLevel.Info, $"Skipping '{conflict}' - no content on one side" );
              continue;
            }

            bool resolved = false;

            try {
              var result = packagesConfigMerger.Merge( conflict,
              baseContent == null ? new ConfigitPackageReference[0]:
                                   NuGetExtensions.ReadPackageReferences( baseContent ),
              NuGetExtensions.ReadPackageReferences( localContent ),
              NuGetExtensions.ReadPackageReferences( incomingContent ) ).ToArray();

              result.Write( fullConflictPath );

              using ( var repository = new Repository( rootFolder ) ) {
            repository.Stage( conflict );
            resolved = true;
              }

            } catch ( MergeAbortException ) {
              logger.Log( LogLevel.Info, $"Package merge aborted for {conflict}" );
              continue;
            }
            catch ( UserQuitException ) {
              throw;
            } catch ( Exception exception ) {
              logger.Log( LogLevel.Error, exception, $"Package merge failed for {conflict}{Environment.NewLine}{exception}" );
            }

            if ( resolved ) {
              continue;
            }

              string userQuestionText = $"Could not resolve conflict: {conflict}{Environment.NewLine}Would you like to resolve the conflict with the mergetool?";
              var userQuestion = new UserQuestion<bool>( userQuestionText, UserQuestion<bool>.YesNoOptions() );

            if ( !userQuestion.Resolve() ) {
              continue;
            }

            XDocument localDocument = XDocument.Parse( localContent );
            XDocument theirDocument = XDocument.Parse( incomingContent );
            XDocument baseDocument = baseContent == null ? new XDocument() : XDocument.Parse( baseContent );

            using ( var repository = new Repository( rootFolder ) ) {
              GitHelper.ResolveWithStandardMergetool(
                repository,
                fullConflictPath,
                baseDocument,
                localDocument,
                theirDocument,
                logger,
                conflict );
            }
              }
        }