private RepositoryBranchState GetBranchStateForCommit(Commit targetCommit, List <Commit> commits)
        {
            var state = RepositoryState.CreateWithFullBranchState(m_allFiles);

            foreach (var commit in commits)
            {
                state.Apply(commit);
                if (commit == targetCommit)
                {
                    return(state[targetCommit.Branch]);
                }
            }

            throw new InvalidOperationException("Did not find target commit in commit stream");
        }
        private Commit ResolveTag(string tag)
        {
            var    state        = RepositoryState.CreateWithFullBranchState(m_allFiles);
            var    moveRecord   = new CommitMoveRecord(tag, m_log);
            Commit curCandidate = null;

            Queue <string> branchPath;
            var            lastCandidate = FindLastCandidate(tag, out branchPath);

            if (lastCandidate == null)
            {
                m_log.WriteLine("No commits");
                return(null);
            }

            var relevantCommits = FilterCommits(branchPath);

            foreach (var commit in relevantCommits)
            {
                state.Apply(commit);

                if (IsCandidate(tag, commit))
                {
                    curCandidate = commit;
                }

                if (curCandidate != null)
                {
                    List <FileInfo> filesToMove;
                    var             cmp = CompareCommitToTag(state, commit, tag, out filesToMove);

                    if (cmp == CommitTagMatch.Ahead)
                    {
                        // the commit has one or more files that are later
                        moveRecord.AddCommit(commit, filesToMove);
                    }
                    else if (cmp == CommitTagMatch.ExactMatch)
                    {
                        break;
                    }
                }

                if (curCandidate == lastCandidate)
                {
                    break;
                }
            }

            // now check added/removed files
            m_log.WriteLine("Candidate: {0}", curCandidate.ConciseFormat);
            var candidateBranchState = GetBranchStateForCommit(curCandidate, relevantCommits);

            CheckAddedRemovedFiles(tag, candidateBranchState, relevantCommits, moveRecord, ref curCandidate);

            // perform any moves
            moveRecord.FinalCommit = curCandidate;
            if (moveRecord.Commits.Any())
            {
                moveRecord.Apply(m_allCommits);
            }

            CheckCommitIndices(m_allCommits);
            return(curCandidate);
        }