/// <inheritdoc />
        public ObjectId SaveInNewRepository(Signature signature, string message, RepositoryDescription repositoryDescription, bool isBare = false)
        {
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (repositoryDescription == null)
            {
                throw new ArgumentNullException(nameof(repositoryDescription));
            }

            LibGit2Sharp.Repository.Init(repositoryDescription.Path, isBare);

            return(_repositoryProvider.Execute(repositoryDescription, repository =>
            {
                var all = this.Flatten().Select(o => new MetadataTreeEntryChanges(o.GetDataPath(), ChangeKind.Added, @new: o));
                var changes = new MetadataTreeChanges(this, all.ToImmutableList());
                var result = repository.CommitChanges(changes, message, signature, signature, hooks: _hooks);

                if (result != null)
                {
                    SetRepositoryData(repositoryDescription, result.Id);
                }

                return result?.Id;
            }));
        }
Пример #2
0
        /// <summary>
        /// Scaffolds a code based migration to apply any pending model changes to the database.
        /// </summary>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <param name="mode">The mode.</param>
        /// <returns>The <see cref="Migrator"/> used to apply migrations.</returns>
        public IImmutableList <Migrator> Scaffold(ObjectId start, ObjectId end, MigrationMode mode)
        {
            if (mode == MigrationMode.Downgrade)
            {
                throw new NotImplementedException(MigrationMode.Downgrade.ToString());
            }

            return(_repositoryProvider.Execute(_repositoryDescription, repository =>
            {
                var log = repository.Commits.QueryBy(new CommitFilter
                {
                    SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Reverse,
                    ExcludeReachableFrom = start,
                    IncludeReachableFrom = end
                });
                var deferred = new List <IMigration>();
                var result = ImmutableList.CreateBuilder <Migrator>();
                result.AddRange(GetLogMigrators(repository, log, deferred, repository.Lookup <Commit>(start), mode));
                if (deferred.Any())
                {
                    var uniqueDeferredMigrations = deferred.Distinct(MetadataObjectIdComparer <IMigration> .Instance);
                    if (result.Any())
                    {
                        var toUpdate = result[result.Count - 1];
                        var newValue = new Migrator(toUpdate.Migrations.Concat(deferred).ToImmutableList(), mode, toUpdate.CommitId);
                        result[result.Count - 1] = newValue;
                    }
                    else
                    {
                        result.Add(new Migrator(uniqueDeferredMigrations.ToImmutableList(), mode, end));
                    }
                }
                return result.ToImmutable();
            }));
        }
Пример #3
0
        /// <inheritdoc/>
        public ObjectRepositoryChangeCollection Compare(ObjectId oldCommitId, ObjectId newCommitId)
        {
            if (oldCommitId == null)
            {
                throw new ArgumentNullException(nameof(oldCommitId));
            }
            if (newCommitId == null)
            {
                throw new ArgumentNullException(nameof(newCommitId));
            }

            return(_repositoryProvider.Execute(_repositoryDescription, repository =>
            {
                var oldRepository = _objectRepositoryLoader.LoadFrom(_container, _repositoryDescription, oldCommitId);
                var newRepository = _objectRepositoryLoader.LoadFrom(_container, _repositoryDescription, newCommitId);

                var oldCommit = repository.Lookup <Commit>(oldCommitId);
                var newCommit = repository.Lookup <Commit>(newCommitId);
                using (var changes = repository.Diff.Compare <TreeChanges>(oldCommit.Tree, newCommit.Tree))
                {
                    ThrowIfNonSupportedChangeTypes(changes);

                    var modified = CollectModifiedNodes(oldRepository, newRepository, changes, oldCommit);
                    var added = CollectAddedNodes(newRepository, changes, newCommit);
                    var deleted = CollectDeletedNodes(oldRepository, changes, oldCommit);

                    _logger.ChangesComputed(modified.Count, added.Count, deleted.Count, oldCommitId, newCommitId);

                    return new ObjectRepositoryChangeCollection(newRepository, added.Concat(modified).Concat(deleted).ToImmutableList(), oldRepository);
                }
            }));
        }
Пример #4
0
        /// <inheritdoc />
        public TRepository AddRepository(TRepository repository, Signature signature, string message, Func <OdbBackend> backend = null, bool isBare = false)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            using (_logger.BeginScope("Adding repository '{Repository}'.", repository.Id))
            {
                var repositoryDescription = new RepositoryDescription(System.IO.Path.Combine(Path, repository.Id.ToString()), backend);
                EnsureNewRepository(repository, repositoryDescription);
                LibGit2Sharp.Repository.Init(repositoryDescription.Path, isBare);

                return(_repositoryProvider.Execute(repositoryDescription, r =>
                {
                    var all = repository.Flatten().Select(o => new ObjectRepositoryEntryChanges(o.GetDataPath(), ChangeKind.Added, @new: o));
                    var changes = new ObjectRepositoryChangeCollection(repository, all.ToImmutableList());
                    var commit = r.CommitChanges(changes, _serializerFactory(), message, signature, signature, _hooks);
                    if (commit == null)
                    {
                        return null;
                    }
                    return ReloadRepository(repositoryDescription, commit.Id);
                }));
            }
        }
Пример #5
0
        /// <inheritdoc />
        public AbstractObjectRepository LoadFrom(RepositoryDescription repositoryDescription, ObjectId commitId = null)
        {
            if (repositoryDescription == null)
            {
                throw new ArgumentNullException(nameof(repositoryDescription));
            }

            return(_repositoryProvider.Execute(repositoryDescription, repository =>
            {
                Commit currentCommit;
                if (commitId == null)
                {
                    currentCommit = repository.Head.Tip;
                    commitId = currentCommit.Id;
                }
                else
                {
                    currentCommit = repository.Lookup <Commit>(commitId);
                }

                var instance = (AbstractObjectRepository)LoadEntry(commitId, currentCommit[FileSystemStorage.DataFile], string.Empty);
                instance.SetRepositoryData(repositoryDescription, commitId);
                return instance;
            }));
        }
        /// <inheritdoc />
        public IObjectRepository Clone(IObjectRepositoryContainer container, string repository, RepositoryDescription repositoryDescription, ObjectId commitId = null)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }
            if (repositoryDescription == null)
            {
                throw new ArgumentNullException(nameof(repositoryDescription));
            }

            Repository.Init(repositoryDescription.Path);
            return(_repositoryProvider.Execute(repositoryDescription, r =>
            {
                Clone(repository, r, commitId);
                return LoadFrom(container, repositoryDescription, r, commitId);
            }));
        }
Пример #7
0
        void Initialize()
        {
            _repositoryProvider.Execute(_repositoryDescription, repository =>
            {
                EnsureHeadCommit(repository);

                var branch     = repository.Branches[BranchName];
                var branchTip  = branch.Tip;
                BranchTarget   = branchTip.Id;
                var headTip    = repository.Head.Tip;
                var baseCommit = repository.ObjectDatabase.FindMergeBase(headTip, branchTip);

                var migrationScaffolder = _migrationScaffolderFactory(_repositoryDescription);
                var migrators           = migrationScaffolder.Scaffold(baseCommit.Id, BranchTarget, MigrationMode.Upgrade);

                branchTip = ResolveRequiredMigrator(repository, branchTip, migrators);

                ComputeMerge(repository, baseCommit, branchTip, headTip);
            });
        }
Пример #8
0
        /// <summary>
        /// Applies the specified merger.
        /// </summary>
        /// <param name="merger">The merger.</param>
        /// <returns>The merge commit id.</returns>
        internal ObjectId Apply(Signature merger)
        {
            if (merger == null)
            {
                throw new ArgumentNullException(nameof(merger));
            }
            var remainingConflicts = _metadataTreeMerge.ModifiedChunks.Where(c => c.IsInConflict).ToList();

            if (remainingConflicts.Any())
            {
                throw new RemainingConflictsException(remainingConflicts);
            }

            return(_repositoryProvider.Execute(_repositoryDescription, repository =>
            {
                _metadataTreeMerge.EnsureHeadCommit(repository);

                _metadataTreeMerge.RequiredMigrator?.Apply();
                return ApplyMerge(merger, repository);
            }));
        }