public void CanAddAndRemoveAnExistingTreeEntry(string sourcePath, string targetPath) { string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { var tree = repo.Head.Tip.Tree; var td = TreeDefinition.From(tree); Assert.Null(td[targetPath]); var te = tree[sourcePath]; td.Add(targetPath, te); var fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(te.Target.Id, fetched.TargetId); // Ensuring that the object database can handle uncommon paths. var newTree = repo.ObjectDatabase.CreateTree(td); Assert.Equal(newTree[targetPath].Target.Id, te.Target.Id); td.Remove(targetPath); Assert.Null(td[targetPath]); } }
public void CanPruneEmptyCommits(string[] treeEntriesToRemove, int expectedCommitCount, string expectedHead) { Assert.Equal(7, repo.Head.Commits.Count()); repo.Refs.RewriteHistory(new RewriteHistoryOptions { OnError = OnError, OnSucceeding = OnSucceeding, PruneEmptyCommits = true, CommitTreeRewriter = c => TreeDefinition.From(c) .Remove(treeEntriesToRemove), }, repo.Head.Commits); AssertSucceedingButNotError(); Assert.Equal(expectedCommitCount, repo.Head.Commits.Count()); if (expectedHead == null) { Assert.Null(repo.Head.Tip); } else { Assert.Equal(expectedHead, repo.Head.Tip.Id.Sha.Substring(0, expectedHead.Length)); } foreach (var treeEntry in treeEntriesToRemove) { Assert.True(repo.Head.Commits.All(c => c[treeEntry] == null), "Did not expect a tree entry at " + treeEntry); } }
private RebaseStatus CompleteRebase(IRepository r) { var computeChanges = _computeTreeChangesFactory(_rebase.Repository.Container, _rebase.Repository.RepositoryDescription); var previous = _rebase.StartRepository; var lastCommit = r.Lookup <Commit>(_rebase.RebaseCommitId); foreach (var info in _rebase.Transformations.Zip(_rebase.ReplayedCommits, (repository, commit) => (repository, r.Lookup <Commit>(commit)))) { var changes = computeChanges.Compare(previous, info.repository); if (changes.Any()) { var definition = TreeDefinition.From(lastCommit); r.UpdateTreeDefinition(changes, definition, _serializer, lastCommit); var tree = r.ObjectDatabase.CreateTree(definition); previous = info.repository; lastCommit = r.ObjectDatabase.CreateCommit(info.Item2.Author, info.Item2.Committer, info.Item2.Message, tree, new[] { lastCommit }, false); } } var logMessage = lastCommit.BuildCommitLogMessage(false, false, false); r.UpdateHeadAndTerminalReference(lastCommit, logMessage); if (_rebase.Repository.Container is ObjectRepositoryContainer container) { container.ReloadRepository(_rebase.Repository, lastCommit.Id); } return(RebaseStatus.Complete); }
public void CanReplaceAnExistingTreeWithAGitLink() { var commitId = (ObjectId)"480095882d281ed676fe5b863569520e54a7d5c0"; const string targetPath = "just_a_dir"; var path = SandboxSubmoduleTestRepo(); using (var repo = new Repository(path)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Equal(TreeEntryTargetType.Tree, td[targetPath].TargetType); Assert.NotNull(td["just_a_dir/contents"]); td.AddGitLink(targetPath, commitId); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(commitId, fetched.TargetId); Assert.Equal(TreeEntryTargetType.GitLink, fetched.TargetType); Assert.Equal(Mode.GitLink, fetched.Mode); Assert.Null(td["just_a_dir/contents"]); } }
public void CanReplaceAnExistingBlobWithATree(string targetPath) { const string treeSha = "7f76480d939dc401415927ea7ef25c676b8ddb8f"; string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td[targetPath]); Assert.Equal(TreeEntryTargetType.Blob, td[targetPath].TargetType); var objectId = new ObjectId(treeSha); var tree = repo.Lookup <Tree>(objectId); td.Add(targetPath, tree); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(TreeEntryTargetType.Tree, td[targetPath].TargetType); Assert.Equal(objectId, fetched.TargetId); Assert.Equal(Mode.Directory, fetched.Mode); } }
public void CanAddAnExistingSubmodule() { const string submodulePath = "sm_unchanged"; using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath)) { var submodule = repo.Submodules[submodulePath]; Assert.NotNull(submodule); TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td[submodulePath]); td.Remove(submodulePath); Assert.Null(td[submodulePath]); td.Add(submodule); TreeEntryDefinition fetched = td[submodulePath]; Assert.NotNull(fetched); Assert.Equal(submodule.HeadCommitId, fetched.TargetId); Assert.Equal(TreeEntryTargetType.GitLink, fetched.TargetType); Assert.Equal(Mode.GitLink, fetched.Mode); } }
public void CanAddAnExistingTree() { const string treeSha = "7f76480d939dc401415927ea7ef25c676b8ddb8f"; const string targetPath = "1/2"; string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); var objectId = new ObjectId(treeSha); var tree = repo.Lookup <Tree>(objectId); td.Add(targetPath, tree); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(objectId, fetched.TargetId); Assert.Equal(Mode.Directory, fetched.Mode); Assert.NotNull(td["1/2/branch_file.txt"]); } }
public void CanReplaceAnExistingGitLinkWithABlob() { const string blobSha = "42cfb95cd01bf9225b659b5ee3edcc78e8eeb478"; const string targetPath = "sm_unchanged"; using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td[targetPath]); Assert.Equal(TreeEntryTargetType.GitLink, td[targetPath].TargetType); Assert.Equal(Mode.GitLink, td[targetPath].Mode); var objectId = new ObjectId(blobSha); var blob = repo.Lookup <Blob>(objectId); td.Add(targetPath, blob, Mode.NonExecutableFile); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(objectId, fetched.TargetId); Assert.Equal(TreeEntryTargetType.Blob, fetched.TargetType); Assert.Equal(Mode.NonExecutableFile, fetched.Mode); } }
public Task <string> Save(string branch, string message, Document document, Author author) { if (string.IsNullOrEmpty(document.Key)) { _logger.Warn("Could not save document with empty key"); throw new ArgumentException("key cannot be empty"); } if (isTransactionInProgress(branch)) { var exceptionMessage = $"There is a transaction in progress for branch {branch}. Complete the transaction first."; _logger.Warn(exceptionMessage); throw new ArgumentException(exceptionMessage); } var blob = addBlob(document.Value); lock (getLock(branch)) { var tree = TreeDefinition.From(_repo.Branches[branch].Tip); addBlobToTree(document.Key, blob, tree); var sha = commitTree(branch, tree, getSignature(author), message); _logger.Trace($"Added {document.Key} on branch {branch} with commit {sha}"); push(branch); return(Task.FromResult(sha)); } }
public void Delete(string fileName) { var committer = CreateSignature(); Branch branch = _repo.Branches[_branchName]; if (branch == null) { return; } var commitLog = branch.Commits.Take(1).ToArray(); if (!commitLog.Any()) { return; } var td = TreeDefinition.From(commitLog.First()); td.Remove(fileName); var tree = _repo.ObjectDatabase.CreateTree(td); var commit = _repo.ObjectDatabase.CreateCommit(committer, committer, "Deleted " + fileName, tree, commitLog, false); UpdateRefs(commit); }
public string Save(string fileName, string value) { var contentBytes = System.Text.Encoding.UTF8.GetBytes(value); var ms = new MemoryStream(contentBytes); var blob = _repo.ObjectDatabase.CreateBlob(ms); var committer = new Signature("Computer", "*****@*****.**", DateTimeOffset.UtcNow); var commitLog = _repo.Head.Commits.Take(1).ToArray(); var commitPrefixString = commitLog.Any() && commitLog.First()[fileName] != null ? "Updated " : "Created "; var td = commitLog.Any() ? TreeDefinition.From(commitLog.First()) : new TreeDefinition(); td.Add(fileName, blob, Mode.NonExecutableFile); var tree = _repo.ObjectDatabase.CreateTree(td); var commit = _repo.ObjectDatabase.CreateCommit(committer, committer, commitPrefixString + fileName, tree, commitLog, false); if (_repo.Branches[_branchName] == null) { _repo.CreateBranch(_branchName, commit); //_repo.Branches[_branchName]. } UpdateRefs(commit); return(commit.Id.Sha); }
public void CanRewriteTreesByInjectingTreeEntry() { var commits = repo.Commits.QueryBy(new CommitFilter { Since = repo.Branches }).ToArray(); var currentReadme = repo.Head["README"]; repo.Refs.RewriteHistory(new RewriteHistoryOptions { OnError = OnError, OnSucceeding = OnSucceeding, CommitTreeRewriter = c => c["README"] == null ? TreeDefinition.From(c) : TreeDefinition.From(c) .Add("README", currentReadme), }, commits); AssertSucceedingButNotError(); Assert.Equal(new Commit[0], repo.Commits .QueryBy(new CommitFilter { Since = repo.Branches }) .Where(c => c["README"] != null && c["README"].Target.Id != currentReadme.Target.Id) .ToArray()); }
public void CanCreateATreeContainingABlobFromAFileInTheWorkingDirectory() { string path = SandboxStandardTestRepo(); using (var repo = new Repository(path)) { Assert.Equal(FileStatus.Nonexistent, repo.RetrieveStatus("hello.txt")); File.AppendAllText(Path.Combine(repo.Info.WorkingDirectory, "hello.txt"), "I'm a new file\n"); TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree) .Add("1/new file", "hello.txt", Mode.NonExecutableFile); TreeEntryDefinition ted = td["1/new file"]; Assert.NotNull(ted); Assert.Equal(ObjectId.Zero, ted.TargetId); td.Add("1/2/another new file", ted); Tree tree = repo.ObjectDatabase.CreateTree(td); TreeEntry te = tree["1/new file"]; Assert.NotNull(te.Target); Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", te.Target.Sha); Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/new file"].TargetId.Sha); te = tree["1/2/another new file"]; Assert.NotNull(te.Target); Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", te.Target.Sha); Assert.Equal("dc53d4c6b8684c21b0b57db29da4a2afea011565", td["1/2/another new file"].TargetId.Sha); } }
public void CanReplaceAnExistingGitLinkWithATree() { const string treeSha = "607d96653d4d0a4f733107f7890c2e67b55b620d"; const string targetPath = "sm_unchanged"; using (var repo = new Repository(SubmoduleTestRepoWorkingDirPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td[targetPath]); Assert.Equal(TreeEntryTargetType.GitLink, td[targetPath].TargetType); Assert.Equal(Mode.GitLink, td[targetPath].Mode); var objectId = new ObjectId(treeSha); var tree = repo.Lookup <Tree>(objectId); td.Add(targetPath, tree); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(objectId, fetched.TargetId); Assert.Equal(TreeEntryTargetType.Tree, fetched.TargetType); Assert.Equal(Mode.Directory, fetched.Mode); } }
public void CanReplaceAnExistingTreeWithABlob() { const string blobSha = "a8233120f6ad708f843d861ce2b7228ec4e3dec6"; const string targetPath = "1"; using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Equal(TreeEntryTargetType.Tree, td[targetPath].TargetType); var objectId = new ObjectId(blobSha); var blob = repo.Lookup <Blob>(objectId); Assert.NotNull(td["1/branch_file.txt"]); td.Add(targetPath, blob, Mode.NonExecutableFile); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(TreeEntryTargetType.Blob, td[targetPath].TargetType); Assert.Equal(objectId, fetched.TargetId); Assert.Equal(Mode.NonExecutableFile, fetched.Mode); Assert.Null(td["1/branch_file.txt"]); } }
public void CanBuildATreeDefinitionFromATree() { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td); } }
public Task <ITransaction> CreateTransaction(string branch) { if (isTransactionInProgress(branch)) { var exceptionMessage = $"There is a transaction in progress for branch {branch}. Complete the transaction first."; _logger.Warn(exceptionMessage); throw new ArgumentException(exceptionMessage); } _branchesWithTransaction.Add(branch, DateTime.Now.AddSeconds(_transactionTimeout)); var tree = TreeDefinition.From(_repo.Branches[branch].Tip); void EnsureTransactionInProgress() { if (!_branchesWithTransaction.ContainsKey(branch)) { var exceptionMessage = $"Transaction does not exist for branch {branch} or has timed out"; _logger.Warn(exceptionMessage); throw new ArgumentException(exceptionMessage); } _branchesWithTransaction[branch] = DateTime.Now.AddSeconds(_transactionTimeout); } return(Task.FromResult((ITransaction) new Transaction( add: document => { EnsureTransactionInProgress(); addBlobToTree(document.Key, addBlob(document.Value), tree); _logger.Trace($"Added blob with key {document.Key} to transaction on {branch}"); return Task.CompletedTask; }, commit: (message, author) => { EnsureTransactionInProgress(); lock (getLock(branch)) { var sha = commitTree(branch, tree, getSignature(author), message); _branchesWithTransaction.Remove(branch); _logger.Info($"Commited transaction on {branch} with commit {sha}"); push(branch); return Task.FromResult(sha); } }, abort: () => { _branchesWithTransaction.Remove(branch); _logger.Info($"Aborted transaction on {branch}"); return Task.CompletedTask; }, delete: key => { EnsureTransactionInProgress(); deleteKeyFromTree(key, tree); _logger.Trace($"Removed blob with key {key} in transaction on {branch}"); return Task.CompletedTask; }))); }
public void CanBuildATreeDefinitionFromATree() { string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.NotNull(td); } }
public void CanRewriteTrees() { repo.Refs.RewriteHistory(repo.Head.Commits, commitTreeRewriter: c => { var td = TreeDefinition.From(c); td.Remove("README"); return td; }); Assert.True(repo.Head.Commits.All(c => c["README"] == null)); }
public void CanRewriteTrees() { repo.Refs.RewriteHistory(new RewriteHistoryOptions { CommitTreeRewriter = c => TreeDefinition.From(c) .Remove("README"), }, repo.Head.Commits); Assert.True(repo.Head.Commits.All(c => c["README"] == null)); }
public Task <string> Delete(string branch, string key, string message, Author author) { lock (getLock(branch)) { var tree = TreeDefinition.From(_repo.Branches[branch].Tip); deleteKeyFromTree(key, tree); var sha = commitTree(branch, tree, getSignature(author), message); _logger.Info($"Deleted {key} on branch {branch} with commit {sha}"); push(branch); return(Task.FromResult(sha)); } }
public void RequestingANonExistingEntryReturnsNull() { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Null(td["nope"]); Assert.Null(td["not/here"]); Assert.Null(td["neither/in/here"]); Assert.Null(td["README/is/a-Blob/not-a-Tree"]); } }
private TreeDefinition GetCurrentTree() { var repo = this.lazyRepository.Value; var branch = repo.Branches[this.BranchName]; if (branch?.Tip == null) { return(new TreeDefinition()); } return(TreeDefinition.From(branch.Tip)); }
public void CanRetrieveEntries(string path, string expectedAttributes, TreeEntryTargetType expectedType, string expectedSha) { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); TreeEntryDefinition ted = td[path]; Assert.Equal(ToMode(expectedAttributes), ted.Mode); Assert.Equal(expectedType, ted.TargetType); Assert.Equal(new ObjectId(expectedSha), ted.TargetId); } }
public void CanNotReplaceAnExistingTreeWithATreeBeingAssembled() { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Equal(TreeEntryTargetType.Tree, td["1"].TargetType); td.Add("new/one", repo.Lookup <Blob>("a823312"), Mode.NonExecutableFile) .Add("new/two", repo.Lookup <Blob>("a71586c"), Mode.NonExecutableFile) .Add("new/tree", repo.Lookup <Tree>("7f76480")); Assert.Throws <InvalidOperationException>(() => td.Add("1", td["new"])); } }
public void RequestingAnEntryWithBadParamsThrows() { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Throws <ArgumentNullException>(() => td[null]); Assert.Throws <ArgumentException>(() => td[string.Empty]); Assert.Throws <ArgumentException>(() => td["/"]); Assert.Throws <ArgumentException>(() => td["/a"]); Assert.Throws <ArgumentException>(() => td["1//branch_file.txt"]); Assert.Throws <ArgumentException>(() => td["README/"]); Assert.Throws <ArgumentException>(() => td["1/"]); } }
public void CanRewriteTrees() { repo.Refs.RewriteHistory(new RewriteHistoryOptions { OnError = OnError, OnSucceeding = OnSucceeding, CommitTreeRewriter = c => TreeDefinition.From(c) .Remove("README"), }, repo.Head.Commits); AssertSucceedingButNotError(); Assert.True(repo.Head.Commits.All(c => c["README"] == null)); }
public void CanCreateATreeByAlteringAnExistingOne(string targetPath) { string path = SandboxBareTestRepo(); using (var repo = new Repository(path)) { var blob = repo.Lookup <Blob>(new ObjectId("a8233120f6ad708f843d861ce2b7228ec4e3dec6")); TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree) .Add(targetPath, blob, Mode.NonExecutableFile); Tree tree = repo.ObjectDatabase.CreateTree(td); Assert.NotNull(tree); } }
public void CanAddAnExistingTreeEntryDefinition(string sourcePath, string targetPath) { using (var repo = new Repository(BareTestRepoPath)) { TreeDefinition td = TreeDefinition.From(repo.Head.Tip.Tree); Assert.Null(td[targetPath]); TreeEntryDefinition ted = td[sourcePath]; td.Add(targetPath, ted); TreeEntryDefinition fetched = td[targetPath]; Assert.NotNull(fetched); Assert.Equal(ted, fetched); } }
public void InMemoryBackend(InMemoryBackend sut, Signature signature, string message) { var path = GetTempPath(); Repository.Init(path, true); using (var repository = new Repository(path)) { repository.ObjectDatabase.AddBackend(sut, priority: 5); var definition = !repository.Info.IsHeadUnborn ? TreeDefinition.From(repository.Head.Tip.Tree) : new TreeDefinition(); definition.Add("somefile.txt", repository.CreateBlob("foo"), Mode.NonExecutableFile); repository.Commit( definition, message, signature, signature); } }