/// <summary> /// Inserts a <see cref="LibGit2Sharp.Commit" /> into the object database by applying a <see cref="TreeDefinition"/>. /// </summary> /// <param name="repository">The repository.</param> /// <param name="changes">The changes.</param> /// <param name="message">The message.</param> /// <param name="author">The author.</param> /// <param name="committer">The committer.</param> /// <param name="hooks">The hooks.</param> /// <param name="options">The options.</param> /// <param name="mergeParent">The parent commit for a merge.</param> /// <returns>The created <see cref="LibGit2Sharp.Commit" />.</returns> internal static Commit CommitChanges(this IRepository repository, MetadataTreeChanges changes, string message, Signature author, Signature committer, GitHooks hooks, CommitOptions options = null, Commit mergeParent = null) { TreeDefinition definition; if (changes.OldRepository?.CommitId != null) { if (repository.Head.Tip.Id != changes.OldRepository.CommitId) { throw new NotSupportedException("Changes are not based on the HEAD commit."); } var startCommit = repository.Lookup <Commit>(changes.OldRepository.CommitId); definition = TreeDefinition.From(startCommit); } else if (repository.Info.IsHeadUnborn) { definition = new TreeDefinition(); } else { throw new NotSupportedException("Changes are not based on the HEAD commit."); } if (!hooks.OnCommitStarted(changes, message)) { return(null); } changes.UpdateTreeDefinition(repository, definition); var result = Commit(repository, definition, message, author, committer, options, mergeParent); hooks.OnCommitCompleted(changes, message, result.Id); return(result); }
/// <summary> /// Adds or replaces a <see cref="TreeEntryDefinition"/> at the specified <paramref name="targetTreeEntryPath"/> location. /// </summary> /// <param name="targetTreeEntryPath">The path within this <see cref="TreeDefinition"/>.</param> /// <param name="treeEntryDefinition">The <see cref="TreeEntryDefinition"/> to be stored at the described location.</param> /// <returns>The current <see cref="TreeDefinition"/>.</returns> public virtual TreeDefinition Add(string targetTreeEntryPath, TreeEntryDefinition treeEntryDefinition) { Ensure.ArgumentNotNullOrEmptyString(targetTreeEntryPath, "targetTreeEntryPath"); Ensure.ArgumentNotNull(treeEntryDefinition, "treeEntryDefinition"); if (Path.IsPathRooted(targetTreeEntryPath)) { throw new ArgumentException("The provided path is an absolute path."); } if (treeEntryDefinition is TransientTreeTreeEntryDefinition) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The {0} references a target which hasn't been created in the {1} yet. " + "This situation can occur when the target is a whole new {2} being created, or when an existing {2} is being updated because some of its children were added/removed.", typeof(TreeEntryDefinition).Name, typeof(ObjectDatabase).Name, typeof(Tree).Name)); } Tuple <string, string> segments = ExtractPosixLeadingSegment(targetTreeEntryPath); if (segments.Item2 != null) { TreeDefinition td = RetrieveOrBuildTreeDefinition(segments.Item1, true); td.Add(segments.Item2, treeEntryDefinition); } else { AddEntry(segments.Item1, treeEntryDefinition); } return(this); }
/// <summary> /// Removes the <see cref="TreeEntryDefinition"/> located at each of the /// specified <paramref name="treeEntryPaths"/>. /// </summary> /// <param name="td">The <see cref="TreeDefinition"/>.</param> /// <param name="treeEntryPaths">The paths within this <see cref="TreeDefinition"/>.</param> /// <returns>The current <see cref="TreeDefinition"/>.</returns> public static TreeDefinition Remove(this TreeDefinition td, IEnumerable <string> treeEntryPaths) { Ensure.ArgumentNotNull(td, "td"); Ensure.ArgumentNotNull(treeEntryPaths, "treeEntryPaths"); foreach (var treeEntryPath in treeEntryPaths) { td.Remove(treeEntryPath); } return(td); }
/// <summary> /// Builds a <see cref="TreeDefinition"/> from an existing <see cref="Tree"/>. /// </summary> /// <param name="tree">The <see cref="Tree"/> to be processed.</param> /// <returns>A new <see cref="TreeDefinition"/> holding the meta data of the <paramref name="tree"/>.</returns> public static TreeDefinition From(Tree tree) { Ensure.ArgumentNotNull(tree, "tree"); var td = new TreeDefinition(); foreach (TreeEntry treeEntry in tree) { td.Add(treeEntry.Name, treeEntry); } return td; }
/// <summary> /// Builds a <see cref = "TreeDefinition" /> from an existing <see cref = "Tree" />. /// </summary> /// <param name = "tree">The <see cref = "Tree" /> to be processed.</param> /// <returns>A new <see cref = "TreeDefinition" /> holding the meta data of the <paramref name = "tree" />.</returns> public static TreeDefinition From(Tree tree) { Ensure.ArgumentNotNull(tree, "tree"); var td = new TreeDefinition(); foreach (TreeEntry treeEntry in tree) { td.AddEntry(treeEntry.Name, TreeEntryDefinition.From(treeEntry)); } return(td); }
private TreeDefinition RetrieveOrBuildTreeDefinition(string treeName, bool shouldOverWrite) { TreeDefinition td; if (unwrappedTrees.TryGetValue(treeName, out td)) { return(td); } TreeEntryDefinition treeEntryDefinition; bool hasAnEntryBeenFound = entries.TryGetValue(treeName, out treeEntryDefinition); if (hasAnEntryBeenFound) { switch (treeEntryDefinition.TargetType) { case TreeEntryTargetType.Tree: td = From(treeEntryDefinition.Target as Tree); break; case TreeEntryTargetType.Blob: case TreeEntryTargetType.GitLink: if (shouldOverWrite) { td = new TreeDefinition(); break; } return(null); default: throw new NotImplementedException(); } } else { if (!shouldOverWrite) { return(null); } td = new TreeDefinition(); } entries[treeName] = new TransientTreeTreeEntryDefinition(); unwrappedTrees.Add(treeName, td); return(td); }
/// <summary> /// Inserts a <see cref="LibGit2Sharp.Commit" /> into the object database by applying a <see cref="TreeDefinition"/>. /// </summary> /// <param name="repository">The repository.</param> /// <param name="definition">The tree definition.</param> /// <param name="message">The message.</param> /// <param name="author">The author.</param> /// <param name="committer">The committer.</param> /// <param name="options">The options.</param> /// <param name="mergeParent">The parent commit for a merge.</param> /// <returns>The created <see cref="LibGit2Sharp.Commit" />.</returns> internal static Commit Commit(this IRepository repository, TreeDefinition definition, string message, Signature author, Signature committer, CommitOptions options = null, Commit mergeParent = null) { if (options == null) { options = new CommitOptions(); } var parents = RetrieveParentsOfTheCommitBeingCreated(repository, options.AmendPreviousCommit, mergeParent).ToList(); var tree = repository.ObjectDatabase.CreateTree(definition); var commit = repository.ObjectDatabase.CreateCommit(author, committer, message, tree, parents, false); var logMessage = commit.BuildCommitLogMessage(options.AmendPreviousCommit, repository.Info.IsHeadUnborn, parents.Count > 1); UpdateHeadAndTerminalReference(repository, commit, logMessage); return(commit); }
/// <summary> /// Retrieves the <see cref="TreeEntryDefinition"/> located the specified <paramref name="treeEntryPath"/> path. /// </summary> /// <param name="treeEntryPath">The path within this <see cref="TreeDefinition"/>.</param> /// <returns>The found <see cref="TreeEntryDefinition"/> if any; null otherwise.</returns> public virtual TreeEntryDefinition this[string treeEntryPath] { get { Ensure.ArgumentNotNullOrEmptyString(treeEntryPath, "treeEntryPath"); Tuple <string, string> segments = ExtractPosixLeadingSegment(treeEntryPath); if (segments.Item2 != null) { TreeDefinition td = RetrieveOrBuildTreeDefinition(segments.Item1, false); return(td == null ? null : td[segments.Item2]); } TreeEntryDefinition treeEntryDefinition; return(!entries.TryGetValue(segments.Item1, out treeEntryDefinition) ? null : treeEntryDefinition); } }
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); }
public void NewPost(Post post) { using (var repo = new Repository(_directory.FullName)) { var json = JsonConvert.SerializeObject(post); var sig = new Signature(post.Author.Name, post.Author.Identifier, post.Timestamp); // Create post structure var votesDir = repo.ObjectDatabase.CreateTree(new TreeDefinition()); var repliesDir = repo.ObjectDatabase.CreateTree(new TreeDefinition()); var postRoot = new TreeDefinition(); postRoot.Add(VOTES_DIR, votesDir); postRoot.Add(REPLIES_DIR, repliesDir); var commit = CommitToBranch(repo, CONTENT_BRANCH, json, sig, repo.ObjectDatabase.CreateTree(postRoot)); // Create a named branch for all future content on this post repo.CreateBranch(commit.Sha, commit); } }
/// <summary> /// Inserts a <see cref = "Tree"/> into the object database, created from a <see cref = "TreeDefinition"/>. /// </summary> /// <param name = "treeDefinition">The <see cref = "TreeDefinition"/>.</param> /// <returns>The created <see cref = "Tree"/>.</returns> public virtual Tree CreateTree(TreeDefinition treeDefinition) { Ensure.ArgumentNotNull(treeDefinition, "treeDefinition"); return treeDefinition.Build(repo); }
public void Vote(Post post, Identity voter, VoteType vote) { using (var repo = new Repository(_directory.FullName)) { var postCommit = repo.Branches[post.Id].Tip; // Retrieve existing tree var commitRoot = postCommit.Tree; var votesDir = (Tree)commitRoot[VOTES_DIR].Target; var repliesDir = (Tree)commitRoot[REPLIES_DIR].Target; // Copy existing content to new votes treedef var newVotesDir = new TreeDefinition(); foreach (TreeEntry obj in votesDir) { newVotesDir.Add(obj.Name, obj); } // Add new vote to new votes treedef Vote(repo, newVotesDir, vote); // Assemble new root treedef var newPostRoot = new TreeDefinition(); newPostRoot.Add(VOTES_DIR, repo.ObjectDatabase.CreateTree(newVotesDir)); newPostRoot.Add(REPLIES_DIR, repliesDir); // Commit new root treedef to post branch var message = string.Format("{0} by {1}", vote, voter.Name); var sig = new Signature(voter.Name, voter.Identifier, DateTimeOffset.UtcNow); CommitToBranch(repo, post.Id, message, sig, repo.ObjectDatabase.CreateTree(newPostRoot)); } }
/// <summary> /// Inserts a <see cref = "Tree"/> into the object database, created from a <see cref = "TreeDefinition"/>. /// </summary> /// <param name = "treeDefinition">The <see cref = "TreeDefinition"/>.</param> /// <returns>The created <see cref = "Tree"/>.</returns> public Tree CreateTree(TreeDefinition treeDefinition) { return(treeDefinition.Build(repo)); }
public void Prepare() { parent = repository.Head.Tip; if (parent == null) { treeDefinition = new TreeDefinition(); } else { treeDefinition = TreeDefinition.From(parent.Tree); } GitReset(); }
private void Vote(Repository repo, TreeDefinition votesDir, VoteType vote) { switch (vote) { case LibBastion.VoteType.Upvote: votesDir.Add(UPVOTE, Upvote(repo), Mode.NonExecutableFile); break; case LibBastion.VoteType.Downvote: votesDir.Add(DOWNVOTE, Downvote(repo), Mode.NonExecutableFile); break; } }
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); } } }
public GitTreeBuilder(ObjectDatabase objectDatabase, Tree tree) { _treeDefinition = TreeDefinition.From(tree); _objectDatabase = objectDatabase; }
private static void UpdateDeletionTreeDefinitions(IEnumerable <ObjectRepositoryEntryChanges> deletions, TreeDefinition definition, Commit oldCommit = null) { foreach (var deleted in deletions) { if (oldCommit == null) { throw new GitObjectDbException("Unexpected state: no deletion should be detected on blank commit."); } var folderEntry = oldCommit[deleted.Path.GetParentPath()]; if (folderEntry != null) { definition.Remove(folderEntry.Path); } } }
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); } } }
public GitTreeBuilder(ObjectDatabase objectDatabase) { _treeDefinition = new TreeDefinition(); _objectDatabase = objectDatabase; }
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); }
private TreeDefinition RetrieveOrBuildTreeDefinition(string treeName, bool shouldOverWrite) { TreeDefinition td; if (unwrappedTrees.TryGetValue(treeName, out td)) { return td; } TreeEntryDefinition treeEntryDefinition; bool hasAnEntryBeenFound = entries.TryGetValue(treeName, out treeEntryDefinition); if (hasAnEntryBeenFound) { switch (treeEntryDefinition.TargetType) { case TreeEntryTargetType.Tree: td = From(treeEntryDefinition.Target as Tree); break; case TreeEntryTargetType.Blob: case TreeEntryTargetType.GitLink: if (shouldOverWrite) { td = new TreeDefinition(); break; } return null; default: throw new NotImplementedException(); } } else { if (!shouldOverWrite) { return null; } td = new TreeDefinition(); } entries[treeName] = new TransientTreeTreeEntryDefinition(); unwrappedTrees.Add(treeName, td); return td; }
/// <summary> /// Write a config back to the global git repository. /// </summary> /// <param name="config"></param> public void WriteConfig(Config config) { using (var repository = new Repository(LocalGitRepositoryLocation)) { var remote = repository.Network.Remotes[ConfigurationRemote]; repository.Network.Fetch(remote); // Create a blob from the content stream Blob blob; var serializedObject = new JavaScriptSerializer().Serialize(config); var contentBytes = Encoding.UTF8.GetBytes(serializedObject); using (var memoryStream = new MemoryStream(contentBytes)) { blob = repository.ObjectDatabase.CreateBlob(memoryStream); } // Put the blob in a tree var treeDefinition = new TreeDefinition(); treeDefinition.Add(GitConfigurationFile, blob, Mode.NonExecutableFile); var tree = repository.ObjectDatabase.CreateTree(treeDefinition); // Committer and author var committer = new Signature(string.Format("{0}@{1}", Environment.UserName, Environment.MachineName), TeamEmailAddress, DateTime.Now); var author = committer; //Create the commit var refOriginMaster = repository.Refs[ConfigurationRemoteRef]; var parentCommit = refOriginMaster != null ? new[]{repository.Lookup<Commit>(refOriginMaster.TargetIdentifier)} : new Commit[0]; var commit = repository.ObjectDatabase.CreateCommit(author, committer, "Updating config.json", tree, parentCommit, false); // Update the HEAD reference to point to the latest commit repository.Refs.UpdateTarget(repository.Refs.Head, commit.Id); repository.Network.Push(remote, repository.Refs.Head.CanonicalName, ConfigurationRef); } }
/// <summary> /// Inserts a <see cref="Tree"/> into the object database, created from a <see cref="TreeDefinition"/>. /// </summary> /// <param name="treeDefinition">The <see cref="TreeDefinition"/>.</param> /// <returns>The created <see cref="Tree"/>.</returns> public virtual Tree CreateTree(TreeDefinition treeDefinition) { Ensure.ArgumentNotNull(treeDefinition, "treeDefinition"); return(treeDefinition.Build(repo)); }
/// <summary> /// Inserts a <see cref = "Tree"/> into the object database, created from a <see cref = "TreeDefinition"/>. /// </summary> /// <param name = "treeDefinition">The <see cref = "TreeDefinition"/>.</param> /// <returns>The created <see cref = "Tree"/>.</returns> public Tree CreateTree(TreeDefinition treeDefinition) { return treeDefinition.Build(repo); }