Exemplo n.º 1
0
		public virtual void TestNonRecursiveFiltering()
		{
			ObjectInserter odi = db.NewObjectInserter();
			ObjectId aSth = odi.Insert(Constants.OBJ_BLOB, Sharpen.Runtime.GetBytesForString(
				"a.sth"));
			ObjectId aTxt = odi.Insert(Constants.OBJ_BLOB, Sharpen.Runtime.GetBytesForString(
				"a.txt"));
			DirCache dc = db.ReadDirCache();
			DirCacheBuilder builder = dc.Builder();
			DirCacheEntry aSthEntry = new DirCacheEntry("a.sth");
			aSthEntry.FileMode = FileMode.REGULAR_FILE;
			aSthEntry.SetObjectId(aSth);
			DirCacheEntry aTxtEntry = new DirCacheEntry("a.txt");
			aTxtEntry.FileMode = FileMode.REGULAR_FILE;
			aTxtEntry.SetObjectId(aTxt);
			builder.Add(aSthEntry);
			builder.Add(aTxtEntry);
			builder.Finish();
			ObjectId treeId = dc.WriteTree(odi);
			odi.Flush();
			TreeWalk tw = new TreeWalk(db);
			tw.Filter = PathSuffixFilter.Create(".txt");
			tw.AddTree(treeId);
			IList<string> paths = new List<string>();
			while (tw.Next())
			{
				paths.AddItem(tw.PathString);
			}
			IList<string> expected = new List<string>();
			expected.AddItem("a.txt");
			NUnit.Framework.Assert.AreEqual(expected, paths);
		}
Exemplo n.º 2
0
        /// <summary>A conflict is detected - add the three different stages to the index</summary>
        /// <param name="path">the path of the conflicting entry</param>
        /// <param name="e">the previous index entry</param>
        /// <param name="h">the first tree you want to merge (the HEAD)</param>
        /// <param name="m">the second tree you want to merge</param>
        private void Conflict(string path, DirCacheEntry e, AbstractTreeIterator h, AbstractTreeIterator
                              m)
        {
            conflicts.AddItem(path);
            DirCacheEntry entry;

            if (e != null)
            {
                entry = new DirCacheEntry(e.PathString, DirCacheEntry.STAGE_1);
                entry.CopyMetaData(e);
                builder.Add(entry);
            }
            if (h != null && !FileMode.TREE.Equals(h.EntryFileMode))
            {
                entry          = new DirCacheEntry(h.EntryPathString, DirCacheEntry.STAGE_2);
                entry.FileMode = h.EntryFileMode;
                entry.SetObjectId(h.EntryObjectId);
                builder.Add(entry);
            }
            if (m != null && !FileMode.TREE.Equals(m.EntryFileMode))
            {
                entry          = new DirCacheEntry(m.EntryPathString, DirCacheEntry.STAGE_3);
                entry.FileMode = m.EntryFileMode;
                entry.SetObjectId(m.EntryObjectId);
                builder.Add(entry);
            }
        }
Exemplo n.º 3
0
		/// <exception cref="System.Exception"></exception>
		private DirCacheEntry MakeEntry(string path, FileMode mode)
		{
			DirCacheEntry ent = new DirCacheEntry(path);
			ent.FileMode = mode;
			ent.SetObjectId(new ObjectInserter.Formatter().IdFor(Constants.OBJ_BLOB, Constants
				.Encode(path)));
			return ent;
		}
Exemplo n.º 4
0
 private void Update(string path, ObjectId mId, FileMode mode)
 {
     if (!FileMode.TREE.Equals(mode))
     {
         updated.Put(path, mId);
         DirCacheEntry entry = new DirCacheEntry(path, DirCacheEntry.STAGE_0);
         entry.SetObjectId(mId);
         entry.FileMode = mode;
         builder.Add(entry);
     }
 }
Exemplo n.º 5
0
        private void CopyMetaDataHelper(bool keepStage)
        {
            DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_2);

            e.IsAssumeValid = false;
            e.SetCreationTime(2L);
            e.FileMode     = FileMode.EXECUTABLE_FILE;
            e.LastModified = 3L;
            e.SetLength(100L);
            e.SetObjectId(ObjectId.FromString("0123456789012345678901234567890123456789"));
            e.IsUpdateNeeded = true;
            DirCacheEntry f = new DirCacheEntry("someother/path", DirCacheEntry.STAGE_1);

            f.IsAssumeValid = true;
            f.SetCreationTime(10L);
            f.FileMode     = FileMode.SYMLINK;
            f.LastModified = 20L;
            f.SetLength(100000000L);
            f.SetObjectId(ObjectId.FromString("1234567890123456789012345678901234567890"));
            f.IsUpdateNeeded = true;
            e.CopyMetaData(f, keepStage);
            NUnit.Framework.Assert.IsTrue(e.IsAssumeValid);
            NUnit.Framework.Assert.AreEqual(10L, e.GetCreationTime());
            NUnit.Framework.Assert.AreEqual(ObjectId.FromString("1234567890123456789012345678901234567890"
                                                                ), e.GetObjectId());
            NUnit.Framework.Assert.AreEqual(FileMode.SYMLINK, e.FileMode);
            NUnit.Framework.Assert.AreEqual(20L, e.LastModified);
            NUnit.Framework.Assert.AreEqual(100000000L, e.Length);
            if (keepStage)
            {
                NUnit.Framework.Assert.AreEqual(DirCacheEntry.STAGE_2, e.Stage);
            }
            else
            {
                NUnit.Framework.Assert.AreEqual(DirCacheEntry.STAGE_1, e.Stage);
            }
            NUnit.Framework.Assert.IsTrue(e.IsUpdateNeeded);
            NUnit.Framework.Assert.AreEqual("some/path", e.PathString);
        }
Exemplo n.º 6
0
        /// <exception cref="System.IO.IOException"></exception>
        private DirCacheEntry AddEntryToBuilder(string path, FilePath file, ObjectInserter
			 newObjectInserter, DirCacheBuilder builder, int stage)
        {
            FileInputStream inputStream = new FileInputStream(file);
            ObjectId id = newObjectInserter.Insert(Constants.OBJ_BLOB, file.Length(), inputStream
                );
            inputStream.Close();
            DirCacheEntry entry = new DirCacheEntry(path, stage);
            entry.SetObjectId(id);
            entry.FileMode = FileMode.REGULAR_FILE;
            entry.LastModified = file.LastModified();
            entry.SetLength((int)file.Length());
            builder.Add(entry);
            return entry;
        }
Exemplo n.º 7
0
        /// <summary>Updates the index after a content merge has happened.</summary>
        /// <remarks>
        /// Updates the index after a content merge has happened. If no conflict has
        /// occurred this includes persisting the merged content to the object
        /// database. In case of conflicts this method takes care to write the
        /// correct stages to the index.
        /// </remarks>
        /// <param name="base"></param>
        /// <param name="ours"></param>
        /// <param name="theirs"></param>
        /// <param name="result"></param>
        /// <param name="of"></param>
        /// <exception cref="System.IO.FileNotFoundException">System.IO.FileNotFoundException
        /// 	</exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        private void UpdateIndex(CanonicalTreeParser @base, CanonicalTreeParser ours, CanonicalTreeParser
			 theirs, MergeResult<RawText> result, FilePath of)
        {
            if (result.ContainsConflicts())
            {
                // a conflict occurred, the file will contain conflict markers
                // the index will be populated with the three stages and only the
                // workdir (if used) contains the halfways merged content
                Add(tw.RawPath, @base, DirCacheEntry.STAGE_1);
                Add(tw.RawPath, ours, DirCacheEntry.STAGE_2);
                Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3);
                mergeResults.Put(tw.PathString, result.Upcast ());
            }
            else
            {
                // no conflict occurred, the file will contain fully merged content.
                // the index will be populated with the new merged version
                DirCacheEntry dce = new DirCacheEntry(tw.PathString);
                int newMode = MergeFileModes(tw.GetRawMode(0), tw.GetRawMode(1), tw.GetRawMode(2)
                    );
                // set the mode for the new content. Fall back to REGULAR_FILE if
                // you can't merge modes of OURS and THEIRS
                dce.FileMode = (newMode == FileMode.MISSING.GetBits()) ? FileMode.REGULAR_FILE :
                    FileMode.FromBits(newMode);
                dce.LastModified = of.LastModified();
                dce.SetLength((int)of.Length());
                InputStream @is = new FileInputStream(of);
                try
                {
                    dce.SetObjectId(oi.Insert(Constants.OBJ_BLOB, of.Length(), @is));
                }
                finally
                {
                    @is.Close();
                    if (inCore)
                    {
                        FileUtils.Delete(of);
                    }
                }
                builder.Add(dce);
            }
        }
Exemplo n.º 8
0
		private void CopyMetaDataHelper(bool keepStage)
		{
			DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_2);
			e.IsAssumeValid = false;
			e.SetCreationTime(2L);
			e.FileMode = FileMode.EXECUTABLE_FILE;
			e.LastModified = 3L;
			e.SetLength(100L);
			e.SetObjectId(ObjectId.FromString("0123456789012345678901234567890123456789"));
			e.IsUpdateNeeded = true;
			DirCacheEntry f = new DirCacheEntry("someother/path", DirCacheEntry.STAGE_1);
			f.IsAssumeValid = true;
			f.SetCreationTime(10L);
			f.FileMode = FileMode.SYMLINK;
			f.LastModified = 20L;
			f.SetLength(100000000L);
			f.SetObjectId(ObjectId.FromString("1234567890123456789012345678901234567890"));
			f.IsUpdateNeeded = true;
			e.CopyMetaData(f, keepStage);
			NUnit.Framework.Assert.IsTrue(e.IsAssumeValid);
			NUnit.Framework.Assert.AreEqual(10L, e.GetCreationTime());
			NUnit.Framework.Assert.AreEqual(ObjectId.FromString("1234567890123456789012345678901234567890"
				), e.GetObjectId());
			NUnit.Framework.Assert.AreEqual(FileMode.SYMLINK, e.FileMode);
			NUnit.Framework.Assert.AreEqual(20L, e.LastModified);
			NUnit.Framework.Assert.AreEqual(100000000L, e.Length);
			if (keepStage)
			{
				NUnit.Framework.Assert.AreEqual(DirCacheEntry.STAGE_2, e.Stage);
			}
			else
			{
				NUnit.Framework.Assert.AreEqual(DirCacheEntry.STAGE_1, e.Stage);
			}
			NUnit.Framework.Assert.IsTrue(e.IsUpdateNeeded);
			NUnit.Framework.Assert.AreEqual("some/path", e.PathString);
		}
Exemplo n.º 9
0
		/// <summary>Resets the index to represent exactly some filesystem content.</summary>
		/// <remarks>
		/// Resets the index to represent exactly some filesystem content. E.g. the
		/// following call will replace the index with the working tree content:
		/// <p>
		/// <code>resetIndex(new FileSystemIterator(db))</code>
		/// <p>
		/// This method can be used by testcases which first prepare a new commit
		/// somewhere in the filesystem (e.g. in the working-tree) and then want to
		/// have an index which matches their prepared content.
		/// </remarks>
		/// <param name="treeItr">
		/// a
		/// <see cref="NGit.Treewalk.FileTreeIterator">NGit.Treewalk.FileTreeIterator</see>
		/// which determines which files should
		/// go into the new index
		/// </param>
		/// <exception cref="System.IO.FileNotFoundException">System.IO.FileNotFoundException
		/// 	</exception>
		/// <exception cref="System.IO.IOException">System.IO.IOException</exception>
		protected internal virtual void ResetIndex(FileTreeIterator treeItr)
		{
			ObjectInserter inserter = db.NewObjectInserter();
			DirCacheBuilder builder = db.LockDirCache().Builder();
			DirCacheEntry dce;
			while (!treeItr.Eof)
			{
				long len = treeItr.GetEntryLength();
				dce = new DirCacheEntry(treeItr.EntryPathString);
				dce.FileMode = treeItr.EntryFileMode;
				dce.LastModified = treeItr.GetEntryLastModified();
				dce.SetLength((int)len);
				FileInputStream @in = new FileInputStream(treeItr.GetEntryFile());
				dce.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, len, @in));
				@in.Close();
				builder.Add(dce);
				treeItr.Next(1);
			}
			builder.Commit();
			inserter.Flush();
			inserter.Release();
		}
Exemplo n.º 10
0
		/// <summary>adds a new path with the specified stage to the index builder</summary>
		/// <param name="path"></param>
		/// <param name="p"></param>
		/// <param name="stage"></param>
		/// <returns>the entry which was added to the index</returns>
		private DirCacheEntry Add(byte[] path, CanonicalTreeParser p, int stage)
		{
			if (p != null && !p.EntryFileMode.Equals(FileMode.TREE))
			{
				DirCacheEntry e = new DirCacheEntry(path, stage);
				e.FileMode = p.EntryFileMode;
				e.SetObjectId(p.EntryObjectId);
				builder.Add(e);
				return e;
			}
			return null;
		}
Exemplo n.º 11
0
 public override void Apply(DirCacheEntry ent)
 {
     ent.FileMode = FileMode.REGULAR_FILE;
     ent.SetLength(length);
     ent.SetObjectId(data);
 }
Exemplo n.º 12
0
			public override void Apply(DirCacheEntry ent)
			{
				ent.FileMode = FileMode.REGULAR_FILE;
				ent.SetLength(1);
				ent.SetObjectId(ObjectId.ZeroId);
			}
Exemplo n.º 13
0
		/// <exception cref="System.Exception"></exception>
		private DirCacheEntry MakeFile(string path)
		{
			DirCacheEntry ent = new DirCacheEntry(path);
			ent.FileMode = FileMode.REGULAR_FILE;
			ent.SetObjectId(new ObjectInserter.Formatter().IdFor(Constants.OBJ_BLOB, Constants
				.Encode(path)));
			return ent;
		}
Exemplo n.º 14
0
			public override void Apply(DirCacheEntry ent)
			{
				ent.FileMode = FileMode.EXECUTABLE_FILE;
				ent.SetObjectId(walk.GetObjectId(0));
			}
Exemplo n.º 15
0
			public override void Apply(DirCacheEntry ent)
			{
				ent.FileMode = FileMode.REGULAR_FILE;
				ent.SetObjectId(gitmodulesBlob);
			}
 public override void Apply(DirCacheEntry ent)
 {
     ent.FileMode = FileMode.REGULAR_FILE;
     ent.SetLength(1);
     ent.SetObjectId(ObjectId.ZeroId);
 }
Exemplo n.º 17
0
        /// <summary>A conflict is detected - add the three different stages to the index</summary>
        /// <param name="path">the path of the conflicting entry</param>
        /// <param name="e">the previous index entry</param>
        /// <param name="h">the first tree you want to merge (the HEAD)</param>
        /// <param name="m">the second tree you want to merge</param>
        private void Conflict(string path, DirCacheEntry e, AbstractTreeIterator h, AbstractTreeIterator
			 m)
        {
            conflicts.AddItem(path);
            DirCacheEntry entry;
            if (e != null)
            {
                entry = new DirCacheEntry(e.PathString, DirCacheEntry.STAGE_1);
                entry.CopyMetaData(e, true);
                builder.Add(entry);
            }
            if (h != null && !FileMode.TREE.Equals(h.EntryFileMode))
            {
                entry = new DirCacheEntry(h.EntryPathString, DirCacheEntry.STAGE_2);
                entry.FileMode = h.EntryFileMode;
                entry.SetObjectId(h.EntryObjectId);
                builder.Add(entry);
            }
            if (m != null && !FileMode.TREE.Equals(m.EntryFileMode))
            {
                entry = new DirCacheEntry(m.EntryPathString, DirCacheEntry.STAGE_3);
                entry.FileMode = m.EntryFileMode;
                entry.SetObjectId(m.EntryObjectId);
                builder.Add(entry);
            }
        }
Exemplo n.º 18
0
 public override void Apply(DirCacheEntry ent)
 {
     ent.FileMode = FileMode.REGULAR_FILE;
     ent.SetObjectId(id);
     ent.IsUpdateNeeded = false;
 }
Exemplo n.º 19
0
 private void Update(string path, ObjectId mId, FileMode mode)
 {
     if (!FileMode.TREE.Equals(mode))
     {
         updated.Put(path, mId);
         DirCacheEntry entry = new DirCacheEntry(path, DirCacheEntry.STAGE_0);
         entry.SetObjectId(mId);
         entry.FileMode = mode;
         builder.Add(entry);
     }
 }
Exemplo n.º 20
0
		public override void Revert (FilePath[] localPaths, bool recurse, IProgressMonitor monitor)
		{
			foreach (var group in localPaths.GroupBy (f => GetRepository (f))) {
				var repository = group.Key;
				var files = group.ToArray ();

			var c = GetHeadCommit (repository);
			RevTree tree = c != null ? c.Tree : null;
			
			List<FilePath> changedFiles = new List<FilePath> ();
			List<FilePath> removedFiles = new List<FilePath> ();
			
			monitor.BeginTask (GettextCatalog.GetString ("Reverting files"), 3);
			monitor.BeginStepTask (GettextCatalog.GetString ("Reverting files"), files.Length, 2);
			
			DirCache dc = repository.LockDirCache ();
			DirCacheBuilder builder = dc.Builder ();
			
			try {
				HashSet<string> entriesToRemove = new HashSet<string> ();
				HashSet<string> foldersToRemove = new HashSet<string> ();
				
				// Add the new entries
				foreach (FilePath fp in files) {
					string p = repository.ToGitPath (fp);
					
					// Register entries to be removed from the index
					if (Directory.Exists (fp))
						foldersToRemove.Add (p);
					else
						entriesToRemove.Add (p);
					
					TreeWalk tw = tree != null ? TreeWalk.ForPath (repository, p, tree) : null;
					if (tw == null) {
						// Removed from the index
					}
					else {
						// Add new entries
						
						TreeWalk r;
						if (tw.IsSubtree) {
							// It's a directory. Make sure we remove existing index entries of this directory
							foldersToRemove.Add (p);
							
							// We have to iterate through all folder files. We need a new iterator since the
							// existing rw is not recursive
							r = new NGit.Treewalk.TreeWalk(repository);
							r.Reset (tree);
							r.Filter = PathFilterGroup.CreateFromStrings(new string[]{p});
							r.Recursive = true;
							r.Next ();
						} else {
							r = tw;
						}
						
						do {
							// There can be more than one entry if reverting a whole directory
							string rpath = repository.FromGitPath (r.PathString);
							DirCacheEntry e = new DirCacheEntry (r.PathString);
							e.SetObjectId (r.GetObjectId (0));
							e.FileMode = r.GetFileMode (0);
							if (!Directory.Exists (Path.GetDirectoryName (rpath)))
								Directory.CreateDirectory (rpath);
							DirCacheCheckout.CheckoutEntry (repository, rpath, e);
							builder.Add (e);
							changedFiles.Add (rpath);
						} while (r.Next ());
					}
					monitor.Step (1);
				}
				
				// Add entries we want to keep
				int count = dc.GetEntryCount ();
				for (int n=0; n<count; n++) {
					DirCacheEntry e = dc.GetEntry (n);
					string path = e.PathString;
					if (!entriesToRemove.Contains (path) && !foldersToRemove.Any (f => IsSubpath (f,path)))
						builder.Add (e);
				}
				
				builder.Commit ();
			}
			catch {
				dc.Unlock ();
				throw;
			}
			
			monitor.EndTask ();
			monitor.BeginTask (null, files.Length);

			foreach (FilePath p in changedFiles) {
				FileService.NotifyFileChanged (p);
				monitor.Step (1);
			}
			foreach (FilePath p in removedFiles) {
				FileService.NotifyFileRemoved (p);
				monitor.Step (1);
			}
			monitor.EndTask ();
			}
		}
Exemplo n.º 21
0
 /// <summary>
 /// adds a entry to the index builder which is a copy of the specified
 /// DirCacheEntry
 /// </summary>
 /// <param name="e">the entry which should be copied</param>
 /// <returns>the entry which was added to the index</returns>
 private DirCacheEntry Keep(DirCacheEntry e)
 {
     DirCacheEntry newEntry = new DirCacheEntry(e.PathString, e.Stage);
     newEntry.FileMode = e.FileMode;
     newEntry.SetObjectId(e.GetObjectId());
     newEntry.LastModified = e.LastModified;
     newEntry.SetLength(e.Length);
     builder.Add(newEntry);
     return newEntry;
 }
Exemplo n.º 22
0
		/// <exception cref="System.IO.FileNotFoundException"></exception>
		/// <exception cref="System.InvalidOperationException"></exception>
		/// <exception cref="System.IO.IOException"></exception>
		private bool ContentMerge(CanonicalTreeParser @base, CanonicalTreeParser ours, CanonicalTreeParser
			 theirs)
		{
			MergeFormatter fmt = new MergeFormatter();
			RawText baseText = @base == null ? RawText.EMPTY_TEXT : GetRawText(@base.EntryObjectId
				, db);
			// do the merge
			MergeResult<RawText> result = mergeAlgorithm.Merge(RawTextComparator.DEFAULT, baseText
				, GetRawText(ours.EntryObjectId, db), GetRawText(theirs.EntryObjectId, db));
			FilePath of = null;
			FileOutputStream fos;
			if (!inCore)
			{
				FilePath workTree = db.WorkTree;
				if (workTree == null)
				{
					// TODO: This should be handled by WorkingTreeIterators which
					// support write operations
					throw new NotSupportedException();
				}
				of = new FilePath(workTree, tw.PathString);
				fos = new FileOutputStream(of);
				try
				{
					fmt.FormatMerge(fos, result, Arrays.AsList(commitNames), Constants.CHARACTER_ENCODING
						);
				}
				finally
				{
					fos.Close();
				}
			}
			else
			{
				if (!result.ContainsConflicts())
				{
					// When working inCore, only trivial merges can be handled,
					// so we generate objects only in conflict free cases
					of = FilePath.CreateTempFile("merge_", "_temp", null);
					fos = new FileOutputStream(of);
					try
					{
						fmt.FormatMerge(fos, result, Arrays.AsList(commitNames), Constants.CHARACTER_ENCODING
							);
					}
					finally
					{
						fos.Close();
					}
				}
			}
			if (result.ContainsConflicts())
			{
				// a conflict occured, the file will contain conflict markers
				// the index will be populated with the three stages and only the
				// workdir (if used) contains the halfways merged content
				Add(tw.RawPath, @base, DirCacheEntry.STAGE_1);
				Add(tw.RawPath, ours, DirCacheEntry.STAGE_2);
				Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3);
				mergeResults.Put(tw.PathString, result.Upcast ());
				return false;
			}
			else
			{
				// no conflict occured, the file will contain fully merged content.
				// the index will be populated with the new merged version
				DirCacheEntry dce = new DirCacheEntry(tw.PathString);
				dce.FileMode = tw.GetFileMode(0);
				dce.LastModified = of.LastModified();
				dce.SetLength((int)of.Length());
				InputStream @is = new FileInputStream(of);
				try
				{
					dce.SetObjectId(oi.Insert(Constants.OBJ_BLOB, of.Length(), @is));
				}
				finally
				{
					@is.Close();
					if (inCore)
					{
						FileUtils.Delete(of);
					}
				}
				builder.Add(dce);
				return true;
			}
		}
Exemplo n.º 23
0
        /// <summary>Processes one path and tries to merge.</summary>
        /// <remarks>
        /// Processes one path and tries to merge. This method will do all do all
        /// trivial (not content) merges and will also detect if a merge will fail.
        /// The merge will fail when one of the following is true
        /// <ul>
        /// <li>the index entry does not match the entry in ours. When merging one
        /// branch into the current HEAD, ours will point to HEAD and theirs will
        /// point to the other branch. It is assumed that the index matches the HEAD
        /// because it will only not match HEAD if it was populated before the merge
        /// operation. But the merge commit should not accidentally contain
        /// modifications done before the merge. Check the &lt;a href=
        /// "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge"
        /// &gt;git read-tree</a> documentation for further explanations.</li>
        /// <li>A conflict was detected and the working-tree file is dirty. When a
        /// conflict is detected the content-merge algorithm will try to write a
        /// merged version into the working-tree. If the file is dirty we would
        /// override unsaved data.</li>
        /// </remarks>
        /// <param name="base">the common base for ours and theirs</param>
        /// <param name="ours">
        /// the ours side of the merge. When merging a branch into the
        /// HEAD ours will point to HEAD
        /// </param>
        /// <param name="theirs">
        /// the theirs side of the merge. When merging a branch into the
        /// current HEAD theirs will point to the branch which is merged
        /// into HEAD.
        /// </param>
        /// <param name="index">the index entry</param>
        /// <param name="work">the file in the working tree</param>
        /// <returns>
        /// <code>false</code> if the merge will fail because the index entry
        /// didn't match ours or the working-dir file was dirty and a
        /// conflict occurred
        /// </returns>
        /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
        /// 	</exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
        /// 	</exception>
        /// <exception cref="NGit.Errors.CorruptObjectException">NGit.Errors.CorruptObjectException
        /// 	</exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        private bool ProcessEntry(CanonicalTreeParser @base, CanonicalTreeParser ours, CanonicalTreeParser
			 theirs, DirCacheBuildIterator index, WorkingTreeIterator work)
        {
            enterSubtree = true;
            int modeO = tw.GetRawMode(T_OURS);
            int modeT = tw.GetRawMode(T_THEIRS);
            int modeB = tw.GetRawMode(T_BASE);
            if (modeO == 0 && modeT == 0 && modeB == 0)
            {
                // File is either untracked or new, staged but uncommitted
                return true;
            }
            if (IsIndexDirty())
            {
                return false;
            }
            DirCacheEntry ourDce = null;
            if (index == null || index.GetDirCacheEntry() == null)
            {
                // create a fake DCE, but only if ours is valid. ours is kept only
                // in case it is valid, so a null ourDce is ok in all other cases.
                if (NonTree(modeO))
                {
                    ourDce = new DirCacheEntry(tw.RawPath);
                    ourDce.SetObjectId(tw.GetObjectId(T_OURS));
                    ourDce.FileMode = tw.GetFileMode(T_OURS);
                }
            }
            else
            {
                ourDce = index.GetDirCacheEntry();
            }
            if (NonTree(modeO) && NonTree(modeT) && tw.IdEqual(T_OURS, T_THEIRS))
            {
                // OURS and THEIRS have equal content. Check the file mode
                if (modeO == modeT)
                {
                    // content and mode of OURS and THEIRS are equal: it doesn't
                    // matter which one we choose. OURS is chosen. Since the index
                    // is clean (the index matches already OURS) we can keep the existing one
                    Keep(ourDce);
                    // no checkout needed!
                    return true;
                }
                else
                {
                    // same content but different mode on OURS and THEIRS.
                    // Try to merge the mode and report an error if this is
                    // not possible.
                    int newMode = MergeFileModes(modeB, modeO, modeT);
                    if (newMode != FileMode.MISSING.GetBits())
                    {
                        if (newMode == modeO)
                        {
                            // ours version is preferred
                            Keep(ourDce);
                        }
                        else
                        {
                            // the preferred version THEIRS has a different mode
                            // than ours. Check it out!
                            if (IsWorktreeDirty(work))
                            {
                                return false;
                            }
                            // we know about length and lastMod only after we have written the new content.
                            // This will happen later. Set these values to 0 for know.
                            DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_0, 0, 0);
                            toBeCheckedOut.Put(tw.PathString, e);
                        }
                        return true;
                    }
                    else
                    {
                        // FileModes are not mergeable. We found a conflict on modes.
                        // For conflicting entries we don't know lastModified and length.
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                        Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                        Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                        unmergedPaths.AddItem(tw.PathString);
                        mergeResults.Put(tw.PathString, new MergeResult<RawText>(Sharpen.Collections.EmptyList
                            <RawText>()).Upcast ());
                    }
                    return true;
                }
            }
            if (NonTree(modeO) && modeB == modeT && tw.IdEqual(T_BASE, T_THEIRS))
            {
                // THEIRS was not changed compared to BASE. All changes must be in
                // OURS. OURS is chosen. We can keep the existing entry.
                Keep(ourDce);
                // no checkout needed!
                return true;
            }
            if (modeB == modeO && tw.IdEqual(T_BASE, T_OURS))
            {
                // OURS was not changed compared to BASE. All changes must be in
                // THEIRS. THEIRS is chosen.
                // Check worktree before checking out THEIRS
                if (IsWorktreeDirty(work))
                {
                    return false;
                }
                if (NonTree(modeT))
                {
                    // we know about length and lastMod only after we have written
                    // the new content.
                    // This will happen later. Set these values to 0 for know.
                    DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_0, 0, 0);
                    if (e != null)
                    {
                        toBeCheckedOut.Put(tw.PathString, e);
                    }
                    return true;
                }
                else
                {
                    if (modeT == 0 && modeB != 0)
                    {
                        // we want THEIRS ... but THEIRS contains the deletion of the
                        // file
                        toBeDeleted.AddItem(tw.PathString);
                        return true;
                    }
                }
            }
            if (tw.IsSubtree)
            {
                // file/folder conflicts: here I want to detect only file/folder
                // conflict between ours and theirs. file/folder conflicts between
                // base/index/workingTree and something else are not relevant or
                // detected later
                if (NonTree(modeO) && !NonTree(modeT))
                {
                    if (NonTree(modeB))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                    }
                    Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                    unmergedPaths.AddItem(tw.PathString);
                    enterSubtree = false;
                    return true;
                }
                if (NonTree(modeT) && !NonTree(modeO))
                {
                    if (NonTree(modeB))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                    }
                    Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                    unmergedPaths.AddItem(tw.PathString);
                    enterSubtree = false;
                    return true;
                }
                // ours and theirs are both folders or both files (and treewalk
                // tells us we are in a subtree because of index or working-dir).
                // If they are both folders no content-merge is required - we can
                // return here.
                if (!NonTree(modeO))
                {
                    return true;
                }
            }
            // ours and theirs are both files, just fall out of the if block
            // and do the content merge
            if (NonTree(modeO) && NonTree(modeT))
            {
                // Check worktree before modifying files
                if (IsWorktreeDirty(work))
                {
                    return false;
                }
                MergeResult<RawText> result = ContentMerge(@base, ours, theirs);
                FilePath of = WriteMergedFile(result);
                UpdateIndex(@base, ours, theirs, result, of);
                if (result.ContainsConflicts())
                {
                    unmergedPaths.AddItem(tw.PathString);
                }
                modifiedFiles.AddItem(tw.PathString);
            }
            else
            {
                if (modeO != modeT)
                {
                    // OURS or THEIRS has been deleted
                    if (((modeO != 0 && !tw.IdEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw.IdEqual(T_BASE
                        , T_THEIRS))))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                        Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                        DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                        // OURS was deleted checkout THEIRS
                        if (modeO == 0)
                        {
                            // Check worktree before checking out THEIRS
                            if (IsWorktreeDirty(work))
                            {
                                return false;
                            }
                            if (NonTree(modeT))
                            {
                                if (e != null)
                                {
                                    toBeCheckedOut.Put(tw.PathString, e);
                                }
                            }
                        }
                        unmergedPaths.AddItem(tw.PathString);
                        // generate a MergeResult for the deleted file
                        mergeResults.Put(tw.PathString, ContentMerge(@base, ours, theirs).Upcast ());
                    }
                }
            }
            return true;
        }
Exemplo n.º 24
0
			public override void Apply(DirCacheEntry ent)
			{
				ent.FileMode = FileMode.GITLINK;
				ent.SetObjectId(id);
			}
Exemplo n.º 25
0
		protected internal virtual DirCacheEntry CreateEntry(string path, FileMode mode, 
			int stage, string content)
		{
			DirCacheEntry entry = new DirCacheEntry(path, stage);
			entry.FileMode = mode;
			entry.SetObjectId(new ObjectInserter.Formatter().IdFor(Constants.OBJ_BLOB, Constants
				.Encode(content)));
			return entry;
		}