Exemple #1
0
        /// <summary>
        /// Find the list of branches a given commit is reachable from when following
        /// parent.s
        /// <p>
        /// Note that this method calls
        /// <see cref="RevWalk.Reset()">RevWalk.Reset()</see>
        /// at the beginning.
        /// <p>
        /// In order to improve performance this method assumes clock skew among
        /// committers is never larger than 24 hours.
        /// </summary>
        /// <param name="commit">the commit we are looking at</param>
        /// <param name="revWalk">The RevWalk to be used.</param>
        /// <param name="refs">the set of branches we want to see reachability from</param>
        /// <returns>the list of branches a given commit is reachable from</returns>
        /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
        ///     </exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
        ///     </exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public static IList <Ref> FindBranchesReachableFrom(RevCommit commit, RevWalk revWalk
                                                            , ICollection <Ref> refs)
        {
            IList <Ref> result = new AList <Ref>();

            // searches from branches can be cut off early if any parent of the
            // search-for commit is found. This is quite likely, so optimize for this.
            revWalk.MarkStart(Arrays.AsList(commit.Parents));
            ObjectIdSubclassMap <ObjectId> cutOff = new ObjectIdSubclassMap <ObjectId>();
            int SKEW = 24 * 3600;

            // one day clock skew
            foreach (Ref @ref in refs)
            {
                RevObject maybehead = revWalk.ParseAny(@ref.GetObjectId());
                if (!(maybehead is RevCommit))
                {
                    continue;
                }
                RevCommit headCommit = (RevCommit)maybehead;
                // if commit is in the ref branch, then the tip of ref should be
                // newer than the commit we are looking for. Allow for a large
                // clock skew.
                if (headCommit.CommitTime + SKEW < commit.CommitTime)
                {
                    continue;
                }
                IList <ObjectId> maybeCutOff = new AList <ObjectId>(cutOff.Size());
                // guess rough size
                revWalk.ResetRetain();
                revWalk.MarkStart(headCommit);
                RevCommit current;
                Ref       found = null;
                while ((current = revWalk.Next()) != null)
                {
                    if (AnyObjectId.Equals(current, commit))
                    {
                        found = @ref;
                        break;
                    }
                    if (cutOff.Contains(current))
                    {
                        break;
                    }
                    maybeCutOff.AddItem(current.ToObjectId());
                }
                if (found != null)
                {
                    result.AddItem(@ref);
                }
                else
                {
                    foreach (ObjectId id in maybeCutOff)
                    {
                        cutOff.AddIfAbsent(id);
                    }
                }
            }
            return(result);
        }
Exemple #2
0
        /// <summary>Return the merge base of two commits.</summary>
        /// <remarks>Return the merge base of two commits.</remarks>
        /// <param name="aIdx">
        /// index of the first commit in
        /// <see cref="sourceObjects">sourceObjects</see>
        /// .
        /// </param>
        /// <param name="bIdx">
        /// index of the second commit in
        /// <see cref="sourceObjects">sourceObjects</see>
        /// .
        /// </param>
        /// <returns>the merge base of two commits</returns>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">one of the input objects is not a commit.
        ///     </exception>
        /// <exception cref="System.IO.IOException">objects are missing or multiple merge bases were found.
        ///     </exception>
        public virtual RevCommit GetBaseCommit(int aIdx, int bIdx)
        {
            if (sourceCommits[aIdx] == null)
            {
                throw new IncorrectObjectTypeException(sourceObjects[aIdx], Constants.TYPE_COMMIT
                                                       );
            }
            if (sourceCommits[bIdx] == null)
            {
                throw new IncorrectObjectTypeException(sourceObjects[bIdx], Constants.TYPE_COMMIT
                                                       );
            }
            walk.Reset();
            walk.SetRevFilter(RevFilter.MERGE_BASE);
            walk.MarkStart(sourceCommits[aIdx]);
            walk.MarkStart(sourceCommits[bIdx]);
            RevCommit @base = walk.Next();

            if (@base == null)
            {
                return(null);
            }
            RevCommit base2 = walk.Next();

            if (base2 != null)
            {
                throw new IOException(MessageFormat.Format(JGitText.Get().multipleMergeBasesFor,
                                                           sourceCommits[aIdx].Name, sourceCommits[bIdx].Name, @base.Name, base2.Name));
            }
            return(@base);
        }
Exemple #3
0
 /// <summary>Configure the generator to compute reverse blame (history of deletes).</summary>
 /// <remarks>
 /// Configure the generator to compute reverse blame (history of deletes).
 /// <p>
 /// This method is expensive as it immediately runs a RevWalk over the
 /// history spanning the expression
 /// <code>start..end</code>
 /// (end being more recent
 /// than start) and then performs the equivalent operation as
 /// <see cref="Push(string, NGit.AnyObjectId)">Push(string, NGit.AnyObjectId)</see>
 /// to begin blame traversal from the
 /// commit named by
 /// <code>start</code>
 /// walking forwards through history until
 /// <code>end</code>
 /// blaming line deletions.
 /// <p>
 /// A reverse blame may produce multiple sources for the same result line,
 /// each of these is a descendant commit that removed the line, typically
 /// this occurs when the same deletion appears in multiple side branches such
 /// as due to a cherry-pick. Applications relying on reverse should use
 /// <see cref="BlameResult">BlameResult</see>
 /// as it filters these duplicate sources and only
 /// remembers the first (oldest) deletion.
 /// </remarks>
 /// <param name="start">
 /// oldest commit to traverse from. The result file will be loaded
 /// from this commit's tree.
 /// </param>
 /// <param name="end">
 /// most recent commits to stop traversal at. Usually an active
 /// branch tip, tag, or HEAD.
 /// </param>
 /// <returns>
 ///
 /// <code>this</code>
 /// </returns>
 /// <exception cref="System.IO.IOException">the repository cannot be read.</exception>
 public virtual NGit.Blame.BlameGenerator Reverse <_T0>(AnyObjectId start, ICollection
                                                        <_T0> end) where _T0 : ObjectId
 {
     InitRevPool(true);
     ReverseWalk.ReverseCommit result = (ReverseWalk.ReverseCommit)revPool.ParseCommit
                                            (start);
     if (!Find(result, resultPath))
     {
         return(this);
     }
     revPool.MarkUninteresting(result);
     foreach (ObjectId id in end)
     {
         revPool.MarkStart(revPool.ParseCommit(id));
     }
     while (revPool.Next() != null)
     {
     }
     // just pump the queue
     Candidate.ReverseCandidate c = new Candidate.ReverseCandidate(result, resultPath);
     c.sourceBlob = idBuf.ToObjectId();
     c.LoadText(reader);
     c.regionList = new Region(0, 0, c.sourceText.Size());
     remaining    = c.sourceText.Size();
     Push(c);
     return(this);
 }
Exemple #4
0
 /// <exception cref="System.IO.IOException"></exception>
 private bool WantSatisfied(RevObject want)
 {
     if (want.Has(SATISFIED))
     {
         return(true);
     }
     walk.ResetRetain(SAVE);
     walk.MarkStart((RevCommit)want);
     if (oldestTime != 0)
     {
         walk.SetRevFilter(CommitTimeRevFilter.After(oldestTime * 1000L));
     }
     for (; ;)
     {
         RevCommit c = walk.Next();
         if (c == null)
         {
             break;
         }
         if (c.Has(PEER_HAS))
         {
             AddCommonBase(c);
             want.Add(SATISFIED);
             return(true);
         }
     }
     return(false);
 }
Exemple #5
0
 /// <exception cref="NGit.Errors.MissingObjectException"></exception>
 /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception>
 /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
 private NGit.Api.LogCommand Add(bool include, AnyObjectId start)
 {
     CheckCallable();
     try
     {
         if (include)
         {
             walk.MarkStart(walk.LookupCommit(start));
             startSpecified = true;
         }
         else
         {
             walk.MarkUninteresting(walk.LookupCommit(start));
         }
         return(this);
     }
     catch (MissingObjectException e)
     {
         throw;
     }
     catch (IncorrectObjectTypeException e)
     {
         throw;
     }
     catch (IOException e)
     {
         throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionOccuredDuringAddingOfOptionToALogCommand
                                                              , start), e);
     }
 }
Exemple #6
0
        private RevCommit ParseCommit(Repository repo, ObjectId id)
        {
            RevWalk rw   = new RevWalk(repo);
            var     head = rw.ParseCommit(id);

            rw.MarkStart(head);
            RevCommit commit = null;

            try
            {
                commit = rw.Next();
                while (commit != null)
                {
                    if (commit.Id.Name == id.Name)
                    {
                        return(commit);
                    }
                    commit = rw.Next();
                }
            }
            finally
            {
                rw.Release();
            }
            return(commit);
        }
        /// <summary>
        /// Compute the tracking status for the <code>branchName</code> in
        /// <code>repository</code>.
        /// </summary>
        /// <remarks>
        /// Compute the tracking status for the <code>branchName</code> in
        /// <code>repository</code>.
        /// </remarks>
        /// <param name="repository">the git repository to compute the status from</param>
        /// <param name="branchName">the local branch</param>
        /// <returns>the tracking status, or null if it is not known</returns>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public static NGit.BranchTrackingStatus Of(Repository repository, string branchName
                                                   )
        {
            BranchConfig branchConfig         = new BranchConfig(repository.GetConfig(), branchName);
            string       remoteTrackingBranch = branchConfig.GetRemoteTrackingBranch();

            if (remoteTrackingBranch == null)
            {
                return(null);
            }
            Ref tracking = repository.GetRef(remoteTrackingBranch);

            if (tracking == null)
            {
                return(null);
            }
            Ref local = repository.GetRef(branchName);

            if (local == null)
            {
                return(null);
            }
            RevWalk   walk           = new RevWalk(repository);
            RevCommit localCommit    = walk.ParseCommit(local.GetObjectId());
            RevCommit trackingCommit = walk.ParseCommit(tracking.GetObjectId());

            walk.SetRevFilter(RevFilter.MERGE_BASE);
            walk.MarkStart(localCommit);
            walk.MarkStart(trackingCommit);
            RevCommit mergeBase = walk.Next();

            walk.Reset();
            walk.SetRevFilter(RevFilter.ALL);
            int aheadCount  = RevWalkUtils.Count(walk, localCommit, mergeBase);
            int behindCount = RevWalkUtils.Count(walk, trackingCommit, mergeBase);

            return(new NGit.BranchTrackingStatus(remoteTrackingBranch, aheadCount, behindCount
                                                 ));
        }
		/// <exception cref="System.Exception"></exception>
		public virtual void Setup(int count)
		{
			Git git = new Git(db);
			for (int i = 0; i < count; i++)
			{
				git.Commit().SetCommitter(committer).SetAuthor(author).SetMessage("commit " + i).
					Call();
			}
			list = new RevCommitList<RevCommit>();
			RevWalk w = new RevWalk(db);
			w.MarkStart(w.LookupCommit(db.Resolve(Constants.HEAD)));
			list.Source(w);
		}
        public virtual void TestFillToCommit()
        {
            Setup(3);
            RevWalk w = new RevWalk(db);

            w.MarkStart(w.LookupCommit(db.Resolve(Constants.HEAD)));
            w.Next();
            RevCommit c = w.Next();

            NUnit.Framework.Assert.IsNotNull(c, "should have found 2. commit");
            list.FillTo(c, 5);
            NUnit.Framework.Assert.AreEqual(2, list.Count);
            NUnit.Framework.Assert.AreEqual("commit 1", list[1].GetFullMessage());
            NUnit.Framework.Assert.IsNull(list[3]);
        }
        /// <exception cref="System.Exception"></exception>
        public virtual void Setup(int count)
        {
            Git git = new Git(db);

            for (int i = 0; i < count; i++)
            {
                git.Commit().SetCommitter(committer).SetAuthor(author).SetMessage("commit " + i).
                Call();
            }
            list = new RevCommitList <RevCommit>();
            RevWalk w = new RevWalk(db);

            w.MarkStart(w.LookupCommit(db.Resolve(Constants.HEAD)));
            list.Source(w);
        }
Exemple #11
0
        /// <summary>
        /// Find commits that are reachable from <code>start</code> until a commit
        /// that is reachable from <code>end</code> is encountered.
        /// </summary>
        /// <remarks>
        /// Find commits that are reachable from <code>start</code> until a commit
        /// that is reachable from <code>end</code> is encountered. In other words,
        /// Find of commits that are in <code>start</code>, but not in
        /// <code>end</code>.
        /// <p>
        /// Note that this method calls
        /// <see cref="RevWalk.Reset()">RevWalk.Reset()</see>
        /// at the beginning.
        /// Also note that the existing rev filter on the walk is left as-is, so be
        /// sure to set the right rev filter before calling this method.
        /// </remarks>
        /// <param name="walk">the rev walk to use</param>
        /// <param name="start">the commit to start counting from</param>
        /// <param name="end">
        /// the commit where counting should end, or null if counting
        /// should be done until there are no more commits
        /// </param>
        /// <returns>the commits found</returns>
        /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
        ///     </exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
        ///     </exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public static IList <RevCommit> Find(RevWalk walk, RevCommit start, RevCommit end)
        {
            walk.Reset();
            walk.MarkStart(start);
            if (end != null)
            {
                walk.MarkUninteresting(end);
            }
            IList <RevCommit> commits = new AList <RevCommit>();

            foreach (RevCommit c in walk)
            {
                commits.AddItem(c);
            }
            return(commits);
        }
		private RevWalk CreateRevWalker()
		{
			var repository = _git.GetRepository();
			try
			{
				var revWalk = new RevWalk(repository);

				foreach (var reference in repository.GetAllRefs())
				{
					revWalk.MarkStart(revWalk.ParseCommit(reference.Value.GetObjectId()));
				}
				return revWalk;
			}
			finally
			{
				repository.Close();
			}
		}
        private RevWalk CreateRevWalker()
        {
            var repository = _git.GetRepository();

            try
            {
                var revWalk = new RevWalk(repository);

                foreach (var reference in repository.GetAllRefs())
                {
                    revWalk.MarkStart(revWalk.ParseCommit(reference.Value.GetObjectId()));
                }
                return(revWalk);
            }
            finally
            {
                repository.Close();
            }
        }
		/// <exception cref="NGit.Errors.TransportException"></exception>
		private void VerifyPrerequisites()
		{
			if (prereqs.IsEmpty())
			{
				return;
			}
			RevWalk rw = new RevWalk(transport.local);
			try
			{
				RevFlag PREREQ = rw.NewFlag("PREREQ");
				RevFlag SEEN = rw.NewFlag("SEEN");
				IDictionary<ObjectId, string> missing = new Dictionary<ObjectId, string>();
				IList<RevObject> commits = new AList<RevObject>();
				foreach (KeyValuePair<ObjectId, string> e in prereqs.EntrySet())
				{
					ObjectId p = e.Key;
					try
					{
						RevCommit c = rw.ParseCommit(p);
						if (!c.Has(PREREQ))
						{
							c.Add(PREREQ);
							commits.AddItem(c);
						}
					}
					catch (MissingObjectException)
					{
						missing.Put(p, e.Value);
					}
					catch (IOException err)
					{
						throw new TransportException(transport.uri, MessageFormat.Format(JGitText.Get().cannotReadCommit
							, p.Name), err);
					}
				}
				if (!missing.IsEmpty())
				{
					throw new MissingBundlePrerequisiteException(transport.uri, missing);
				}
				foreach (Ref r in transport.local.GetAllRefs().Values)
				{
					try
					{
						rw.MarkStart(rw.ParseCommit(r.GetObjectId()));
					}
					catch (IOException)
					{
					}
				}
				// If we cannot read the value of the ref skip it.
				int remaining = commits.Count;
				try
				{
					RevCommit c;
					while ((c = rw.Next()) != null)
					{
						if (c.Has(PREREQ))
						{
							c.Add(SEEN);
							if (--remaining == 0)
							{
								break;
							}
						}
					}
				}
				catch (IOException err)
				{
					throw new TransportException(transport.uri, JGitText.Get().cannotReadObject, err);
				}
				if (remaining > 0)
				{
					foreach (RevObject o in commits)
					{
						if (!o.Has(SEEN))
						{
							missing.Put(o, prereqs.Get(o));
						}
					}
					throw new MissingBundlePrerequisiteException(transport.uri, missing);
				}
			}
			finally
			{
				rw.Release();
			}
		}
Exemple #15
0
        public static void MergeTest(EngineContext engineContext)
        {
            // TODO: Currently hardcoded
            var db            = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT));
            var git           = new Git(db);
            var tree1Ref      = db.GetRef("test");
            var tree2Ref      = db.GetRef(Constants.HEAD);
            var tree1CommitId = tree1Ref.GetObjectId();
            var tree2CommitId = tree2Ref.GetObjectId();

            // Merge tree1 into current tree
            var mergeResult = git.Merge().Include(tree1CommitId).Call();

            if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING)
            {
                foreach (var conflict in mergeResult.GetConflicts())
                {
                    if (conflict.Key.EndsWith(".hotei"))
                    {
                        // Search base tree (common ancestor), if any
                        var walk = new RevWalk(db);
                        walk.SetRevFilter(RevFilter.MERGE_BASE);
                        walk.MarkStart(walk.ParseCommit(tree1CommitId));
                        walk.MarkStart(walk.ParseCommit(tree2CommitId));
                        var baseTree = walk.Next();

                        var tw = new NameConflictTreeWalk(db);
                        tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId());
                        tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId());
                        if (baseTree != null)
                        {
                            tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId());
                        }
                        tw.Filter = PathFilter.Create(conflict.Key);

                        // Should be only one iteration
                        while (tw.Next())
                        {
                            var tree0 = baseTree != null?tw.GetTree <AbstractTreeIterator>(2) : null;

                            var tree1 = tw.GetTree <AbstractTreeIterator>(0);
                            var tree2 = tw.GetTree <AbstractTreeIterator>(1);

                            // Get contents of every versions for the 3-way merge
                            var data0 = baseTree != null?LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null;

                            var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes()));
                            var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes()));

                            // Perform 3-way merge
                            var entities = new List <EntityDefinition>();
                            ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts);

                            // Save new merged file
                            var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write);
                            var stream     = new BinarySerializationWriter(fileStream);
                            stream.Context.Serializer = Serializer;
                            stream.SerializeClass(null, ref entities, ArchiveMode.Serialize);
                            fileStream.Close();

                            // TODO: Check if all conflicts are really resolved
                            // Add resolved file for merge commit
                            git.Add().AddFilepattern(conflict.Key).Call();
                        }
                    }
                }
            }
        }
Exemple #16
0
		public static RevCommit[] Blame (NGit.Repository repo, RevCommit commit, string file)
		{
			string localFile = ToGitPath (repo, file);
			TreeWalk tw = TreeWalk.ForPath (repo, localFile, commit.Tree);
			if (tw == null)
				return new RevCommit [0];
			int totalLines = GetFileLineCount (repo, tw);
			int lineCount = totalLines;			
			RevCommit[] lines = new RevCommit [lineCount];
			RevWalk revWalker = new RevWalk (repo);
			revWalker.MarkStart (commit);
			List<RevCommit> commitHistory = new List<RevCommit>();
			FilePath localCpath = FromGitPath (repo, localFile);
			
			foreach (RevCommit ancestorCommit in revWalker) {
				foreach (Change change in GetCommitChanges (repo, ancestorCommit)) {
					FilePath cpath = FromGitPath (repo, change.Path);
					if (localCpath == cpath || cpath.IsChildPathOf (localCpath))
					{
						commitHistory.Add(ancestorCommit);
						break;
					}
				}
			}
			
			int historySize = commitHistory.Count;
			
			if (historySize > 1) {
				RevCommit recentCommit = commitHistory[0];
				RawText latestRawText = GetRawText (repo, localFile, recentCommit);
				
				for (int i = 1; i < historySize; i++) {
					RevCommit ancestorCommit = commitHistory[i];
					RawText ancestorRawText = GetRawText (repo, localFile, ancestorCommit);
					lineCount -= SetBlameLines(repo, lines, recentCommit, latestRawText, ancestorRawText);
					recentCommit = ancestorCommit;
					
					if (lineCount <= 0)
					{
						break;
					}
				}
				
				if (lineCount > 0) {
					RevCommit firstCommit = commitHistory[historySize - 1];
					
					for (int i = 0; i < totalLines; i++) {
						if (lines[i] == null) {
							lines[i] = firstCommit;
						}
					}
				}
			} else if (historySize == 1) {
				RevCommit firstCommit = commitHistory[0];
					
				for (int i = 0; i < totalLines; i++) {
					lines[i] = firstCommit;
				}
			}
			
			return lines;
		}
Exemple #17
0
 /// <exception cref="System.Exception"></exception>
 protected internal virtual void MarkStart(RevCommit commit)
 {
     rw.MarkStart(commit);
 }
Exemple #18
0
        public static RevCommit[] Blame(NGit.Repository repo, RevCommit commit, string file)
        {
            string   localFile = ToGitPath(repo, file);
            TreeWalk tw        = TreeWalk.ForPath(repo, localFile, commit.Tree);

            if (tw == null)
            {
                return(new RevCommit [0]);
            }
            int totalLines = GetFileLineCount(repo, tw);
            int lineCount  = totalLines;

            RevCommit[] lines     = new RevCommit [lineCount];
            RevWalk     revWalker = new RevWalk(repo);

            revWalker.MarkStart(commit);
            List <RevCommit> commitHistory = new List <RevCommit>();
            FilePath         localCpath    = FromGitPath(repo, localFile);

            foreach (RevCommit ancestorCommit in revWalker)
            {
                foreach (Change change in GetCommitChanges(repo, ancestorCommit))
                {
                    FilePath cpath = FromGitPath(repo, change.Path);
                    if (change.ChangeType != ChangeType.Deleted && (localCpath == cpath || cpath.IsChildPathOf(localCpath)))
                    {
                        commitHistory.Add(ancestorCommit);
                        break;
                    }
                }
            }

            int historySize = commitHistory.Count;

            if (historySize > 1)
            {
                RevCommit recentCommit  = commitHistory[0];
                RawText   latestRawText = GetRawText(repo, localFile, recentCommit);

                for (int i = 1; i < historySize; i++)
                {
                    RevCommit ancestorCommit  = commitHistory[i];
                    RawText   ancestorRawText = GetRawText(repo, localFile, ancestorCommit);
                    lineCount   -= SetBlameLines(repo, lines, recentCommit, latestRawText, ancestorRawText);
                    recentCommit = ancestorCommit;

                    if (lineCount <= 0)
                    {
                        break;
                    }
                }

                if (lineCount > 0)
                {
                    RevCommit firstCommit = commitHistory[historySize - 1];

                    for (int i = 0; i < totalLines; i++)
                    {
                        if (lines[i] == null)
                        {
                            lines[i] = firstCommit;
                        }
                    }
                }
            }
            else if (historySize == 1)
            {
                RevCommit firstCommit = commitHistory[0];

                for (int i = 0; i < totalLines; i++)
                {
                    lines[i] = firstCommit;
                }
            }

            return(lines);
        }
Exemple #19
0
		// Utility class
		/// <summary>
		/// Count the number of commits that are reachable from <code>start</code>
		/// until a commit that is reachable from <code>end</code> is encountered.
		/// </summary>
		/// <remarks>
		/// Count the number of commits that are reachable from <code>start</code>
		/// until a commit that is reachable from <code>end</code> is encountered. In
		/// other words, count the number of commits that are in <code>start</code>,
		/// but not in <code>end</code>.
		/// <p>
		/// Note that this method calls
		/// <see cref="RevWalk.Reset()">RevWalk.Reset()</see>
		/// at the beginning.
		/// Also note that the existing rev filter on the walk is left as-is, so be
		/// sure to set the right rev filter before calling this method.
		/// </remarks>
		/// <param name="walk">the rev walk to use</param>
		/// <param name="start">the commit to start counting from</param>
		/// <param name="end">
		/// the commit where counting should end, or null if counting
		/// should be done until there are no more commits
		/// </param>
		/// <returns>the number of commits</returns>
		/// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
		/// 	</exception>
		/// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
		/// 	</exception>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public static int Count(RevWalk walk, RevCommit start, RevCommit end)
		{
			walk.Reset();
			walk.MarkStart(start);
			if (end != null)
			{
				walk.MarkUninteresting(end);
			}
			int count = 0;
			for (RevCommit c = walk.Next(); c != null; c = walk.Next())
			{
				count++;
			}
			return count;
		}
		public virtual void TestFillToCommit()
		{
			Setup(3);
			RevWalk w = new RevWalk(db);
			w.MarkStart(w.LookupCommit(db.Resolve(Constants.HEAD)));
			w.Next();
			RevCommit c = w.Next();
			NUnit.Framework.Assert.IsNotNull(c, "should have found 2. commit");
			list.FillTo(c, 5);
			NUnit.Framework.Assert.AreEqual(2, list.Count);
			NUnit.Framework.Assert.AreEqual("commit 1", list[1].GetFullMessage());
			NUnit.Framework.Assert.IsNull(list[3]);
		}
Exemple #21
0
        public static void MergeTest(EngineContext engineContext)
        {
            // TODO: Currently hardcoded
            var db = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT));
            var git = new Git(db);
            var tree1Ref = db.GetRef("test");
            var tree2Ref = db.GetRef(Constants.HEAD);
            var tree1CommitId = tree1Ref.GetObjectId();
            var tree2CommitId = tree2Ref.GetObjectId();

            // Merge tree1 into current tree
            var mergeResult = git.Merge().Include(tree1CommitId).Call();

            if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING)
            {
                foreach (var conflict in mergeResult.GetConflicts())
                {
                    if (conflict.Key.EndsWith(".hotei"))
                    {
                        // Search base tree (common ancestor), if any
                        var walk = new RevWalk(db);
                        walk.SetRevFilter(RevFilter.MERGE_BASE);
                        walk.MarkStart(walk.ParseCommit(tree1CommitId));
                        walk.MarkStart(walk.ParseCommit(tree2CommitId));
                        var baseTree = walk.Next();

                        var tw = new NameConflictTreeWalk(db);
                        tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId());
                        tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId());
                        if (baseTree != null)
                            tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId());
                        tw.Filter = PathFilter.Create(conflict.Key);

                        // Should be only one iteration
                        while (tw.Next())
                        {
                            var tree0 = baseTree != null ? tw.GetTree<AbstractTreeIterator>(2) : null;
                            var tree1 = tw.GetTree<AbstractTreeIterator>(0);
                            var tree2 = tw.GetTree<AbstractTreeIterator>(1);

                            // Get contents of every versions for the 3-way merge
                            var data0 = baseTree != null ? LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null;
                            var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes()));
                            var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes()));

                            // Perform 3-way merge
                            var entities = new List<EntityDefinition>();
                            ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts);

                            // Save new merged file
                            var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write);
                            var stream = new BinarySerializationWriter(fileStream);
                            stream.Context.Serializer = Serializer;
                            stream.SerializeClass(null, ref entities, ArchiveMode.Serialize);
                            fileStream.Close();

                            // TODO: Check if all conflicts are really resolved
                            // Add resolved file for merge commit
                            git.Add().AddFilepattern(conflict.Key).Call();
                        }
                    }
                }
            }
        }
Exemple #22
0
		public override Revision[] GetHistory (FilePath localFile, Revision since)
		{
			List<Revision> revs = new List<Revision> ();
		
			var repository = GetRepository (localFile);
			var hc = GetHeadCommit (repository);
			if (hc == null)
				return new GitRevision [0];

			RevWalk walk = new RevWalk (repository);
			string path = repository.ToGitPath (localFile);
			if (path != ".")
				walk.SetTreeFilter (FollowFilter.Create (path));
			walk.MarkStart (hc);
			
			foreach (RevCommit commit in walk) {
				PersonIdent author = commit.GetAuthorIdent ();
				GitRevision rev = new GitRevision (this, repository, commit.Id.Name, author.GetWhen().ToLocalTime (), author.GetName (), commit.GetFullMessage ());
				rev.Email = author.GetEmailAddress ();
				rev.ShortMessage = commit.GetShortMessage ();
				rev.Commit = commit;
				rev.FileForChanges = localFile;
				revs.Add (rev);
			}
			return revs.ToArray ();
		}
		/// <summary>
		/// Compute the tracking status for the <code>branchName</code> in
		/// <code>repository</code>.
		/// </summary>
		/// <remarks>
		/// Compute the tracking status for the <code>branchName</code> in
		/// <code>repository</code>.
		/// </remarks>
		/// <param name="repository">the git repository to compute the status from</param>
		/// <param name="branchName">the local branch</param>
		/// <returns>the tracking status, or null if it is not known</returns>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public static NGit.BranchTrackingStatus Of(Repository repository, string branchName
			)
		{
			BranchConfig branchConfig = new BranchConfig(repository.GetConfig(), branchName);
			string trackingBranch = branchConfig.GetTrackingBranch();
			if (trackingBranch == null)
			{
				return null;
			}
			Ref tracking = repository.GetRef(trackingBranch);
			if (tracking == null)
			{
				return null;
			}
			Ref local = repository.GetRef(branchName);
			if (local == null)
			{
				return null;
			}
			RevWalk walk = new RevWalk(repository);
			RevCommit localCommit = walk.ParseCommit(local.GetObjectId());
			RevCommit trackingCommit = walk.ParseCommit(tracking.GetObjectId());
			walk.SetRevFilter(RevFilter.MERGE_BASE);
			walk.MarkStart(localCommit);
			walk.MarkStart(trackingCommit);
			RevCommit mergeBase = walk.Next();
			walk.Reset();
			walk.SetRevFilter(RevFilter.ALL);
			int aheadCount = RevWalkUtils.Count(walk, localCommit, mergeBase);
			int behindCount = RevWalkUtils.Count(walk, trackingCommit, mergeBase);
			return new NGit.BranchTrackingStatus(trackingBranch, aheadCount, behindCount);
		}
Exemple #24
0
		/// <summary>
		/// Find the list of branches a given commit is reachable from when following
		/// parent.s
		/// <p>
		/// Note that this method calls
		/// <see cref="RevWalk.Reset()">RevWalk.Reset()</see>
		/// at the beginning.
		/// <p>
		/// In order to improve performance this method assumes clock skew among
		/// committers is never larger than 24 hours.
		/// </summary>
		/// <param name="commit">the commit we are looking at</param>
		/// <param name="revWalk">The RevWalk to be used.</param>
		/// <param name="refs">the set of branches we want to see reachability from</param>
		/// <returns>the list of branches a given commit is reachable from</returns>
		/// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
		/// 	</exception>
		/// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
		/// 	</exception>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		public static IList<Ref> FindBranchesReachableFrom(RevCommit commit, RevWalk revWalk
			, ICollection<Ref> refs)
		{
			IList<Ref> result = new AList<Ref>();
			// searches from branches can be cut off early if any parent of the
			// search-for commit is found. This is quite likely, so optimize for this.
			revWalk.MarkStart(Arrays.AsList(commit.Parents));
			ObjectIdSubclassMap<ObjectId> cutOff = new ObjectIdSubclassMap<ObjectId>();
			int SKEW = 24 * 3600;
			// one day clock skew
			foreach (Ref @ref in refs)
			{
				RevObject maybehead = revWalk.ParseAny(@ref.GetObjectId());
				if (!(maybehead is RevCommit))
				{
					continue;
				}
				RevCommit headCommit = (RevCommit)maybehead;
				// if commit is in the ref branch, then the tip of ref should be
				// newer than the commit we are looking for. Allow for a large
				// clock skew.
				if (headCommit.CommitTime + SKEW < commit.CommitTime)
				{
					continue;
				}
				IList<ObjectId> maybeCutOff = new AList<ObjectId>(cutOff.Size());
				// guess rough size
				revWalk.ResetRetain();
				revWalk.MarkStart(headCommit);
				RevCommit current;
				Ref found = null;
				while ((current = revWalk.Next()) != null)
				{
					if (AnyObjectId.Equals(current, commit))
					{
						found = @ref;
						break;
					}
					if (cutOff.Contains(current))
					{
						break;
					}
					maybeCutOff.AddItem(current.ToObjectId());
				}
				if (found != null)
				{
					result.AddItem(@ref);
				}
				else
				{
					foreach (ObjectId id in maybeCutOff)
					{
						cutOff.AddIfAbsent(id);
					}
				}
			}
			return result;
		}
Exemple #25
0
        /// <exception cref="NGit.Errors.TransportException"></exception>
        private void VerifyPrerequisites()
        {
            if (prereqs.IsEmpty())
            {
                return;
            }
            RevWalk rw = new RevWalk(transport.local);

            try
            {
                RevFlag PREREQ = rw.NewFlag("PREREQ");
                RevFlag SEEN   = rw.NewFlag("SEEN");
                IDictionary <ObjectId, string> missing = new Dictionary <ObjectId, string>();
                IList <RevObject> commits = new AList <RevObject>();
                foreach (KeyValuePair <ObjectId, string> e in prereqs.EntrySet())
                {
                    ObjectId p = e.Key;
                    try
                    {
                        RevCommit c = rw.ParseCommit(p);
                        if (!c.Has(PREREQ))
                        {
                            c.Add(PREREQ);
                            commits.AddItem(c);
                        }
                    }
                    catch (MissingObjectException)
                    {
                        missing.Put(p, e.Value);
                    }
                    catch (IOException err)
                    {
                        throw new TransportException(transport.uri, MessageFormat.Format(JGitText.Get().cannotReadCommit
                                                                                         , p.Name), err);
                    }
                }
                if (!missing.IsEmpty())
                {
                    throw new MissingBundlePrerequisiteException(transport.uri, missing);
                }
                foreach (Ref r in transport.local.GetAllRefs().Values)
                {
                    try
                    {
                        rw.MarkStart(rw.ParseCommit(r.GetObjectId()));
                    }
                    catch (IOException)
                    {
                    }
                }
                // If we cannot read the value of the ref skip it.
                int remaining = commits.Count;
                try
                {
                    RevCommit c;
                    while ((c = rw.Next()) != null)
                    {
                        if (c.Has(PREREQ))
                        {
                            c.Add(SEEN);
                            if (--remaining == 0)
                            {
                                break;
                            }
                        }
                    }
                }
                catch (IOException err)
                {
                    throw new TransportException(transport.uri, JGitText.Get().cannotReadObject, err);
                }
                if (remaining > 0)
                {
                    foreach (RevObject o in commits)
                    {
                        if (!o.Has(SEEN))
                        {
                            missing.Put(o, prereqs.Get(o));
                        }
                    }
                    throw new MissingBundlePrerequisiteException(transport.uri, missing);
                }
            }
            finally
            {
                rw.Release();
            }
        }
Exemple #26
0
        private RevCommit ParseCommit(Repository repo, ObjectId id)
        {
            RevWalk rw = new RevWalk(repo);
            var head = rw.ParseCommit(id);
            rw.MarkStart(head);
            RevCommit commit = null;
            try
            {
                commit = rw.Next();
                while( commit != null )
                {
                    if (commit.Id.Name == id.Name)
                    {
                        return commit;
                    }
                    commit = rw.Next();
                }

            }
            finally
            {
                rw.Release();
            }
            return commit;
        }
Exemple #27
0
 /// <summary>
 /// Find commits that are reachable from <code>start</code> until a commit
 /// that is reachable from <code>end</code> is encountered.
 /// </summary>
 /// <remarks>
 /// Find commits that are reachable from <code>start</code> until a commit
 /// that is reachable from <code>end</code> is encountered. In other words,
 /// Find of commits that are in <code>start</code>, but not in
 /// <code>end</code>.
 /// <p>
 /// Note that this method calls
 /// <see cref="RevWalk.Reset()">RevWalk.Reset()</see>
 /// at the beginning.
 /// Also note that the existing rev filter on the walk is left as-is, so be
 /// sure to set the right rev filter before calling this method.
 /// </remarks>
 /// <param name="walk">the rev walk to use</param>
 /// <param name="start">the commit to start counting from</param>
 /// <param name="end">
 /// the commit where counting should end, or null if counting
 /// should be done until there are no more commits
 /// </param>
 /// <returns>the commits found</returns>
 /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
 /// 	</exception>
 /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
 /// 	</exception>
 /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 public static IList<RevCommit> Find(RevWalk walk, RevCommit start, RevCommit end)
 {
     walk.Reset();
     walk.MarkStart(start);
     if (end != null)
     {
         walk.MarkUninteresting(end);
     }
     IList<RevCommit> commits = new AList<RevCommit>();
     foreach (RevCommit c in walk)
     {
         commits.AddItem(c);
     }
     return commits;
 }
		public override Revision[] GetHistory (FilePath localFile, Revision since)
		{
			List<Revision> revs = new List<Revision> ();
			
			RevWalk walk = new RevWalk (repo);
			var hc = GetHeadCommit ();
			if (hc == null)
				return new GitRevision [0];
			walk.MarkStart (hc);
			
			foreach (RevCommit commit in walk) {
				List<RevisionPath> paths = new List<RevisionPath> ();
				foreach (Change change in GitUtil.GetCommitChanges (repo, commit)) {
					FilePath cpath = FromGitPath (change.Path);
					if (cpath != localFile && !cpath.IsChildPathOf (localFile))
						continue;
					RevisionAction ra;
					switch (change.ChangeType) {
					case ChangeType.Added:
						ra = RevisionAction.Add;
						break;
					case ChangeType.Deleted:
						ra = RevisionAction.Delete;
						break;
					default:
						ra = RevisionAction.Modify;
						break;
					}
					RevisionPath p = new RevisionPath (cpath, ra, null);
					paths.Add (p);
				}
				if (paths.Count > 0) {
					PersonIdent author = commit.GetAuthorIdent ();
					GitRevision rev = new GitRevision (this, commit.Id.Name, author.GetWhen().ToLocalTime (), author.GetName (), commit.GetFullMessage (), paths.ToArray ());
					rev.Email = author.GetEmailAddress ();
					rev.ShortMessage = commit.GetShortMessage ();
					revs.Add (rev);
				}
			}
			return revs.ToArray ();
		}