private static void AddEmptyBranchesVirtualTipCommits(MRepository repository) { IEnumerable <MBranch> emptyBranches = repository.Branches.Values .Where(b => !b.Commits.Any() && !b.IsLocalPart); foreach (MBranch branch in emptyBranches) { string virtualShaText = (Guid.NewGuid() + Guid.NewGuid().ToString()).Replace("-", "") .Substring(0, 40); CommitSha virtualSha = new CommitSha(virtualShaText); CommitId virtualId = new CommitId(virtualShaText); MCommit commit = AddVirtualCommit(repository, virtualId); commit.IsVirtual = true; commit.BranchId = branch.Id; commit.SetBranchName(branch.Name); CopyToVirtualCommit(repository, branch, commit, virtualSha); SetChildOfParents(commit); //repository.Commits[commit.Id] = commit; branch.CommitIds.Add(commit.Id); branch.TipCommitId = commit.Id; branch.FirstCommitId = commit.Id; branch.TipCommit.BranchTips = $"{branch.Name} branch tip"; } }
/// <summary> /// Builds a <see cref="FilterDefinition{BsonDocument}" /> corresponding to the <see cref="CommitId" /> supplied /// </summary> /// <param name="commit">A <see cref="CommitId" /></param> /// <returns>A <see cref="FilterDefinition{BsonDocument}" /> corresponding to the <see cref="CommitId" /></returns> public static FilterDefinition <BsonDocument> ToFilter(this CommitId commit) { var builder = Builders <BsonDocument> .Filter; var filter = builder.Eq(CommitConstants.COMMIT_ID, commit.Value); return(filter); }
private static void SetMasterBranchCommits(MRepository repository, MSubBranch subBranch) { CommitId commitId = subBranch.TipCommitId; while (commitId != CommitId.None) { MCommit commit = repository.Commits[commitId]; if (commit.BranchName == subBranch.Name && commit.SubBranchId != null) { // Do not break if commit is the tip if (!(commit.Id == subBranch.TipCommitId && commit.SubBranchId == subBranch.SubBranchId)) { break; } } if (commit.HasBranchName && commit.BranchName != subBranch.Name) { Log.Warn($"commit {commit} already has branch {commit.BranchName} != {subBranch.Name}"); break; } commit.SetBranchName(subBranch.Name); commit.SubBranchId = subBranch.SubBranchId; commitId = commit.FirstParentId; } }
public static void CommitId_equality() { var commitId1 = new CommitId(Sha1.Hash("abc")); var commitId2 = new CommitId(Sha1.Hash("abc")); var commitId3 = new CommitId(Sha1.Hash("def")); Assert.True(commitId1 == commitId2); Assert.False(commitId1 != commitId2); Assert.True(commitId1.Equals((object)commitId2)); Assert.Equal(commitId1.Sha1.ToString(), commitId1.ToString()); Assert.Equal(commitId2.Sha1.ToString(), commitId2.ToString()); Assert.Equal(commitId3.Sha1.ToString(), commitId3.ToString()); Assert.Equal(commitId1, commitId2); Assert.Equal(commitId1.GetHashCode(), commitId2.GetHashCode()); Assert.Equal(commitId1.ToString(), commitId2.ToString()); Assert.NotEqual(CommitId.Empty, commitId1); Assert.NotEqual(CommitId.Empty.GetHashCode(), commitId1.GetHashCode()); Assert.NotEqual(CommitId.Empty.ToString(), commitId1.ToString()); Assert.NotEqual(commitId3, commitId1); Assert.NotEqual(commitId3.GetHashCode(), commitId1.GetHashCode()); Assert.NotEqual(commitId3.ToString(), commitId1.ToString()); }
public override string ToString(BotElement bot, Func <string, string> transform) { string formattedTime = String.IsNullOrEmpty(bot.Text.DateTimeFormat) ? AuthorTime.ToString() : AuthorTime.ToString(bot.Text.DateTimeFormat); var sb = new StringBuilder(); if (RefNames != null) { sb.AppendFormat("{0} ", transform(String.Concat(RefNames))); } sb.Append(bot.Text.CommitFormat.FormatWith(new { Action = Type == CommitRowType.Commit ? bot.Text.Commit : bot.Text.RefPointer, CommitUri = CommitUri, CommitId = transform(CommitId.ToHexString(settings.HashLength)), ChangeCounts = (ChangeCounts != null) ? String.Join(", ", ChangeCounts.Select(c => ChangeCountToString(bot, c))) : "", AuthorTime = formattedTime, Author = transform(Author), AuthorName = transform(AuthorName), AuthorEmail = transform(AuthorEmail), Comment = transform(Comment.Truncate(settings.CommentMaxLength)) })); return(sb.ToString()); }
public virtual async ValueTask <Commit?> ReadCommitAsync(CommitId commitId, CancellationToken cancellationToken) { var buffer = await ReadObjectAsync(commitId.Sha1, cancellationToken).ConfigureAwait(false); if (buffer == null) { return(default);
private async Task Commit() { var headers = new Dictionary <string, string> { [$"{Defaults.PrefixHeader}.{Defaults.CommitIdHeader}"] = CommitId.ToString(), [$"{Defaults.PrefixHeader}.Instance"] = Defaults.Instance.ToString() // Todo: what else can we put in here? }; var allRepos = _repositories.Values.Cast <IRepositoryCommit>().ToArray(); var changedStreams = allRepos.Sum(x => x.ChangedStreams); Logger.DebugEvent("Changed", "{Changed} streams {CommitId}", changedStreams, CommitId); // Only prepare if multiple changed streams, which will quickly check all changed streams to see if they are all the same version as when we read them // Not 100% guarenteed to eliminate writing 1 stream then failing the other one but will help - and we also tell the user to not do this.. if (changedStreams > 1) { Logger.WarnEvent("BestPractices", "{Changed} changed streams. We highly discourage this https://github.com/volak/Aggregates.NET/wiki/Changing-Multiple-Streams", changedStreams, CommitId); // First check all streams read but not modified - if the store has a different version a VersionException will be thrown await allRepos.WhenAllAsync(x => x.Prepare(CommitId)).ConfigureAwait(false); } Logger.DebugEvent("Commit", "{CommitId} for {Repositories} repositories", CommitId, allRepos.Length); try { await allRepos.WhenAllAsync(x => x.Commit(CommitId, headers)).ConfigureAwait(false); } finally { Guid eventId; EventIds.TryRemove(CommitId, out eventId); } }
private string TryGetCommitId(string id) { if (CommitId.TryParse(id, out CommitId commitId)) { return(id); } else { var gitCommits = repositoryMgr.Value.Repository?.MRepository?.GitCommits; if (gitCommits == null) { return(id); } var commits = gitCommits.ToList(); foreach (var pair in commits) { if (pair.Value.Sha.Sha.StartsWithOic(id)) { commitId = new CommitId(pair.Value.Sha); return(commitId.Id); } } } return(id); }
/// <summary> /// /// </summary> /// <param name="sequence"></param> /// <param name="source"></param> /// <param name="id"></param> /// <param name="timestamp"></param> /// <param name="correlationId"></param> public CommitMetadata(CommitSequenceNumber sequence, VersionedEventSource source, CommitId id, DateTimeOffset timestamp, CorrelationId correlationId) { Sequence = sequence; Source = source; Id = id; Timestamp = timestamp; CorrelationId = correlationId; }
public static JsonObject Convert(this CommitId model) { var wire = new JsonObject { [_id] = model.Sha1.ToString("N") }; return(wire); }
public static CommitId ConvertCommitId(this string wire) { if (string.IsNullOrWhiteSpace(wire)) return default; var sha1 = Sha1.Parse(wire); var model = new CommitId(sha1); return model; }
private void UpdateMerges( IEnumerable <Branch> sourceBranches, RepositoryViewModel repositoryViewModel) { var branches = repositoryViewModel.Branches; var commits = repositoryViewModel.Commits; var commitsById = repositoryViewModel.CommitsById; var merges = repositoryViewModel.Merges; var mergePoints = commits .Where(c => c.IsMergePoint && c.Commit.HasSecondParent && sourceBranches.Contains(c.Commit.SecondParent.Branch)) .ToList(); var branchStarts = branches.Where(b => b.Branch.HasParentBranch && sourceBranches.Contains(b.Branch.ParentCommit.Branch)) .Select(b => b.Branch.FirstCommit) .ToList(); bool isMergeInProgress = repositoryMgr.Repository.Status.IsMerging && branches.Any(b => b.Branch == repositoryMgr.Repository.CurrentBranch) && repositoryViewModel.MergingBranch != null && branches.Any(b => b.Branch.Id == repositoryViewModel.MergingBranch.Id) && repositoryMgr.Repository.UnComitted != null; int mergeCount = mergePoints.Count + branchStarts.Count + (isMergeInProgress ? 1 : 0); SetNumberOfItems(merges, mergeCount, _ => new MergeViewModel()); int index = 0; foreach (CommitViewModel childCommit in mergePoints) { CommitViewModel parentCommit = commitsById[childCommit.Commit.SecondParent.Id]; MergeViewModel merge = merges[index++]; SetMerge(merge, branches, childCommit, parentCommit); } foreach (Commit childCommit in branchStarts) { CommitViewModel parentCommit = commitsById[childCommit.FirstParent.Id]; MergeViewModel merge = merges[index++]; SetMerge(merge, branches, commitsById[childCommit.Id], parentCommit, false); } if (isMergeInProgress) { CommitId mergeSourceId = new CommitId(repositoryViewModel.MergingCommitSha); CommitViewModel parentCommit = commitsById[mergeSourceId]; MergeViewModel merge = merges[index++]; SetMerge(merge, branches, commitsById[parentCommit.Commit.Repository.UnComitted.Id], parentCommit); } }
static UncommittedEventStream BuildStreamFrom(EventStream stream) { var now = DateTimeOffset.UtcNow; var lastEvent = stream.Last(); var versionedEventSource = lastEvent.Metadata.VersionedEventSource; var correlationId = lastEvent.Metadata.CorrelationId; return(new UncommittedEventStream(CommitId.New(), correlationId, versionedEventSource, now, stream)); }
public static CommitIdWire Convert(this CommitId model) { var wire = new CommitIdWire { Id = model.Sha1.Convert() }; return(wire); }
void ThrowIfDuplicate(CommitId commitId) { if (!_duplicates.Contains(commitId)) { return; } throw new CommitIsADuplicate(); }
private async Task Commit() { Guid eventId; EventIds.TryRemove(CommitId, out eventId); var headers = new Dictionary <string, string> { [CommitHeader] = CommitId.ToString(), [TerminatingEventIdHeader] = eventId.ToString() // Todo: what else can we put in here? }; var allRepos = _repositories.Values.Concat(_entityRepositories.Values).Concat(_pocoRepositories.Values).ToArray(); var changedStreams = _repositories.Sum(x => x.Value.ChangedStreams) + _entityRepositories.Sum(x => x.Value.ChangedStreams); Logger.Write(LogLevel.Debug, () => $"Detected {changedStreams} changed streams in commit {CommitId}"); if (changedStreams > 1) { Logger.Write(LogLevel.Info, () => $"Starting prepare for commit id {CommitId} with {_repositories.Count + _entityRepositories.Count + _pocoRepositories.Count} tracked repositories"); using (PrepareTime.NewContext()) { // First check all streams read but not modified - if the store has a different version a VersionException will be thrown await allRepos.SelectAsync(x => x.Prepare(CommitId)).ConfigureAwait(false); } } // this log message can be expensive as the list is computed for a check // so only warn users about multiple stream commits when debugging Logger.Write(LogLevel.Debug, () => { var orderedRepos = _repositories.Select(x => new Tuple <int, IRepository>(x.Value.ChangedStreams, x.Value)) .Concat(_entityRepositories.Select(x => new Tuple <int, IRepository>(x.Value.ChangedStreams, x.Value))); if (orderedRepos.Count(x => x.Item1 != 0) > 1) { return($"Starting commit id {CommitId} with {_repositories.Count + _entityRepositories.Count + _pocoRepositories.Count} tracked repositories. You changed {orderedRepos.Sum(x => x.Item1)} streams. We highly discourage this https://github.com/volak/Aggregates.NET/wiki/Changing-Multiple-Streams"); } return($"Starting commit id {CommitId} with {_repositories.Count + _entityRepositories.Count + _pocoRepositories.Count} tracked repositories"); }); using (var ctx = CommitTime.NewContext()) { await allRepos.SelectAsync(x => x.Commit(CommitId, headers)).ConfigureAwait(false); if (ctx.Elapsed > TimeSpan.FromSeconds(1)) { SlowLogger.Write(LogLevel.Warn, () => $"Commit id {CommitId} took {ctx.Elapsed.TotalSeconds} seconds!"); } Logger.Write(LogLevel.Info, () => $"Commit id {CommitId} took {ctx.Elapsed.TotalMilliseconds} ms"); } }
public static void ChasmSerializer_Roundtrip_CommitId(IChasmSerializer ser) { var expected = new CommitId(Sha1.Hash("abc")); using (var buf = ser.Serialize(expected)) { var actual = ser.DeserializeCommitId(buf.Result); Assert.Equal(expected, actual); } }
public MCommit Commit(CommitId commitId) { MCommit commit; if (!Commits.TryGetValue(commitId, out commit)) { commit = AddNewCommit(commitId); } return(commit); }
private MCommit AddNewCommit(CommitId commitId) { MCommit commit = new MCommit() { Repository = this, Id = commitId, }; Commits[commitId] = commit; return(commit); }
private void SetNoteBranches( string nameSpace, CommitSha commitSha, BranchName branchName) { try { string file = Path.Combine(workingFolder, ".git", nameSpace); CommitId id = new CommitId(commitSha); File.AppendAllText(file, $"{id} {branchName}\n"); } catch (Exception e) { Log.Exception(e, $"Failed to add commit name for {commitSha} {branchName}"); } }
private async Task Commit() { var headers = new Dictionary <string, string> { [CommitHeader] = CommitId.ToString(), // Todo: what else can we put in here? }; var allRepos = _repositories.Values.Concat(_pocoRepositories.Values).ToArray(); var changedStreams = _repositories.Sum(x => x.Value.ChangedStreams) + _pocoRepositories.Sum(x => x.Value.ChangedStreams); Logger.Write(LogLevel.Debug, () => $"Detected {changedStreams} changed streams in commit {CommitId}"); // Only prepare if multiple changed streams, which will quickly check all changed streams to see if they are all the same version as when we read them // Not 100% guarenteed to eliminate writing 1 stream then failing the other one but will help - and we also tell the user to not do this.. if (changedStreams > 1) { Logger.Write(LogLevel.Warn, $"Starting prepare for commit id {CommitId} with {_repositories.Count + _pocoRepositories.Count} tracked repositories. You changed {changedStreams} streams. We highly discourage this https://github.com/volak/Aggregates.NET/wiki/Changing-Multiple-Streams"); using (PrepareTime.NewContext()) { // First check all streams read but not modified - if the store has a different version a VersionException will be thrown await allRepos.WhenAllAsync(x => x.Prepare(CommitId)).ConfigureAwait(false); } } Logger.Write(LogLevel.Debug, () => $"Starting commit id {CommitId} with {_repositories.Count + _pocoRepositories.Count} tracked repositories"); try { using (var ctx = CommitTime.NewContext()) { await allRepos.WhenAllAsync(x => x.Commit(CommitId, headers)).ConfigureAwait(false); if (ctx.Elapsed > TimeSpan.FromSeconds(1)) { SlowLogger.Write(LogLevel.Warn, () => $"Commit id {CommitId} took {ctx.Elapsed.TotalSeconds} seconds!"); } Logger.Write(LogLevel.Debug, () => $"Commit id {CommitId} took {ctx.Elapsed.TotalMilliseconds} ms"); } } finally { Guid eventId; EventIds.TryRemove(CommitId, out eventId); } }
public BufferSession Serialize(CommitId model) { var json = model.Write(); var maxLen = Encoding.UTF8.GetMaxByteCount(json.Length); // Utf8 is 1-4 bpc var rented = BufferSession.RentBuffer(maxLen); var count = Encoding.UTF8.GetBytes(json, 0, json.Length, rented, 0); var seg = new ArraySegment <byte>(rented, 0, count); var session = new BufferSession(seg); return(session); }
private static MCommit AddVirtualCommit( MRepository repository, CommitId virtualId) { MCommit commit = new MCommit() { Repository = repository, Id = virtualId, }; repository.Commits[virtualId] = commit; return(commit); }
private void AddVirtualEmptyCommit(MRepository repository) { CommitSha virtualSha = CommitSha.NoCommits; CommitId virtualId = new CommitId(virtualSha); GitCommit gitCommit = new GitCommit( virtualSha, "<Repository with no commits yet ...>", "<Repository with no commits yet ...>", "", DateTime.Now, DateTime.Now, new List <CommitId>()); repository.GitCommits[virtualId] = gitCommit; }
public BufferSession Serialize(CommitId model) { var wire = model.Convert(); var size = wire.CalculateSize(); var buffer = BufferSession.RentBuffer(size); using (var cos = new CodedOutputStream(buffer)) { wire.WriteTo(cos); var segment = new ArraySegment <byte>(buffer, 0, (int)cos.Position); var session = new BufferSession(buffer, segment); return(session); } }
public static void CommitId_Compare() { var comparer = CommitIdComparer.Default; var commitId1 = new CommitId(Sha1.Hash("abc")); var commitId2 = new CommitId(Sha1.Hash("abc")); var commitId3 = new CommitId(Sha1.Hash("def")); var list = new[] { commitId1, commitId2, commitId3 }; Assert.True(commitId1.CompareTo(commitId2) == 0); Assert.True(commitId1.CompareTo(commitId3) != 0); Array.Sort(list, comparer.Compare); Assert.True(list[0] <= list[1]); Assert.True(list[2] >= list[1]); }
private static void TrySetBranchNameFromSubject( CommitId commitId, GitCommit gitCommit, IDictionary <CommitId, BranchName> branchNameByCommitId, IDictionary <CommitId, BranchName> subjectBranchNameByCommitId) { // Trying to parse source and target branch names from subject. They can be like // "Merge branch 'branch-name' of remote-repository-path" // This is considered a "pull merge", where branch-name is both source and target. These are // usually automatically created by tools and thus more trustworthy. // Other merge merge subjects are less trustworthy since they sometiems are manually edited // like: // "Merge source-branch" // which contains a source branch name, but sometimes they contain a target like // "Merge source-branch into target-branch" MergeBranchNames mergeNames = BranchNameParser.ParseBranchNamesFromSubject(gitCommit.Subject); if (IsPullMergeCommit(mergeNames)) { // Pull merge subjects (source branch same as target) (trust worthy, so use branch name branchNameByCommitId[commitId] = mergeNames.SourceBranchName; branchNameByCommitId[gitCommit.ParentIds[0]] = mergeNames.SourceBranchName; branchNameByCommitId[gitCommit.ParentIds[1]] = mergeNames.SourceBranchName; // But also note the barnch name from subjects subjectBranchNameByCommitId[commitId] = mergeNames.SourceBranchName; subjectBranchNameByCommitId[gitCommit.ParentIds[0]] = mergeNames.SourceBranchName; subjectBranchNameByCommitId[gitCommit.ParentIds[1]] = mergeNames.SourceBranchName; } else { // Normal merge subject (less trustworthy) if (mergeNames.TargetBranchName != null) { // There was a target branch name subjectBranchNameByCommitId[commitId] = mergeNames.TargetBranchName; } if (mergeNames.SourceBranchName != null) { // There was a source branch name subjectBranchNameByCommitId[gitCommit.ParentIds[1]] = mergeNames.SourceBranchName; } } }
private void SetDetails() { if (CommitViewModel != null) { if (filesCommitId != CommitViewModel.Commit.RealCommitId || filesCommitId == GitModel.CommitId.Uncommitted) { files.Clear(); filesCommitId = CommitViewModel.Commit.RealCommitId; SetFilesAsync(commitViewModel.Commit).RunInBackground(); } } else { files.Clear(); filesCommitId = null; } }
private Repository ToRepository(MRepository mRepository) { Timing t = new Timing(); KeyedList <string, Branch> rBranches = new KeyedList <string, Branch>(b => b.Id); Dictionary <CommitId, Commit> rCommits = new Dictionary <CommitId, Commit>(); Branch currentBranch = null; Commit currentCommit = null; CommitId rootCommitId = mRepository.RootCommitId; Repository repository = new Repository( mRepository, new Lazy <IReadOnlyKeyedList <string, Branch> >(() => rBranches), new Lazy <IReadOnlyDictionary <CommitId, Commit> >(() => rCommits), new Lazy <Branch>(() => currentBranch), new Lazy <Commit>(() => currentCommit), commitsDetailsService, mRepository.Status, rootCommitId, mRepository.Uncommitted?.Id ?? CommitId.None); foreach (var mCommit in mRepository.Commits.Values) { Commit commit = Converter.ToCommit(repository, mCommit); rCommits[commit.Id] = commit; if (mCommit == mRepository.CurrentCommit) { currentCommit = commit; } } foreach (var mBranch in mRepository.Branches) { Branch branch = Converter.ToBranch(repository, mBranch.Value); rBranches.Add(branch); if (mBranch.Value == mRepository.CurrentBranch) { currentBranch = branch; } } t.Log($"Created repository {repository.Commits.Count} commits"); return(repository); }
public async Task AddNewCommitsAsync(MRepository repository) { int addedCount = 0; CancellationTokenSource cts = new CancellationTokenSource(); int seenCount = 0; void OnCommit(GitCommit commit) { CommitId commitId = new CommitId(commit.Sha); if (repository.GitCommits.TryGetValue(commitId, out _)) { if (commit.ParentIds.All(p => repository.GitCommits.TryGetValue(commitId, out _))) { seenCount++; if (seenCount > 5000) { Log.Debug($"Commit {commitId} already cached"); cts.Cancel(); } } else { seenCount = 0; } } else { seenCount = 0; repository.GitCommits[commitId] = commit; addedCount++; } } R result = await gitLogService.GetLogAsync(OnCommit, cts.Token); if (result.IsFaulted) { Log.Warn($"Failed to add new commits, {result}"); } Log.Debug($"Added {addedCount} to cache"); }