Exemple #1
0
        /// <exception cref="System.IO.IOException"></exception>
        private DirCache CreateTemporaryIndex(ObjectId headId, DirCache index)
        {
            ObjectInserter inserter = null;
            // get DirCacheEditor to modify the index if required
            DirCacheEditor dcEditor = index.Editor();
            // get DirCacheBuilder for newly created in-core index to build a
            // temporary index for this commit
            DirCache        inCoreIndex = DirCache.NewInCore();
            DirCacheBuilder dcBuilder   = inCoreIndex.Builder();

            onlyProcessed = new bool[only.Count];
            bool     emptyCommit = true;
            TreeWalk treeWalk    = new TreeWalk(repo);
            int      dcIdx       = treeWalk.AddTree(new DirCacheIterator(index));
            int      fIdx        = treeWalk.AddTree(new FileTreeIterator(repo));
            int      hIdx        = -1;

            if (headId != null)
            {
                hIdx = treeWalk.AddTree(new RevWalk(repo).ParseTree(headId));
            }
            treeWalk.Recursive = true;
            while (treeWalk.Next())
            {
                string path = treeWalk.PathString;
                // check if current entry's path matches a specified path
                int pos = LookupOnly(path);
                CanonicalTreeParser hTree = null;
                if (hIdx != -1)
                {
                    hTree = treeWalk.GetTree <CanonicalTreeParser>(hIdx);
                }
                if (pos >= 0)
                {
                    // include entry in commit
                    DirCacheIterator dcTree = treeWalk.GetTree <DirCacheIterator>(dcIdx);
                    FileTreeIterator fTree  = treeWalk.GetTree <FileTreeIterator>(fIdx);
                    // check if entry refers to a tracked file
                    bool tracked = dcTree != null || hTree != null;
                    if (!tracked)
                    {
                        break;
                    }
                    if (fTree != null)
                    {
                        // create a new DirCacheEntry with data retrieved from disk
                        DirCacheEntry dcEntry     = new DirCacheEntry(path);
                        long          entryLength = fTree.GetEntryLength();
                        dcEntry.SetLength(entryLength);
                        dcEntry.LastModified = fTree.GetEntryLastModified();
                        dcEntry.FileMode     = fTree.GetIndexFileMode(dcTree);
                        bool objectExists = (dcTree != null && fTree.IdEqual(dcTree)) || (hTree != null &&
                                                                                          fTree.IdEqual(hTree));
                        if (objectExists)
                        {
                            dcEntry.SetObjectId(fTree.EntryObjectId);
                        }
                        else
                        {
                            if (FileMode.GITLINK.Equals(dcEntry.FileMode))
                            {
                                dcEntry.SetObjectId(fTree.EntryObjectId);
                            }
                            else
                            {
                                // insert object
                                if (inserter == null)
                                {
                                    inserter = repo.NewObjectInserter();
                                }
                                long        contentLength = fTree.GetEntryContentLength();
                                InputStream inputStream   = fTree.OpenEntryStream();
                                try
                                {
                                    dcEntry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentLength, inputStream
                                                                        ));
                                }
                                finally
                                {
                                    inputStream.Close();
                                }
                            }
                        }
                        // update index
                        dcEditor.Add(new _PathEdit_375(dcEntry, path));
                        // add to temporary in-core index
                        dcBuilder.Add(dcEntry);
                        if (emptyCommit && (hTree == null || !hTree.IdEqual(fTree) || hTree.EntryRawMode
                                            != fTree.EntryRawMode))
                        {
                            // this is a change
                            emptyCommit = false;
                        }
                    }
                    else
                    {
                        // if no file exists on disk, remove entry from index and
                        // don't add it to temporary in-core index
                        dcEditor.Add(new DirCacheEditor.DeletePath(path));
                        if (emptyCommit && hTree != null)
                        {
                            // this is a change
                            emptyCommit = false;
                        }
                    }
                    // keep track of processed path
                    onlyProcessed[pos] = true;
                }
                else
                {
                    // add entries from HEAD for all other paths
                    if (hTree != null)
                    {
                        // create a new DirCacheEntry with data retrieved from HEAD
                        DirCacheEntry dcEntry = new DirCacheEntry(path);
                        dcEntry.SetObjectId(hTree.EntryObjectId);
                        dcEntry.FileMode = hTree.EntryFileMode;
                        // add to temporary in-core index
                        dcBuilder.Add(dcEntry);
                    }
                }
            }
            // there must be no unprocessed paths left at this point; otherwise an
            // untracked or unknown path has been specified
            for (int i = 0; i < onlyProcessed.Length; i++)
            {
                if (!onlyProcessed[i])
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().entryNotFoundByPath
                                                                         , only[i]));
                }
            }
            // there must be at least one change
            if (emptyCommit)
            {
                throw new JGitInternalException(JGitText.Get().emptyCommit);
            }
            // update index
            dcEditor.Commit();
            // finish temporary in-core index used for this commit
            dcBuilder.Finish();
            return(inCoreIndex);
        }
Exemple #2
0
 /// <summary>
 /// Processing an entry in the context of
 /// <see cref="PrescanOneTree()">PrescanOneTree()</see>
 /// when only
 /// one tree is given
 /// </summary>
 /// <param name="m">the tree to merge</param>
 /// <param name="i">the index</param>
 /// <param name="f">the working tree</param>
 /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 internal virtual void ProcessEntry(CanonicalTreeParser m, DirCacheBuildIterator i
                                    , WorkingTreeIterator f)
 {
     if (m != null)
     {
         // There is an entry in the merge commit. Means: we want to update
         // what's currently in the index and working-tree to that one
         if (i == null)
         {
             // The index entry is missing
             if (f != null && !FileMode.TREE.Equals(f.EntryFileMode) && !f.IsEntryIgnored())
             {
                 // don't overwrite an untracked and not ignored file
                 conflicts.AddItem(walk.PathString);
             }
             else
             {
                 Update(m.EntryPathString, m.EntryObjectId, m.EntryFileMode);
             }
         }
         else
         {
             if (f == null || !m.IdEqual(i))
             {
                 // The working tree file is missing or the merge content differs
                 // from index content
                 Update(m.EntryPathString, m.EntryObjectId, m.EntryFileMode);
             }
             else
             {
                 if (i.GetDirCacheEntry() != null)
                 {
                     // The index contains a file (and not a folder)
                     if (f.IsModified(i.GetDirCacheEntry(), true) || i.GetDirCacheEntry().Stage != 0)
                     {
                         // The working tree file is dirty or the index contains a
                         // conflict
                         Update(m.EntryPathString, m.EntryObjectId, m.EntryFileMode);
                     }
                     else
                     {
                         Keep(i.GetDirCacheEntry());
                     }
                 }
                 else
                 {
                     // The index contains a folder
                     Keep(i.GetDirCacheEntry());
                 }
             }
         }
     }
     else
     {
         // There is no entry in the merge commit. Means: we want to delete
         // what's currently in the index and working tree
         if (f != null)
         {
             // There is a file/folder for that path in the working tree
             if (walk.IsDirectoryFileConflict())
             {
                 conflicts.AddItem(walk.PathString);
             }
             else
             {
                 // No file/folder conflict exists. All entries are files or
                 // all entries are folders
                 if (i != null)
                 {
                     // ... and the working tree contained a file or folder
                     // -> add it to the removed set and remove it from
                     // conflicts set
                     Remove(i.EntryPathString);
                     conflicts.Remove(i.EntryPathString);
                 }
             }
         }
         else
         {
             // untracked file, neither contained in tree to merge
             // nor in index
             // There is no file/folder for that path in the working tree.
             // The only entry we have is the index entry. If that entry is a
             // conflict simply remove it. Otherwise keep that entry in the
             // index
             if (i.GetDirCacheEntry().Stage == 0)
             {
                 Keep(i.GetDirCacheEntry());
             }
         }
     }
 }