private ChangeKind? CommitContainsFile(Repository repository, Commit commit, string relativePath, GitHistoryOptions options, HashSet<ObjectId> necessaryObjectIds, out string renameSourcePath)
   {
       renameSourcePath = (string)null;
       if ((GitObject)commit == (GitObject)null)
           return new ChangeKind?();
       if (Enumerable.Count<Commit>(commit.Parents) == 0)
       {
           TreeEntry treeEntry = commit[relativePath];
           if (!(treeEntry != (TreeEntry)null))
               return new ChangeKind?();
           //trace "GitRepository.CommitContainsFile true id={0} objectId={1} relPath={2}", (object)GitId.GetShortId(commit.Id.Sha), (object)GitId.GetShortId(treeEntry.Target.Sha), (object)relativePath);
           return new ChangeKind?(ChangeKind.Added);
       }
       bool flag1 = (options & GitHistoryOptions.ExcludeMerges) != GitHistoryOptions.None;
       bool flag2 = (options & GitHistoryOptions.ExcludeUnnecessaryCommits) != GitHistoryOptions.None;
       bool flag3 = (options & GitHistoryOptions.FollowRenames) != GitHistoryOptions.None;
       List<ObjectId> list = (List<ObjectId>)null;
       Commit commit1 = Enumerable.First<Commit>(commit.Parents);
       string[] strArray = new string[1]
 {
   relativePath
 };
       TreeEntryChanges fileChange = repository.Diff.Compare<TreeChanges>(commit1.Tree, commit.Tree, (IEnumerable<string>)strArray, (ExplicitPathsOptions)null, new CompareOptions()
       {
           Similarity = SimilarityOptions.None
       })[relativePath];
       if (fileChange != null)
       {
           
           //TreeEntry treeEntry = commit.Tree[relativePath];
           //trace "GitRepository.CommitContainsFile true commitId={0} parentId={1} fileObjectId={2} parentObjectId={3} relPath={4}", commit.Id != (ObjectId)null ? (object)GitId.GetShortId(commit.Id.Sha) : (object)"null", commit1.Id != (ObjectId)null ? (object)GitId.GetShortId(commit1.Id.Sha) : (object)"null", fileChange.Oid != (ObjectId)null ? (object)GitId.GetShortId(fileChange.Oid.Sha) : (object)"null", fileChange.OldOid != (ObjectId)null ? (object)GitId.GetShortId(fileChange.OldOid.Sha) : (object)"null", (object)relativePath);
           
           bool flag4 = true;
           if (flag2)
           {
               flag4 = necessaryObjectIds.Contains(fileChange.Oid);
               if (flag4)
               {
                   list = new List<ObjectId>();
                   list.Add(fileChange.OldOid);
               }
           }
           bool flag5 = false;
           if (Enumerable.Count<Commit>(commit.Parents) > 1 && (flag1 || flag2 && flag4))
           {
               TreeEntry treeEntry1 = commit.Tree[relativePath];
               if (treeEntry1 != (TreeEntry)null && treeEntry1.Target != (GitObject)null)
               {
                   foreach (Commit commit2 in commit.Parents)
                   {
                       if (!(commit2.Id == commit1.Id))
                       {
                           TreeEntry treeEntry2 = commit2.Tree[relativePath];
                           if (treeEntry2 != (TreeEntry)null && treeEntry2.Target != (GitObject)null)
                           {
                               if (treeEntry2.Target.Id == treeEntry1.Target.Id)
                                   flag5 = true;
                               else if (flag2 && flag4)
                                   list.Add(treeEntry2.Target.Id);
                           }
                       }
                   }
               }
           }
           if (flag3 && fileChange.Status == ChangeKind.Added)
           {
               TreeChanges treeChanges = repository.Diff.Compare<TreeChanges>(commit1.Tree, commit.Tree, (IEnumerable<string>)null, (ExplicitPathsOptions)null, new CompareOptions()
               {
                   Similarity = SimilarityOptions.None
               });
               TreeEntryChanges renameSourceChange;
               if (treeChanges != null && this.CheckForRename(treeChanges, fileChange, out renameSourceChange))
                   renameSourcePath = renameSourceChange.Path;
           }
           if (flag5 && string.IsNullOrEmpty(renameSourcePath))
           {
               //trace "GitRepository.CommitContainsFile Skipping commitId={0} objectId={1} because it only contains merged content for the file", commit.Id != (ObjectId)null ? (object)GitId.GetShortId(commit.Id.Sha) : (object)"null", (object)GitId.GetShortId(fileChange.Oid.Sha));
               return new ChangeKind?(ChangeKind.Unmodified);
           }
           if (flag2)
           {
               if (!flag4 && string.IsNullOrEmpty(renameSourcePath))
               {
                   //trace "GitRepository.CommitContainsFile Skipping commitId={0} objectId={1} because the target objectId is not necessary", commit.Id != (ObjectId)null ? (object)GitId.GetShortId(commit.Id.Sha) : (object)"null", (object)GitId.GetShortId(fileChange.Oid.Sha));
                   return new ChangeKind?(ChangeKind.Unmodified);
               }
               list.ForEach((Action<ObjectId>)(pfObjId => necessaryObjectIds.Add(pfObjId)));
           }
           return new ChangeKind?(fileChange.Status);
       }
       //trace "GitRepository.CommitContainsFile false id={0} relPath={1}", (object)GitId.GetShortId(commit.Id.Sha), (object)relativePath);
       return new ChangeKind?(ChangeKind.Unmodified);
   }
        public IList<Commit> GetHistory(Repository repository, Branch branch, string relativePath, object since, object until, int maxCount, GitHistoryOptions options = GitHistoryOptions.None)
        {
            List<Commit> list = new List<Commit>();
            //bool flag1 = (options & GitHistoryOptions.IncludeChanges) != GitHistoryOptions.None;
            string str = relativePath;
            bool hasRelativePath = !string.IsNullOrEmpty(str);
            bool excludeUnnecessaryCommits = hasRelativePath && (options & GitHistoryOptions.ExcludeUnnecessaryCommits) != GitHistoryOptions.None;
            HashSet<ObjectId> necessaryObjectIds = new HashSet<ObjectId>();
            if (since == null)
            {
                if (branch != null && branch.Tip != null)
                    since = (object)branch.Tip.Id.Sha;
                if (since == null)
                    since = (object)repository.Head;
            }
            CommitSortStrategies commitSortStrategies = CommitSortStrategies.Time;
            if ((options & GitHistoryOptions.TopologicalTimeSort) != GitHistoryOptions.None)
                commitSortStrategies |= CommitSortStrategies.Topological;
            CommitFilter filter = new CommitFilter()
            {
                Since = since,
                Until = until,
                SortBy = commitSortStrategies
            };
            foreach (Commit commit in (IEnumerable<Commit>)repository.Commits.QueryBy(filter))
            {
                string renameSourcePath = (string)null;
                ChangeKind? changeKind = new ChangeKind?();
                if (hasRelativePath)
                {
                    if (excludeUnnecessaryCommits && necessaryObjectIds.Count == 0)
                    {
                        TreeEntry treeEntry = commit.Tree[relativePath];
                        if (treeEntry != (TreeEntry)null)
                            necessaryObjectIds.Add(treeEntry.Target.Id);
                    }
                    changeKind = this.CommitContainsFile(repository, commit, str, options, necessaryObjectIds, out renameSourcePath);
                    if (!changeKind.HasValue || changeKind.Value == ChangeKind.Unmodified)
                    {
                        //trace "GitRepository.GetHistory Skipping commit {0} because it doesn't contain the file", commit.Id != (ObjectId)null ? (object)GitId.GetShortId(commit.Id.Sha) : (object)(string)null);
                        continue;
                    }
                }

                //trace "GitRepository.GetHistory Adding commit {0}", commit.Id != (ObjectId)null ? (object)GitId.GetShortId(commit.Id.Sha) : (object)(string)null);
                list.Add(commit);
                if (hasRelativePath && excludeUnnecessaryCommits && (changeKind.HasValue && changeKind.Value == ChangeKind.Added) && string.IsNullOrEmpty(renameSourcePath))
                {
                    //trace "GitRepository.GetHistory Breaking after finding changeKind={0}", changeKind.HasValue ? (object)changeKind.Value.ToString() : (object)"null");
                    break;
                }
                if (list.Count >= maxCount)
                {
                    //trace "GitRepository.GetHistory Breaking after reaching the commit maxCount={0}", (object)maxCount);
                    break;
                }
                if (!string.IsNullOrEmpty(renameSourcePath))
                    str = renameSourcePath;
            }
            //trace "GitRepository.GetHistory Found {0} commits", (object)list.Count);
            return (IList<Commit>)list.AsReadOnly();
        }