Represents a git commit for scripting, with flattened properties with lower case name.
コード例 #1
0
        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);
        }
コード例 #2
0
 /// <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));
 }
コード例 #3
0
        private void RemoveEntries(SimpleCommit commit)
        {
            var entries = entriesToKeep.ToList();

            foreach (var entry in entries)
            {
                KeepEntry(commit, entry.Key, removePathPatterns, false);
            }
        }
コード例 #4
0
        internal SimpleCommit GetMapCommit(SimpleCommit commit)
        {
            Commit rewritten;

            if (commitMap.TryGetValue(commit.Id.Sha, out rewritten))
            {
                return(GetSimpleCommit(rewritten));
            }
            return(null);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
                    }
                }
            }
        }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
0
        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);
                }
            }
        }
コード例 #10
0
        /// <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;
        }
コード例 #11
0
 /// <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);
 }