Пример #1
0
        internal CherryPickProcessor(ObjectRepositoryCherryPick objectRepositoryCherryPick,
                                     ComputeTreeChangesFactory computeTreeChangesFactory, ObjectRepositorySerializerFactory serializerFactory)
        {
            if (serializerFactory == null)
            {
                throw new ArgumentNullException(nameof(serializerFactory));
            }

            _cherryPick = objectRepositoryCherryPick ?? throw new ArgumentNullException(nameof(objectRepositoryCherryPick));

            _computeTreeChangesFactory = computeTreeChangesFactory ?? throw new ArgumentNullException(nameof(computeTreeChangesFactory));
            _serializer = serializerFactory(new ModelObjectSerializationContext(objectRepositoryCherryPick.Repository.Container));
        }
Пример #2
0
        internal RebaseProcessor(ObjectRepositoryRebase objectRepositoryRebase,
                                 ComputeTreeChangesFactory computeTreeChangesFactory, ObjectRepositorySerializerFactory serializerFactory)
        {
            if (serializerFactory == null)
            {
                throw new ArgumentNullException(nameof(serializerFactory));
            }

            _rebase = objectRepositoryRebase ?? throw new ArgumentNullException(nameof(objectRepositoryRebase));

            _computeTreeChangesFactory = computeTreeChangesFactory ?? throw new ArgumentNullException(nameof(computeTreeChangesFactory));
            _serializer = serializerFactory(new ModelObjectSerializationContext(objectRepositoryRebase.Repository.Container));
        }
Пример #3
0
        internal static ObjectRepositoryDelete ComputeChanges_Deleted(IObjectRepositorySerializer serializer, IRepository repository, PatchEntryChanges change, Func <string, string> relativeFileDataResolver, Func <string, IList <TreeEntryChanges> > deletionConflictProvider = null)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (System.IO.Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return(null);
            }

            var conflicts = deletionConflictProvider?.Invoke(change.Path);

            if (conflicts?.Any() ?? false)
            {
                throw new NotImplementedException("Node deletion while children have been added or modified in head is not supported.");
            }

            var mergeBaseObject = serializer.Deserialize(repository.Lookup <Blob>(change.OldOid).GetContentStream(), relativeFileDataResolver);

            return(new ObjectRepositoryDelete(change.Path, mergeBaseObject.Id));
        }
Пример #4
0
 private static IEnumerable <IMigration> GetCommitMigrations(IRepository repository, Commit previousCommit, Commit commit, IObjectRepositorySerializer serializer)
 {
     using (var changes = repository.Diff.Compare <TreeChanges>(previousCommit.Tree, commit.Tree))
     {
         foreach (var change in changes.Where(c => c.Path.StartsWith(FileSystemStorage.MigrationFolder, StringComparison.OrdinalIgnoreCase) && (c.Status == ChangeKind.Added || c.Status == ChangeKind.Modified)))
         {
             var blob = (Blob)commit[change.Path].Target;
             yield return((IMigration)serializer.Deserialize(blob.GetContentStream(),
                                                             relativePath => (commit[change.Path.GetSiblingFile(relativePath)]?.Target as Blob)?.GetContentText() ?? string.Empty));
         }
     }
 }
Пример #5
0
        internal static void UpdateTreeDefinition(this IRepository repository, ObjectRepositoryChangeCollection changes, TreeDefinition definition, IObjectRepositorySerializer serializer, Commit oldCommit = null)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (definition == null)
            {
                throw new ArgumentNullException(nameof(definition));
            }

            UpdateChangeTreeDefinitions(repository, changes.Modified, definition, serializer);
            UpdateChangeTreeDefinitions(repository, changes.Added, definition, serializer);
            UpdateDeletionTreeDefinitions(changes.Deleted, definition, oldCommit);
            UpdateIndexTreeDefinitions(repository, changes, definition, serializer);
        }
Пример #6
0
        internal static Commit CommitChanges(this IRepository repository, ObjectRepositoryChangeCollection changes, IObjectRepositorySerializer serializer, string message, Signature author, Signature committer, GitHooks hooks, CommitOptions options = null, Commit mergeParent = null)
        {
            TreeDefinition definition;
            Commit         startCommit;

            if (changes.OldRepository?.CommitId != null)
            {
                if (repository.Head.Tip.Id != changes.OldRepository.CommitId)
                {
                    throw new GitObjectDbException("Changes are not based on the HEAD commit.");
                }
                startCommit = repository.Lookup <Commit>(changes.OldRepository.CommitId);
                definition  = TreeDefinition.From(startCommit);
            }
            else if (repository.Info.IsHeadUnborn)
            {
                startCommit = null;
                definition  = new TreeDefinition();
            }
            else
            {
                throw new GitObjectDbException("Changes are not based on the HEAD commit.");
            }

            if (!hooks.OnCommitStarted(changes, message))
            {
                return(null);
            }

            repository.UpdateTreeDefinition(changes, definition, serializer, startCommit);

            var result = Commit(repository, definition, message, author, committer, options, mergeParent);

            hooks.OnCommitCompleted(changes, message, result.Id);

            return(result);
        }
Пример #7
0
        private static bool UpdateAndSerializerIndex(IObjectRepositoryIndex index, ObjectRepositoryChangeCollection changes, IObjectRepositorySerializer serializer, StringBuilder buffer, bool fullScan)
        {
            buffer.Clear();
            var binding      = index.DataAccessor.ConstructorParameterBinding;
            var updatedIndex = fullScan ? index.FullScan() : index.Update(changes);

            if (updatedIndex == null)
            {
                return(false);
            }

            var cloned = (IObjectRepositoryIndex)binding.Cloner(index,
                                                                (instance, propertyName, type, fallback) =>
                                                                propertyName == nameof(IObjectRepositoryIndex.Values) ? updatedIndex : fallback,
                                                                (childProperty, children, @new, dataAccessor) =>
                                                                throw new NotSupportedException("Index should not contain child properties."));

            serializer.Serialize(cloned, buffer);
            return(true);
        }
Пример #8
0
        private static void UpdateIndexTreeDefinitions(IRepository repository, ObjectRepositoryChangeCollection changes, TreeDefinition definition, IObjectRepositorySerializer serializer)
        {
            var buffer = new StringBuilder();

            foreach (var index in changes.NewRepository.Indexes)
            {
                var fullScan = changes.Added.Any(c => c.New.Id == index.Id);
                if (UpdateAndSerializerIndex(index, changes, serializer, buffer, fullScan))
                {
                    definition.Add(index.GetDataPath(), repository.CreateBlob(buffer), Mode.NonExecutableFile);
                }
            }
        }
Пример #9
0
        private static void UpdateChangeTreeDefinitions(IRepository repository, IEnumerable <ObjectRepositoryEntryChanges> changes, TreeDefinition definition, IObjectRepositorySerializer serializer)
        {
            var buffer = new StringBuilder();

            foreach (var change in changes)
            {
                if (change.New is IObjectRepositoryIndex index)
                {
                    // Index are managed separately
                    continue;
                }
                buffer.Clear();
                var nested = serializer.Serialize(change.New, buffer);
                definition.Add(change.Path, repository.CreateBlob(buffer), Mode.NonExecutableFile);
                foreach (var info in nested)
                {
                    var nestedPath = change.New.GetDataPath(info.FileName);
                    definition.Add(nestedPath, repository.CreateBlob(info.Data), Mode.NonExecutableFile);
                }
            }
        }
Пример #10
0
        internal static ObjectRepositoryAdd ComputeChanges_Added(IObjectRepository objectRepository, IObjectRepositorySerializer serializer, IRepository repository, PatchEntryChanges change, Func <string, string> relativeFileDataResolver)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (System.IO.Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return(null);
            }

            if (objectRepository.TryGetFromGitPath(change.Path) != null)
            {
                throw new NotImplementedException("Node already present in current state.");
            }
            var parentDataPath = change.Path.GetDataParentDataPath();

            if (objectRepository.TryGetFromGitPath(parentDataPath) == null)
            {
                throw new NotImplementedException("Node addition while parent has been deleted in head is not supported.");
            }

            var @new     = serializer.Deserialize(repository.Lookup <Blob>(change.Oid).GetContentStream(), relativeFileDataResolver);
            var parentId = change.Path.GetDataParentId(objectRepository);

            return(new ObjectRepositoryAdd(change.Path, @new, parentId));
        }
Пример #11
0
        internal static IEnumerable <ObjectRepositoryPropertyChange> ComputeChanges_Modified(IObjectRepository objectRepository, IObjectRepositorySerializer serializer, PatchEntryChanges change, Func <string, Blob> relativeFileDataResolverStart, Func <string, Blob> relativeFileDataResolverEnd)
        {
            // Get data file path, in the case where a blob has changed
            var dataPath = change.Path.GetSiblingFile(FileSystemStorage.DataFile);

            var currentObject = objectRepository.TryGetFromGitPath(dataPath) ??
                                throw new NotImplementedException($"Conflict as a modified node {change.Path} has been deleted in current rebase state.");

            var changeStart = serializer.Deserialize(
                relativeFileDataResolverStart(FileSystemStorage.DataFile)?.GetContentStream() ?? throw new GitObjectDbException("Change start content could not be found."),
                relativePath => relativeFileDataResolverStart(relativePath)?.GetContentText() ?? string.Empty);

            var changeEnd = serializer.Deserialize(
                relativeFileDataResolverEnd(FileSystemStorage.DataFile)?.GetContentStream() ?? throw new GitObjectDbException("Change end content could not be found."),
                relativePath => relativeFileDataResolverEnd(relativePath)?.GetContentText() ?? string.Empty);

            var changes = ObjectRepositoryMerge.ComputeModifiedProperties(change, changeStart, changeEnd, currentObject);

            // Indexes will be recomputed anyways from the changes when committed,
            // so there is no need to track them in the modified chunks
            var changesWithoutIndexes = changes.Where(
                modifiedProperty => !typeof(IObjectRepositoryIndex).IsAssignableFrom(modifiedProperty.Property.Property.ReflectedType));

            return(changesWithoutIndexes);
        }