Example #1
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);
        }
Example #2
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);
        }
Example #3
0
        /// <summary>Ensure this list contains at least a specified number of commits.</summary>
        /// <remarks>
        /// Ensure this list contains at least a specified number of commits.
        /// <p>
        /// The revision walker specified by
        /// <see cref="RevCommitList{E}.Source(RevWalk)">RevCommitList&lt;E&gt;.Source(RevWalk)
        ///     </see>
        /// is pumped until
        /// the given number of commits are contained in this list. If there are
        /// fewer total commits available from the walk then the method will return
        /// early. Callers can test the final size of the list by
        /// <see cref="RevObjectList{E}.Count()">RevObjectList&lt;E&gt;.Count()</see>
        /// to
        /// determine if the high water mark specified was met.
        /// </remarks>
        /// <param name="highMark">
        /// number of commits the caller wants this list to contain when
        /// the fill operation is complete.
        /// </param>
        /// <exception cref="System.IO.IOException">
        /// see
        /// <see cref="RevWalk.Next()">RevWalk.Next()</see>
        /// </exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
        /// see
        /// <see cref="RevWalk.Next()">RevWalk.Next()</see>
        /// </exception>
        /// <exception cref="NGit.Errors.MissingObjectException">
        /// see
        /// <see cref="RevWalk.Next()">RevWalk.Next()</see>
        /// </exception>
        public virtual void FillTo(int highMark)
        {
            if (walker == null || size > highMark)
            {
                return;
            }
            RevCommit c = walker.Next();

            if (c == null)
            {
                walker = null;
                return;
            }
            Enter(size, (E)c);
            AddItem((E)c);
            while (size <= highMark)
            {
                int index            = size;
                RevObjectListBlock s = contents;
                while (index >> s.shift >= BLOCK_SIZE)
                {
                    s             = new RevObjectListBlock(s.shift + BLOCK_SHIFT);
                    s.contents[0] = contents;
                    contents      = s;
                }
                while (s.shift > 0)
                {
                    int i = index >> s.shift;
                    index -= i << s.shift;
                    if (s.contents[i] == null)
                    {
                        s.contents[i] = new RevObjectListBlock(s.shift - BLOCK_SHIFT);
                    }
                    s = (RevObjectListBlock)s.contents[i];
                }
                object[] dst = s.contents;
                while (size <= highMark && index < BLOCK_SIZE)
                {
                    c = walker.Next();
                    if (c == null)
                    {
                        walker = null;
                        return;
                    }
                    Enter(size++, (E)c);
                    dst[index++] = c;
                }
            }
        }
Example #4
0
        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]);
        }
Example #5
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);
 }
Example #6
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);
 }
Example #7
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);
        }
        /// <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
                                                 ));
        }
Example #9
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;
		}
Example #10
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;
        }
Example #11
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();
            }
        }
		/// <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();
			}
		}
Example #13
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();
                        }
                    }
                }
            }
        }
Example #14
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;
		}
Example #15
0
		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]);
		}
Example #16
0
		/// <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);
		}
Example #17
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();
                        }
                    }
                }
            }
        }