/// <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; })); }
/// <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(); })); }
/// <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); } })); }
/// <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); })); } }
/// <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); })); }
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); }); }
/// <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); })); }