private bool PerformTreeFiltering(SimpleCommit commit, out Tree newTree) { newTree = null; if (hasTreeFiltering) { // clear the cache of entries to keep and the tasks to run entriesToKeep.Clear(); // Process white list if (keepPathPatterns.Count == 0) { KeepAllEntries(commit.Tree); } else { KeepEntries(commit, commit.Tree); } ProcessPendingTasks(); // Process black list if (removePathPatterns.Count > 0) { RemoveEntries(commit); ProcessPendingTasks(); } // If the commit was discarded by a tree-filtering, we need to skip it also here if (commit.Discard || entriesToKeep.Count == 0) { commit.Discard = true; // Store that this commit was discarded (used for re-parenting commits) commitsDiscarded.Add(commit.Sha); return(true); } // Rebuild a new tree based on the list of entries to keep var treeDef = new TreeDefinition(); foreach (var entryIt in entriesToKeep) { var entry = entryIt.Key; var entryValue = entryIt.Value; if (entryValue.Blob != null) { treeDef.Add(entry.Path, entryValue.Blob, entryValue.Mode); } else { treeDef.Add(entry.Path, entry); } } newTree = repo.ObjectDatabase.CreateTree(treeDef); } else { // If we don't have any tree filtering, just use the original tree newTree = commit.Tree; } return(false); }
/// <summary> /// Maps the specified commit to an already mapped commit. /// </summary> /// <param name="commit">The commit.</param> /// <returns>The new commit that has been mapped.</returns> /// <exception cref="System.ArgumentNullException">commit</exception> public SimpleCommit Map(SimpleCommit commit) { if (commit == null) { throw new ArgumentNullException("commit"); } return(rocketFilterApp.GetMapCommit(commit)); }
private void RemoveEntries(SimpleCommit commit) { var entries = entriesToKeep.ToList(); foreach (var entry in entries) { KeepEntry(commit, entry.Key, removePathPatterns, false); } }
internal SimpleCommit GetMapCommit(SimpleCommit commit) { Commit rewritten; if (commitMap.TryGetValue(commit.Id.Sha, out rewritten)) { return(GetSimpleCommit(rewritten)); } return(null); }
internal SimpleCommit GetSimpleCommit(Commit commit) { SimpleCommit simpleCommit; lock (simpleCommits) { if (!simpleCommits.TryGetValue(commit, out simpleCommit)) { simpleCommit = new SimpleCommit(this, commit); simpleCommits.Add(commit, simpleCommit); } } return(simpleCommit); }
private bool PerformCommitFiltering(SimpleCommit commit) { if (commitFilteringCallback != null) { // Filter this commit commitFilteringCallback(repo, commit); if (commit.Discard) { // Store that this commit was discarded (used for reparenting commits) commitsDiscarded.Add(commit.Sha); return(true); } } return(false); }
private void KeepEntry(SimpleCommit commit, TreeEntry entry, PathPatterns globalPattern, bool keepOnIgnore) { // Early exit if the commit was discarded by a tree-filtering if (commit.Discard) { return; } PathMatch match; var path = entry.Path; if (TryMatch(path, globalPattern, out match)) { // If path is ignored we can update the entries to keep if (match.IsIgnored) { DirectMatch(commit, entry, keepOnIgnore, ref match); } } else { var checkTask = Task.Factory.StartNew(() => { Match(path, globalPattern, ref match); // If path is ignored we can update the entries to keep if (match.IsIgnored) { DirectMatch(commit, entry, keepOnIgnore, ref match); } }); if (DisableTasks) { checkTask.RunSynchronously(); } else { lock (pendingTasks) { pendingTasks.Add(checkTask); } } } }
private void DirectMatch(SimpleCommit commit, TreeEntry entry, bool keepOnIgnore, ref PathMatch match) { // If callback return false, then we don't update entries to keep or delete SimpleEntry simpleEntry; var pattern = match.Pattern; var callback = pattern.Callback; if (callback != null) { simpleEntry = new SimpleEntry(repo, entry); simpleEntry.Discard = !keepOnIgnore; // Calls the script callback(repo, pattern.Path, commit, ref simpleEntry); // Skip if this commit is discarded by the tree filtering // Skip if this entry was discarded if (commit.Discard || (simpleEntry.Discard == keepOnIgnore)) { return; } } else { simpleEntry = default(SimpleEntry); } // We can update entries to keep lock (entriesToKeep) { if (keepOnIgnore) { entriesToKeep.Add(entry, simpleEntry.NewEntryValue); } else { entriesToKeep.Remove(entry); } } }
private void KeepEntries(SimpleCommit commit, Tree tree) { // Early exit if the commit was discarded by a tree-filtering if (commit.Discard) { return; } var task = Task.Factory.StartNew(() => { foreach (var entryIt in tree) { var entry = entryIt; if (entry.TargetType == TreeEntryTargetType.Tree) { var subTree = (Tree)entry.Target; KeepEntries(commit, subTree); } else if (entry.TargetType == TreeEntryTargetType.Blob || IncludeLinks) { KeepEntry(commit, entry, keepPathPatterns, true); } } }); if (DisableTasks) { task.RunSynchronously(); } else { lock (pendingTasks) { pendingTasks.Add(task); } } }
/// <summary> /// Processes a commit. /// </summary> /// <param name="commit">The commit.</param> private void ProcessCommit(SimpleCommit commit) { // ------------------------------------ // commit-filtering // ------------------------------------ if (PerformCommitFiltering(commit)) { return; } // Map parents of previous commit to new parents // Check if at least a parent has the same tree, if yes, we don't need to create a new commit Commit newCommit = null; Tree newTree; // ------------------------------------ // tree-filtering // ------------------------------------ if (PerformTreeFiltering(commit, out newTree)) { return; } // Process parents var newParents = new List <Commit>(); bool hasOriginalParents = false; bool treePruned = false; foreach (var parent in commit.Parents) { // Find a non discarded parent var remapParent = FindRewrittenParent(parent); // If remap parent is null, we can skip it if (remapParent == null) { continue; } // If parent is same, then it is an original parent that can be detached by DetachFirstCommits hasOriginalParents = parent.GitCommit == remapParent; newParents.Add(remapParent); // If parent tree is equal, we can prune this commit if (!treePruned && remapParent.Tree.Id == newTree.Id) { newCommit = remapParent; commitsDiscarded.Add(commit.Sha); treePruned = true; } } // If we detach first commits from their parents if (DetachFirstCommits && hasOriginalParents) { // Remove original parents foreach (var parent in commit.Parents) { newParents.Remove(parent.GitCommit); } } // If we need to create a new commit (new tree) if (newCommit == null) { var author = new Signature(commit.AuthorName, commit.AuthorEmail, commit.AuthorDate); var committer = new Signature(commit.CommitterName, commit.CommitterEmail, commit.CommitterDate); newCommit = repo.ObjectDatabase.CreateCommit(author, committer, commit.Message, newTree, newParents, false); } // Store the remapping between the old commit and the new commit commitMap.Add(commit.Sha, newCommit); // Store the last commit lastCommit = newCommit; }
/// <summary> /// Maps the specified commit to an already mapped commit. /// </summary> /// <param name="commit">The commit.</param> /// <returns>The new commit that has been mapped.</returns> /// <exception cref="System.ArgumentNullException">commit</exception> public SimpleCommit Map(SimpleCommit commit) { if (commit == null) throw new ArgumentNullException("commit"); return rocketFilterApp.GetMapCommit(commit); }