Example #1
0
        protected override void HandleMissingFiles(string tag, List <Commit> commits, IEnumerable <FileInfo> files,
                                                   CommitMoveRecord moveRecord, ref Commit candidate)
        {
            var filteredFiles = files.Where(f => f.BranchAddedOn != tag);

            base.HandleMissingFiles(tag, commits, filteredFiles, moveRecord, ref candidate);
        }
        private void HandleExtraFiles(string tag, List <Commit> commits, IEnumerable <FileInfo> files,
                                      CommitMoveRecord moveRecord, ref Commit candidate)
        {
            int    candidateIndex = commits.IndexOfFromEnd(candidate);
            string tagBranch      = candidate.Branch;

            foreach (var file in files)
            {
                var tagRevision = GetRevisionForTag(file, tag);

                // search backwards for the file being added
                int addCommitIndex = -1;
                if (candidateIndex > 0)
                {
                    addCommitIndex = FindLastCommitBackwards(commits, candidateIndex - 1,
                                                             c => c.Any(r =>
                                                                        r.File == file &&
                                                                        !r.IsDead &&
                                                                        r.File.IsRevisionOnBranch(r.Revision, tagBranch)));
                }

                // search forwards for the file being deleted
                int deleteCommitIndex = -1;
                if (candidateIndex < commits.Count - 1)
                {
                    deleteCommitIndex = FindCommitForwards(commits, candidateIndex,
                                                           c => c.Any(r =>
                                                                      r.File == file &&
                                                                      r.IsDead &&
                                                                      r.File.IsRevisionOnBranch(r.Revision, tagBranch)));
                }

                if (deleteCommitIndex < 0 && addCommitIndex < 0)
                {
                    throw new TagResolutionException(String.Format(
                                                         "Tag {0}: file {1} is not tagged but a commit removing it could not be found", tag, file));
                }

                // pick the closest of the two
                int addDistance    = (addCommitIndex < 0) ? int.MaxValue : candidateIndex - addCommitIndex;
                int deleteDistance = (deleteCommitIndex < 0) ? int.MaxValue : deleteCommitIndex - candidateIndex;

                if (addDistance <= deleteDistance)
                {
                    moveRecord.AddCommit(commits[addCommitIndex], file);
                    for (int i = addCommitIndex + 1; i <= candidateIndex; i++)
                    {
                        if (commits[i].Any(r => r.File == file))
                        {
                            moveRecord.AddCommit(commits[i], file);
                        }
                    }
                }
                else
                {
                    candidate = commits[deleteCommitIndex];
                }
            }
        }
        protected virtual void HandleMissingFiles(string tag, List <Commit> commits, IEnumerable <FileInfo> files,
                                                  CommitMoveRecord moveRecord, ref Commit candidate)
        {
            int    candidateIndex = commits.IndexOfFromEnd(candidate);
            string tagBranch      = candidate.Branch;

            foreach (var file in files)
            {
                var tagRevision = GetRevisionForTag(file, tag);

                // search forwards for the file being added
                int addCommitIndex = -1;
                if (candidateIndex < commits.Count - 1)
                {
                    addCommitIndex = FindCommitForwards(commits, candidateIndex + 1,
                                                        c => c.Any(r =>
                                                                   r.File == file &&
                                                                   r.Revision == tagRevision &&
                                                                   r.File.IsRevisionOnBranch(r.Revision, tagBranch)));
                }

                if (addCommitIndex >= 0)
                {
                    // add any intermediate commits to the list of those that need moving
                    for (int i = candidateIndex + 1; i < addCommitIndex; i++)
                    {
                        moveRecord.AddCommit(commits[i], file);
                    }
                    candidate = commits[addCommitIndex];
                }
                else
                {
                    // search backwards for the file being deleted
                    int deleteCommitIndex = -1;
                    if (candidateIndex > 0)
                    {
                        deleteCommitIndex = FindCommitBackwards(commits, candidateIndex,
                                                                c => c.Any(r =>
                                                                           r.File == file &&
                                                                           r.IsDead &&
                                                                           r.File.IsRevisionOnBranch(r.Revision, tagBranch)));
                    }

                    if (deleteCommitIndex < 0)
                    {
                        throw new TagResolutionException(String.Format(
                                                             "Tag {0}: file {1} is tagged but a commit for it could not be found", tag, file));
                    }

                    moveRecord.AddCommit(commits[deleteCommitIndex], file);
                }
            }
        }
Example #4
0
        private Commit ResolveBranchpoint(string branch, string tag)
        {
            Commit branchCommit;

            if (!m_tagResolver.ResolvedTags.TryGetValue(tag, out branchCommit))
            {
                return(null);
            }

            // check for commits to the branch that occur before the tag
            CommitMoveRecord moveRecord = null;

            foreach (var c in m_commits)
            {
                if (c == branchCommit)
                {
                    break;
                }

                if (c.Branch == branch)
                {
                    if (moveRecord == null)
                    {
                        moveRecord = new CommitMoveRecord(branch, m_log)
                        {
                            FinalCommit = branchCommit
                        }
                    }
                    ;
                    moveRecord.AddCommit(c, c.Select(r => r.File));
                }
            }

            if (moveRecord != null)
            {
                m_log.WriteLine("Some commits on {0} need moving after branchpoint {1}", branch, tag);
                using (m_log.Indent())
                {
                    moveRecord.Apply(m_commits);
                }
            }

            return(branchCommit);
        }
    }
        private void CheckAddedRemovedFiles(string tag, RepositoryBranchState candidateBranchState, List <Commit> commits,
                                            CommitMoveRecord moveRecord, ref Commit candidate)
        {
            List <FileInfo> missingFiles = null;
            List <FileInfo> extraFiles   = null;
            var             liveFiles    = new HashSet <string>(candidateBranchState.LiveFiles);

            foreach (var file in m_allFiles)
            {
                if (GetRevisionForTag(file, tag) == Revision.Empty)
                {
                    if (liveFiles.Contains(file.Name))
                    {
                        AddAndCreateList(ref extraFiles, file);
                        m_log.WriteLine("Extra:   {0}", file.Name);

                        if (extraFiles.Count > PartialTagThreshold)
                        {
                            throw new TagResolutionException(String.Format("Tag {0} appears to be a partial tag", tag));
                        }
                    }
                }
                else
                {
                    if (!liveFiles.Contains(file.Name))
                    {
                        AddAndCreateList(ref missingFiles, file);
                        m_log.WriteLine("Missing: {0}", file.Name);
                    }
                }
            }

            if (missingFiles != null)
            {
                HandleMissingFiles(tag, commits, missingFiles, moveRecord, ref candidate);
            }

            if (extraFiles != null)
            {
                HandleExtraFiles(tag, commits, extraFiles, moveRecord, ref candidate);
            }
        }
		protected override void HandleMissingFiles(string tag, List<Commit> commits, IEnumerable<FileInfo> files,
				CommitMoveRecord moveRecord, ref Commit candidate)
		{
			var filteredFiles = files.Where(f => f.BranchAddedOn != tag);
			base.HandleMissingFiles(tag, commits, filteredFiles, moveRecord, ref candidate);
		}
		private Commit ResolveBranchpoint(string branch, string tag)
		{
			Commit branchCommit;
			if (!m_tagResolver.ResolvedTags.TryGetValue(tag, out branchCommit))
				return null;

			// check for commits to the branch that occur before the tag
			CommitMoveRecord moveRecord = null;
			foreach (var c in m_commits)
			{
				if (c == branchCommit)
					break;

				if (c.Branch == branch)
				{
					if (moveRecord == null)
						moveRecord = new CommitMoveRecord(branch, m_log) { FinalCommit = branchCommit };
					moveRecord.AddCommit(c, c.Select(r => r.File));
				}
			}

			if (moveRecord != null)
			{
				m_log.WriteLine("Some commits on {0} need moving after branchpoint {1}", branch, tag);
				using (m_log.Indent())
				{
					moveRecord.Apply(m_commits);
				}
			}

			return branchCommit;
		}
        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);
        }