A representation of a Git tree entry. A Tree is a directory in Git.
Inheritance: TreeEntry, Treeish
Beispiel #1
0
        private void UpdateSingleFile(string file)
        {
            TreeEntry treeEntry = null;
            var       commit    = Repository.Head.CurrentCommit;

            _tree = commit != null ? commit.Tree : null;
            if (_tree != null)
            {
                treeEntry = _tree.FindBlobMember(file);
            }

            _index = Repository.Index.GitIndex;
            _index.RereadIfNecessary();
            GitIndex.Entry indexEntry = _index.GetEntry(file);

            TreeEntry wdirEntry = null;
            FileInfo  fileInfo  = new FileInfo(Path.Combine(Repository.WorkingDirectory, file.Replace('/', Path.DirectorySeparatorChar)));

            if (fileInfo.Exists && !IgnoreHandler.IsIgnored(file))
            {
                var tree = new Core.Tree(Repository._internal_repo);
                wdirEntry = tree.AddFile(file);
            }

            OnVisitEntry(treeEntry, wdirEntry, indexEntry, fileInfo);
        }
        ObjectId SaveTree(GitSharp.Core.Tree tree, HashSet <GitSharp.Core.Tree> modifiedTrees)
        {
            // Saves tree that have been modified (that is, which are in the provided list or
            // which have child trees that have been modified)

            bool childModified = false;

            foreach (var te in tree.Members)
            {
                GitSharp.Core.Tree childTree = te as GitSharp.Core.Tree;
                if (childTree != null)
                {
                    ObjectId newId = SaveTree(childTree, modifiedTrees);
                    if (newId != null)
                    {
                        childTree.Id  = newId;
                        childModified = true;
                    }
                }
            }
            if (childModified || modifiedTrees.Contains(tree))
            {
                ObjectWriter writer = new ObjectWriter(_internal_repo);
                return(writer.WriteTree(tree));
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        private void doCheckout(GitSharp.Core.Ref branch)
        {
            if (branch == null)
            {
                throw new ArgumentNullException("branch", "Cannot checkout; no HEAD advertised by remote");
            }
            var repo = Repository._internal_repo;

            if (!Constants.HEAD.Equals(branch.getName()))
            {
                RefUpdate u1 = repo.UpdateRef(Constants.HEAD);
                u1.disableRefLog();
                u1.link(branch.getName());
            }

            GitSharp.Core.Commit commit = repo.MapCommit(branch.ObjectId);
            RefUpdate            u      = repo.UpdateRef(Constants.HEAD);

            u.NewObjectId = commit.CommitId;
            u.forceUpdate();
            GitIndex index = new GitIndex(repo);

            GitSharp.Core.Tree tree = commit.TreeEntry;
            WorkDirCheckout    co   = new WorkDirCheckout(repo, repo.WorkingDirectory, index, tree);

            co.checkout();
            index.write();
        }
Beispiel #4
0
 ///	<summary>
 /// Create a checkout class for checking out one tree, merging with the index
 ///	</summary>
 ///	<param name="repo"> </param>
 ///	<param name="root"> workdir </param>
 ///	<param name="index"> current index </param>
 ///	<param name="merge"> tree to check out </param>
 public WorkDirCheckout(Repository repo, DirectoryInfo root, GitIndex index, Tree merge)
     : this()
 {
     this._repo = repo;
     this._root = root;
     this._index = index;
     this._merge = merge;
 }
 public void testEmpty()
 {
     Tree tree = new Tree(db);
     TreeIterator i = makeIterator(tree);
     Assert.IsTrue(i.hasNext());
     Assert.AreEqual("", i.next().FullName);
     Assert.IsFalse(i.hasNext());
 }
Beispiel #6
0
        ObjectId WriteWorkingDirectoryTree(Core.Tree headTree, GitIndex index)
        {
            var writer = new ObjectWriter(_repo._internal_repo);
            var tree   = new Core.Tree(_repo._internal_repo);

            WriteTree(writer, headTree, index, tree, _repo._internal_repo.WorkingDirectory);
            return(writer.WriteTree(tree));
        }
Beispiel #7
0
 internal WorkDirCheckout(Repository repo, DirectoryInfo workDir, GitIndex oldIndex, GitIndex newIndex)
     : this()
 {
     _repo = repo;
     _root = workDir;
     _index = oldIndex;
     _merge = repo.MapTree(newIndex.writeTree());
 }
 public void StartVisitTree(Tree t)
 {
     stack.Push(currentDirectory);
     if (!t.IsRoot)
     {
         currentDirectory = new DirectoryInfo(Path.Combine(currentDirectory.FullName, t.Name));
     }
 }
 public void testSimpleF1()
 {
     Tree tree = new Tree(db);
     tree.AddFile("x");
     TreeIterator i = MakeIterator(tree);
     Assert.IsTrue(i.hasNext());
     Assert.AreEqual("x", i.next().Name);
 }
 void IndexTreeVisitor.FinishVisitTree(Tree tree, Tree auxTree, string curDir)
 {
     FinishVisitTreeDelegate handler = FinishVisitTree;
     if (handler != null)
     {
         handler(tree, auxTree, curDir);
     }
 }
Beispiel #11
0
 public IndexTreeWalker(GitIndex index, Tree mainTree, Tree newTree, FileSystemInfo root,
                        IndexTreeVisitor visitor)
 {
     _mainTree = mainTree;
     _newTree = newTree;
     _root = root;
     _visitor = visitor;
     _threeTrees = newTree != null;
     _indexMembers = index.Members;
 }
Beispiel #12
0
        public IndexDiff(Tree tree, GitIndex index)
        {
            _anyChanges = false;
            _tree = tree;
            _index = index;

            Added = new HashSet<string>();
            Changed = new HashSet<string>();
            Removed = new HashSet<string>();
            Missing = new HashSet<string>();
            Modified = new HashSet<string>();
        }
Beispiel #13
0
        /// <summary>
        /// Run the diff operation. Until this is called, all lists will be empty
        /// </summary>
        /// <returns>true if anything is different between index, tree, and workdir</returns>
        private void UpdateDirectoryRecursive(string path)
        {
            var commit = Repository.Head.CurrentCommit;

            _tree  = (commit != null ? commit.Tree : new Core.Tree(Repository));
            _index = Repository.Index.GitIndex;
            _index.RereadIfNecessary();
            DirectoryInfo root    = _index.Repository.WorkingDirectory;
            var           visitor = new AbstractIndexTreeVisitor {
                VisitEntryAux = OnVisitEntry
            };

            new IndexTreeWalker(_index, _tree, CreateWorkingDirectoryTree(path), root, visitor).Walk();
        }
Beispiel #14
0
        public void testAdded2()
        {
            var index = new GitIndex(db);
            writeTrashFile("test/für henon.txt", "Weißebier");
            var tree = new Tree(db);

            index.add(trash, new FileInfo(Path.Combine(trash.FullName, "test/für henon.txt")));
            var diff = new IndexDiff(tree, index);
            diff.Diff();

            Assert.AreEqual(1, diff.Added.Count);
            Assert.IsTrue(diff.Added.Contains("test/für henon.txt"));
            Assert.AreEqual(0, diff.Changed.Count);
            Assert.AreEqual(0, diff.Modified.Count);
            Assert.AreEqual(0, diff.Removed.Count);
        }
Beispiel #15
0
        public void testAdded()
        {
            var index = new GitIndex(db);
            writeTrashFile("file1", "file1");
            writeTrashFile("dir/subfile", "dir/subfile");
            var tree = new Tree(db);

            index.add(trash, new FileInfo(Path.Combine(trash.FullName, "file1")));
            index.add(trash, new FileInfo(Path.Combine(trash.FullName, "dir/subfile")));
            var diff = new IndexDiff(tree, index);
            diff.Diff();

            Assert.AreEqual(2, diff.Added.Count);
            Assert.IsTrue(diff.Added.Contains("file1"));
            Assert.IsTrue(diff.Added.Contains("dir/subfile"));
            Assert.AreEqual(0, diff.Changed.Count);
            Assert.AreEqual(0, diff.Modified.Count);
            Assert.AreEqual(0, diff.Removed.Count);
        }
Beispiel #16
0
        private GitSharp.Core.Tree CreateWorkingDirectoryTree(string subdir)
        {
            var mainTree = new Core.Tree(Repository._internal_repo);
            var tree     = mainTree;

            // Create the subdir branch
            foreach (string sdir in subdir.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries))
            {
                tree = tree.AddTree(sdir);
            }

            DirectoryInfo root = new DirectoryInfo(Repository.FromGitPath(subdir));

            if (root.Exists)
            {
                FillTree(root, tree);
            }
            return(mainTree);
        }
Beispiel #17
0
 private void FillTree(DirectoryInfo dir, Core.Tree tree)
 {
     foreach (var subdir in dir.GetDirectories())
     {
         if (subdir.Name == Constants.DOT_GIT || IgnoreHandler.IsIgnored(tree.FullName + "/" + subdir.Name))
         {
             continue;
         }
         var t = tree.AddTree(subdir.Name);
         FillTree(subdir, t);
     }
     foreach (var file in dir.GetFiles())
     {
         if (IgnoreHandler.IsIgnored(tree.FullName + "/" + file.Name))
         {
             continue;
         }
         tree.AddFile((file.Name));
     }
 }
Beispiel #18
0
        private void Checkout(string working_directory)         // [henon] made this private to not confuse with Checkout( paths ). It seems to be not a common use case anyway and could be better exposed via the CheckoutCommand
        {
            if (InternalCommit == null)
            {
                throw new InvalidOperationException("Unable to checkout this commit. It was not initialized properly (i.e. the hash is not pointing to a commit object).");
            }
            if (working_directory == null)
            {
                throw new ArgumentException("Path to checkout directory must not be null");
            }
            if (new DirectoryInfo(working_directory).Exists == false)
            {
                throw new IOException("Cannot checkout into non-existent directory: " + working_directory);
            }
            var db    = _repo._internal_repo;
            var index = _repo.Index.GitIndex;

            index.RereadIfNecessary();
            CoreTree tree = InternalCommit.TreeEntry;
            var      co   = new GitSharp.Core.WorkDirCheckout(db, new DirectoryInfo(working_directory), index, tree);

            co.checkout();
        }
        public void CanAddAFileToAMSysGitIndexWhereAFileIsAlreadyWaitingToBeCommitted()
        {
            //setup of .git directory
            var resource =
                new DirectoryInfo(Path.Combine(Path.Combine(Environment.CurrentDirectory, "Resources"),
                                               "CorruptIndex"));
            var tempRepository =
                new DirectoryInfo(Path.Combine(trash.FullName, "CorruptIndex" + Path.GetRandomFileName()));
            CopyDirectory(resource.FullName, tempRepository.FullName);

            var repositoryPath = new DirectoryInfo(Path.Combine(tempRepository.FullName, ".git"));
            Directory.Move(repositoryPath.FullName + "ted", repositoryPath.FullName);

            var repository = new Repository(repositoryPath);
            GitIndex index = repository.Index;

            Assert.IsNotNull(index);

            writeTrashFile(Path.Combine(repository.WorkingDirectory.FullName, "c.txt"), "c");

            var tree = new Tree(repository);

            index.add(repository.WorkingDirectory, new FileInfo(Path.Combine(repository.WorkingDirectory.FullName, "c.txt")));

            var diff = new IndexDiff(tree, index);
            diff.Diff();

            index.write();

            Assert.AreEqual(3, diff.Added.Count);
            Assert.IsTrue(diff.Added.Contains("a.txt"));
            Assert.IsTrue(diff.Added.Contains("b.txt"));
            Assert.IsTrue(diff.Added.Contains("c.txt"));
            Assert.AreEqual(0, diff.Changed.Count);
            Assert.AreEqual(0, diff.Modified.Count);
            Assert.AreEqual(0, diff.Removed.Count);
        }
Beispiel #20
0
 void WriteTree(ObjectWriter writer, Core.Tree headTree, GitIndex index, Core.Tree tree, DirectoryInfo dir)
 {
     foreach (var fsi in dir.GetFileSystemInfos())
     {
         if (fsi is FileInfo)
         {
             // Exclude untracked files
             string gname   = _repo.ToGitPath(fsi.FullName);
             bool   inIndex = index.GetEntry(gname) != null;
             bool   inHead  = headTree.FindBlobMember(gname) != null;
             if (inIndex || inHead)
             {
                 var entry = tree.AddFile(fsi.Name);
                 entry.Id = writer.WriteBlob((FileInfo)fsi);
             }
         }
         else if (fsi.Name != Constants.DOT_GIT)
         {
             var child = tree.AddTree(fsi.Name);
             WriteTree(writer, headTree, index, child, (DirectoryInfo)fsi);
             child.Id = writer.WriteTree(child);
         }
     }
 }
Beispiel #21
0
        private static bool HasParentBlob(Tree t, string name)
        {
            if (name.IndexOf('/') == -1)
            {
                return false;
            }

            string parent = name.Slice(0, name.LastIndexOf('/'));
            return t.FindBlobMember(parent) != null || HasParentBlob(t, parent);
        }
        public void Refresh()
        {
            cache.Clear();
            if (!string.IsNullOrEmpty(initFolder))
            {
                try
                {
                    this.repository = Repository.Open(initFolder);

                    if (this.repository != null)
                    {
                        var id = repository.Resolve("HEAD");
                        var commit = repository.MapCommit(id);
                        this.commitTree = (commit != null ? commit.TreeEntry : new Tree(repository));
                        this.index = repository.Index;
                        this.index.RereadIfNecessary();
                        //this.ignoreHandler = new IgnoreHandler(repository);
                        //this.watcher = new FileSystemWatcher(this.repository.WorkingDirectory.FullName);
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
Beispiel #23
0
 internal Tree(Repository repo, CoreTree tree)
     : base(repo, tree.Id)
 {
     _internal_tree = tree;
 }
Beispiel #24
0
		/// <summary>
		/// Adds a new or existing file with the specified name to this tree.
		///	Trees are added if necessary as the name may contain '/':s.
		///	</summary>
		///	<param name="s"> an array containing the name </param>
		///	<param name="offset"> when the name starts in the tree.
		///	</param>
		///	<returns>A <seealso cref="FileTreeEntry"/> for the added file.</returns>
		///	<exception cref="IOException"></exception>
		public FileTreeEntry AddFile(byte[] s, int offset)
		{
			int slash;

			for (slash = offset; slash < s.Length && s[slash] != '/'; slash++)
			{
				// search for path component terminator
				// [henon] body is empty by intention!
			}

			EnsureLoaded();
            byte xlast = slash < s.Length ? (byte)'/' : (byte)0;
			int p = BinarySearch(_contents, s, xlast, offset, slash);
			if (p >= 0 && slash < s.Length && _contents[p] is Tree)
			{
				return ((Tree)_contents[p]).AddFile(s, slash + 1);
			}

			byte[] newName = SubString(s, offset, slash);
			if (p >= 0)
			{
				throw new EntryExistsException(RawParseUtils.decode(newName));
			}

			if (slash < s.Length)
			{
                Tree t = new Tree(this, newName);
				InsertEntry(p, t);
				return t.AddFile(s, slash + 1);
			}

            FileTreeEntry f = new FileTreeEntry(this, null, newName, false);
			InsertEntry(p, f);
			return f;
		}
Beispiel #25
0
		///	<summary>
		/// Construct a new Tree under another Tree
		/// </summary>
		/// <param name="parent"></param>
		/// <param name="nameUTF8"></param>
		public Tree(Tree parent, byte[] nameUTF8)
			: base(parent, null, nameUTF8)
		{
			_db = parent.Repository;
			_contents = EmptyTree;
		}
Beispiel #26
0
 ///	<summary>
 /// Create a checkout class for merging and checking our two trees and the index.
 ///	</summary>
 ///	<param name="repo"> </param>
 ///	<param name="root"> workdir </param>
 ///	<param name="head"> </param>
 ///	<param name="index"> </param>
 ///	<param name="merge"> </param>
 public WorkDirCheckout(Repository repo, DirectoryInfo root, Core.Tree head, GitIndex index, Core.Tree merge)
     : this(repo, root, index, merge)
 {
     this._head = head;
 }
Beispiel #27
0
        public void Write_Tree()
        {
            var t = new Tree(db);
            FileTreeEntry f = t.AddFile("i-am-a-file");
            writeTrashFile(f.Name, "and this is the data in me\r\n\r\n");
            Assert.AreEqual(File.ReadAllText("Resources/single_file_commit/i-am-a-file"), File.ReadAllText(trash + "/i-am-a-file"));
            t.Accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
            var id = t.Id;

            var b1 = new BinaryReader(new Inspector(db).ContentStream(id));
            b1.BaseStream.Position = b1.BaseStream.Length - 21;

            var b2 = new BinaryReader(Inspector.ContentStream("Resources/single_file_commit", "917c130bd4fa5bf2df0c399dc1b03401860aa448"));
            b2.BaseStream.Position = b2.BaseStream.Length - 21;
            Assert.AreEqual(b2.ReadByte(), b1.ReadByte());

            var git_w1=b2.ReadInt32();
            var git_w2=b2.ReadInt32();
            var git_w3 = b2.ReadInt32();
            var git_w4 = b2.ReadInt32();
            var git_w5 = b2.ReadInt32();
            b2.BaseStream.Position = b2.BaseStream.Length-20;
            var git_id = ObjectId.FromRaw(b2.ReadBytes(20));
            var w1 = b1.ReadInt32();
            var w2= b1.ReadInt32();
            b1.Close();
            b2.Close();

            Assert.AreEqual(git_w1,w1);
            Assert.AreEqual(git_w2, w2);

            Assert.AreEqual("917c130bd4fa5bf2df0c399dc1b03401860aa448", id.ToString());
            var s_git = Inspector.Inspect("Resources/single_file_commit", "917c130bd4fa5bf2df0c399dc1b03401860aa448");
            var s = new Inspector(db).Inspect(id);
            Assert.AreEqual(s_git, s);
        }
Beispiel #28
0
        public void Write_Simple_Commit()
        {
            var t = new Tree(db);
            FileTreeEntry f = t.AddFile("i-am-a-file");
            writeTrashFile(f.Name, "and this is the data in me\r\n\r\n");
            t.Accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
            //new ObjectChecker().checkBlob(Constants.CHARSET.GetString(db.OpenObject(t.TreeId).getBytes()).ToCharArray());

            string s = new Inspector(db).Inspect(t.Id);
            string s1 = Inspector.Inspect("Resources/single_file_commit", "16c0beaf7523eb3ef5df45bd42dd4fc6343de864");
            string s2 = Inspector.Inspect("Resources/single_file_commit", "917c130bd4fa5bf2df0c399dc1b03401860aa448");
            string s3 = Inspector.Inspect("Resources/single_file_commit", "95ea6a6859af6791464bd8b6de76ad5a6f9fad81");

            //tree 917c130bd4fa5bf2df0c399dc1b03401860aa448\nauthor henon <*****@*****.**> 1245946742 +0200\ncommitter henon <*****@*****.**> 1245946742 +0200\n\nA Commit\n"

            Assert.AreEqual(ObjectId.FromString("917c130bd4fa5bf2df0c399dc1b03401860aa448"), t.Id);

            var c = new Commit(db)
                        {
                            Author = (new PersonIdent("henon", "*****@*****.**", 1245946742000L, 2*60)),
                            Committer = (new PersonIdent("henon", "*****@*****.**", 1245946742000L, 2*60)),
                            Message = ("A Commit\n"),
                            TreeEntry = (t)
                        };
            Assert.AreEqual(t.TreeId, c.TreeId);
            c.Save();

            string s_c = new Inspector(db).Inspect(c.CommitId);
            ObjectId cmtid = ObjectId.FromString("16c0beaf7523eb3ef5df45bd42dd4fc6343de864");
            Assert.AreEqual(cmtid, c.CommitId);

            // Verify the commit we just wrote is in the correct format.
            //using (var xis = new XInputStream(new FileStream(db.ToFile(cmtid).FullName, System.IO.FileMode.Open, FileAccess.Read)))
            //{
            //    Assert.AreEqual(0x78, xis.ReadUInt8());
            //    Assert.AreEqual(0x9c, xis.ReadUInt8());
            //    Assert.IsTrue(0x789c % 31 == 0);
            //}

            // Verify we can Read it.
            Commit c2 = db.MapCommit(cmtid.ToString());
            Assert.IsNotNull(c2);
            Assert.AreEqual(c.Message, c2.Message);
            Assert.AreEqual(c.TreeId, c2.TreeId);
            Assert.AreEqual(c.Author, c2.Author);
            Assert.AreEqual(c.Committer, c2.Committer);
        }
Beispiel #29
0
        public void testTwoSuccessiveCommitsLinkedToHead()
        {
            var repo = createNewEmptyRepo();
            var workingDirectory = repo.WorkingDirectory;
            repo.Create();

            var objectWriter = new ObjectWriter(repo);

            FileInfo project1_a_txt = writeTrashFile(Path.Combine(workingDirectory.FullName, "Project-1/A.txt"), "A.txt - first version\n");
            FileInfo project1_b_txt = writeTrashFile(Path.Combine(workingDirectory.FullName, "Project-1/B.txt"), "B.txt - first version\n");

            var tree = new Tree(repo);
            Tree projectTree = tree.AddTree("Project-1");
            addFile(projectTree, project1_a_txt, objectWriter);
            projectTree.Id = (objectWriter.WriteTree(projectTree));
            addFile(projectTree, project1_b_txt, objectWriter);
            projectTree.Id = (objectWriter.WriteTree(projectTree));
            tree.Id = (objectWriter.WriteTree(tree));

            var commit = new Commit(repo)
            {
                Author = new PersonIdent(jauthor, (0L), 60),
                Committer = new PersonIdent(jcommitter, (0L), 60),
                Message = "Foo\n\nMessage",
                TreeEntry = tree
            };
            commit.Save();
            var commitId = commit.CommitId;

            FileInfo project1_b_v2_txt = writeTrashFile(Path.Combine(workingDirectory.FullName, "Project-1/B.txt"), "B.txt - second version\n");

            tree = new Tree(repo);
            projectTree = tree.AddTree("Project-1");
            addFile(projectTree, project1_a_txt, objectWriter);
            projectTree.Id = (objectWriter.WriteTree(projectTree));
            addFile(projectTree, project1_b_v2_txt, objectWriter);
            projectTree.Id = (objectWriter.WriteTree(projectTree));
            tree.Id = (objectWriter.WriteTree(tree));

            commit = new Commit(repo)
            {
                Author = new PersonIdent(jauthor, (0L), 60),
                Committer = new PersonIdent(jcommitter, (0L), 60),
                Message = "Modified",
                ParentIds = new[] { commitId },
                TreeEntry = tree
            };
            commit.Save();
            commitId = commit.CommitId;

            RefUpdate lck = repo.UpdateRef("refs/heads/master");
            Assert.IsNotNull(lck, "obtained lock");
            lck.NewObjectId = commitId;
            Assert.AreEqual(RefUpdate.RefUpdateResult.New, lck.ForceUpdate());
        }
Beispiel #30
0
        public void test026_CreateCommitMultipleparents()
        {
            db.Config.load();

            var t = new Tree(db);
            FileTreeEntry f = t.AddFile("i-am-a-file");
            writeTrashFile(f.Name, "and this is the data in me\n");
            t.Accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
            Assert.AreEqual(ObjectId.FromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
                    t.TreeId);

            var c1 = new Commit(db)
                     	{
                     		Author = new PersonIdent(jauthor, 1154236443000L, -4*60),
                     		Committer = new PersonIdent(jcommitter, 1154236443000L, -4*60),
                     		Message = "A Commit\n",
                     		TreeEntry = t
                     	};

            Assert.AreEqual(t.TreeId, c1.TreeId);
            c1.Save();
            ObjectId cmtid1 = ObjectId.FromString("803aec4aba175e8ab1d666873c984c0308179099");
            Assert.AreEqual(cmtid1, c1.CommitId);

            var c2 = new Commit(db)
                     	{
                     		Author = new PersonIdent(jauthor, 1154236443000L, -4*60),
                     		Committer = new PersonIdent(jcommitter, 1154236443000L, -4*60),
                     		Message = "A Commit 2\n",
                     		TreeEntry = t
                     	};

            Assert.AreEqual(t.TreeId, c2.TreeId);
            c2.ParentIds = new[] { c1.CommitId };
            c2.Save();
            ObjectId cmtid2 = ObjectId.FromString("95d068687c91c5c044fb8c77c5154d5247901553");
            Assert.AreEqual(cmtid2, c2.CommitId);

            Commit rm2 = db.MapCommit(cmtid2);
            Assert.AreNotSame(c2, rm2); // assert the parsed objects is not from the cache
            Assert.AreEqual(c2.Author, rm2.Author);
            Assert.AreEqual(c2.CommitId, rm2.CommitId);
            Assert.AreEqual(c2.Message, rm2.Message);
            Assert.AreEqual(c2.TreeEntry.TreeId, rm2.TreeEntry.TreeId);
            Assert.AreEqual(1, rm2.ParentIds.Length);
            Assert.AreEqual(c1.CommitId, rm2.ParentIds[0]);

            var c3 = new Commit(db)
                     	{
                     		Author = new PersonIdent(jauthor, 1154236443000L, -4*60),
                     		Committer = new PersonIdent(jcommitter, 1154236443000L, -4*60),
                     		Message = "A Commit 3\n",
                     		TreeEntry = t
                     	};

            Assert.AreEqual(t.TreeId, c3.TreeId);
            c3.ParentIds = new[] { c1.CommitId, c2.CommitId };
            c3.Save();
            ObjectId cmtid3 = ObjectId.FromString("ce6e1ce48fbeeb15a83f628dc8dc2debefa066f4");
            Assert.AreEqual(cmtid3, c3.CommitId);

            Commit rm3 = db.MapCommit(cmtid3);
            Assert.AreNotSame(c3, rm3); // assert the parsed objects is not from the cache
            Assert.AreEqual(c3.Author, rm3.Author);
            Assert.AreEqual(c3.CommitId, rm3.CommitId);
            Assert.AreEqual(c3.Message, rm3.Message);
            Assert.AreEqual(c3.TreeEntry.TreeId, rm3.TreeEntry.TreeId);
            Assert.AreEqual(2, rm3.ParentIds.Length);
            Assert.AreEqual(c1.CommitId, rm3.ParentIds[0]);
            Assert.AreEqual(c2.CommitId, rm3.ParentIds[1]);

            var c4 = new Commit(db)
                     	{
                     		Author = new PersonIdent(jauthor, 1154236443000L, -4*60),
                     		Committer = new PersonIdent(jcommitter, 1154236443000L, -4*60),
                     		Message = "A Commit 4\n",
                     		TreeEntry = t
                     	};

            Assert.AreEqual(t.TreeId, c3.TreeId);
            c4.ParentIds = new[] { c1.CommitId, c2.CommitId, c3.CommitId };
            c4.Save();
            ObjectId cmtid4 = ObjectId.FromString("d1fca9fe3fef54e5212eb67902c8ed3e79736e27");
            Assert.AreEqual(cmtid4, c4.CommitId);

            Commit rm4 = db.MapCommit(cmtid4);
            Assert.AreNotSame(c4, rm3); // assert the parsed objects is not from the cache
            Assert.AreEqual(c4.Author, rm4.Author);
            Assert.AreEqual(c4.CommitId, rm4.CommitId);
            Assert.AreEqual(c4.Message, rm4.Message);
            Assert.AreEqual(c4.TreeEntry.TreeId, rm4.TreeEntry.TreeId);
            Assert.AreEqual(3, rm4.ParentIds.Length);
            Assert.AreEqual(c1.CommitId, rm4.ParentIds[0]);
            Assert.AreEqual(c2.CommitId, rm4.ParentIds[1]);
            Assert.AreEqual(c3.CommitId, rm4.ParentIds[2]);
        }
Beispiel #31
0
 ///	<summary>
 /// Create a checkout class for merging and checking our two trees and the index.
 ///	</summary>
 ///	<param name="repo"> </param>
 ///	<param name="root"> workdir </param>
 ///	<param name="head"> </param>
 ///	<param name="index"> </param>
 ///	<param name="merge"> </param>
 public WorkDirCheckout(Repository repo, DirectoryInfo root, Core.Tree head, GitIndex index, Core.Tree merge)
     : this(repo, root, index, merge)
 {
     this._head = head;
 }
Beispiel #32
0
		private void ReadTree(byte[] raw)
		{
			int rawSize = raw.Length;
			int rawPtr = 0;
			int nextIndex = 0;

			while (rawPtr < rawSize)
			{
				while (rawPtr < rawSize && raw[rawPtr] != 0)
				{
					rawPtr++;
				}

				rawPtr++;
				rawPtr += Constants.OBJECT_ID_LENGTH;
				nextIndex++;
			}

			var temp = new TreeEntry[nextIndex];
			rawPtr = 0;
			nextIndex = 0;

			while (rawPtr < rawSize)
			{
				int c = raw[rawPtr++];
				if (c < '0' || c > '7')
				{
					throw new CorruptObjectException(Id, "invalid entry mode");
				}

				int mode = c - '0';

				while (true)
				{
					c = raw[rawPtr++];
					if (' ' == c) break;

					if (c < '0' || c > '7')
					{
						throw new CorruptObjectException(Id, "invalid mode");
					}

					mode <<= 3;
					mode += c - '0';
				}

				int nameLen = 0;
				while (raw[rawPtr + nameLen] != 0)
				{
					nameLen++;
				}

				var name = new byte[nameLen];
				Array.Copy(raw, rawPtr, name, 0, nameLen);
				rawPtr += nameLen + 1;

				ObjectId id = ObjectId.FromRaw(raw, rawPtr);
				rawPtr += Constants.OBJECT_ID_LENGTH;

				TreeEntry ent;
				if (FileMode.RegularFile.Equals(mode))
				{
					ent = new FileTreeEntry(this, id, name, false);
				}
				else if (FileMode.ExecutableFile.Equals(mode))
				{
					ent = new FileTreeEntry(this, id, name, true);
				}
				else if (FileMode.Tree.Equals(mode))
				{
					ent = new Tree(this, id, name);
				}
                else if (FileMode.Symlink.Equals(mode))
                {
                    ent = new SymlinkTreeEntry(this, id, name);
                }
                else if (FileMode.GitLink.Equals(mode))
                {
                    ent = new GitLinkTreeEntry(this, id, name);
                }
				else
				{
					throw new CorruptObjectException(Id, "Invalid mode: " + Convert.ToString(mode, 8));
				}

				temp[nextIndex++] = ent;
			}

			_contents = temp;
		}
Beispiel #33
0
        /// <summary>
        /// Commit changes in the specified files and update HEAD
        /// </summary>
        /// <param name='message'>The commit message</param>
        /// <param name="author">The author of the content to be committed</param>
        /// <param name="paths">List of files to commit</param>
        /// <returns>Returns the newly created commit</returns>
        public Commit Commit(string message, Author author, params string[] paths)
        {
            if (string.IsNullOrEmpty(message))
            {
                throw new ArgumentException("Commit message must not be null or empty!", "message");
            }
            if (string.IsNullOrEmpty(author.Name))
            {
                throw new ArgumentException("Author name must not be null or empty!", "author");
            }

            int basePathLength = Path.GetFullPath(WorkingDirectory).TrimEnd('/', '\\').Length;

            // Expand directory paths into file paths. Convert paths to full paths.
            List <string> filePaths = new List <string>();

            foreach (var path in paths)
            {
                string fullPath = path;
                if (!Path.IsPathRooted(fullPath))
                {
                    fullPath = Path.Combine(WorkingDirectory, fullPath);
                }
                fullPath = Path.GetFullPath(fullPath).TrimEnd('/', '\\');
                DirectoryInfo dir = new DirectoryInfo(fullPath);
                if (dir.Exists)
                {
                    filePaths.AddRange(GetDirectoryFiles(dir));
                }
                else
                {
                    filePaths.Add(fullPath);
                }
            }

            // Read the tree of the last commit. We are going to update it.
            GitSharp.Core.Tree tree = _internal_repo.MapTree(CurrentBranch.CurrentCommit._id);

            // Keep a list of trees that have been modified, since they have to be written.
            HashSet <GitSharp.Core.Tree> modifiedTrees = new HashSet <GitSharp.Core.Tree>();

            // Update the tree
            foreach (string fullPath in filePaths)
            {
                string    relPath   = fullPath.Substring(basePathLength + 1).Replace('\\', '/');
                TreeEntry treeEntry = tree.FindBlobMember(relPath);

                if (File.Exists(fullPath))
                {
                    // Looks like an old directory is now a file. Delete the subtree and create a new entry for the file.
                    if (treeEntry != null && !(treeEntry is FileTreeEntry))
                    {
                        treeEntry.Delete();
                    }

                    FileTreeEntry fileEntry  = treeEntry as FileTreeEntry;
                    var           writer     = new ObjectWriter(_internal_repo);
                    bool          executable = GitSharp.Core.Util.FS.canExecute(new FileInfo(fullPath));
                    ObjectId      id         = writer.WriteBlob(new FileInfo(fullPath));
                    if (fileEntry == null)
                    {
                        // It's a new file. Add it.
                        fileEntry = (FileTreeEntry)tree.AddFile(relPath);
                        treeEntry = fileEntry;
                    }
                    else if (fileEntry.Id == id && executable == fileEntry.IsExecutable)
                    {
                        // Same file, ignore it
                        continue;
                    }

                    fileEntry.Id = id;
                    fileEntry.SetExecutable(executable);
                }
                else
                {
                    // Deleted file or directory. Remove from the tree
                    if (treeEntry != null)
                    {
                        GitSharp.Core.Tree ptree = treeEntry.Parent;
                        treeEntry.Delete();
                        // Remove the subtree if it's now empty
                        while (ptree != null && ptree.MemberCount == 0)
                        {
                            GitSharp.Core.Tree nextParent = ptree.Parent;
                            ptree.Delete();
                            ptree = nextParent;
                        }
                    }
                    else
                    {
                        continue; // Already deleted.
                    }
                }
                modifiedTrees.Add(treeEntry.Parent);
            }

            // check if tree is different from current commit's tree
            if (modifiedTrees.Count == 0)
            {
                throw new InvalidOperationException("There are no changes to commit");
            }

            // Create new trees if there is any change
            ObjectId tree_id = SaveTree(tree, modifiedTrees);

            // Create the commit
            var parent = CurrentBranch.CurrentCommit;
            var commit = GitSharp.Commit.Create(message, parent, new Tree(this, tree_id), author);

            Ref.Update("HEAD", commit);

            // Unstage updated files
            Index.Unstage(paths);

            return(commit);
        }
Beispiel #34
0
        private void UpdateDirectoryNotRecursive(string path)
        {
            _index = Repository.Index.GitIndex;

            // Tree that will hold the working dir file entries
            var wtree = new Core.Tree(Repository._internal_repo);

            // Get a list of a leaves in the path

            Tree commitTree = null;
            var  commit     = Repository.Head.CurrentCommit;

            commitTree = commit != null ? commit.Tree : null;
            if (commitTree != null)
            {
                commitTree = commitTree[path] as Tree;
            }

            Dictionary <string, Leaf> commitEntries;

            if (commitTree != null)
            {
                commitEntries = commitTree.Leaves.ToDictionary(l => l.Path);
            }
            else
            {
                commitEntries = new Dictionary <string, Leaf> ();
            }

            HashSet <string> visited = new HashSet <string> ();

            // Compare commited files and working tree files

            DirectoryInfo dir = new DirectoryInfo(Repository.FromGitPath(path));

            if (dir.Exists)
            {
                foreach (FileInfo fileInfo in dir.GetFiles())
                {
                    string file = path + "/" + fileInfo.Name;

                    Leaf lf;
                    if (commitEntries.TryGetValue(file, out lf))
                    {
                        // Remove from the collection. At the end of the loop, entries still remaining in the
                        // collection will be processed as not having a corresponding working dir file
                        commitEntries.Remove(file);
                    }

                    TreeEntry wdirEntry = null;
                    if (!IgnoreHandler.IsIgnored(file) && fileInfo.Exists)
                    {
                        wdirEntry = wtree.AddFile(file);
                    }

                    GitIndex.Entry indexEntry = _index.GetEntry(file);

                    OnVisitEntry(lf != null ? lf.InternalEntry : null, wdirEntry, indexEntry, fileInfo);
                    visited.Add(file);
                }
            }

            // Now visit entries for which a working dir file was not found

            foreach (var lf in commitEntries)
            {
                string         file       = lf.Key;
                FileInfo       fileInfo   = new FileInfo(Repository.FromGitPath(file));
                GitIndex.Entry indexEntry = _index.GetEntry(file);
                OnVisitEntry(lf.Value.InternalEntry, null, indexEntry, fileInfo);
                visited.Add(file);
            }

            // Finally, visit remaining index entries which are not in the working dir nor in the commit

            foreach (var ie in _index.Members)
            {
                string file = ie.Name;
                // Exclude entries in subdirectories of _root_path
                int    i    = file.LastIndexOf('/');
                string fdir = i != -1 ? file.Substring(0, i) : string.Empty;
                if (fdir == _root_path && !visited.Contains(file))
                {
                    OnVisitEntry(null, null, ie, new FileInfo(Repository.FromGitPath(file)));
                }
            }
        }
Beispiel #35
0
 private void addFile(Tree t, FileInfo f, ObjectWriter objectWriter)
 {
     ObjectId id = objectWriter.WriteBlob(f);
     t.AddEntry(new FileTreeEntry(t, id, f.Name.getBytes("UTF-8"), false));
 }
Beispiel #36
0
 public ObjectId WriteTree(Tree t)
 {
     var output = new MemoryStream();
     var writer = new BinaryWriter(output);
     foreach (TreeEntry entry in t.Members)
     {
         ObjectId id = entry.Id;
         if (id == null)
         {
             throw new ObjectWritingException("object at path \"" + entry.FullName +
                                              "\" does not have an id assigned.  All object ids must be assigned prior to writing a tree.");
         }
         entry.Mode.CopyTo(output);
         writer.Write((byte)0x20);
         writer.Write(entry.NameUTF8);
         writer.Write((byte)0);
         id.copyRawTo(output);
     }
     return WriteCanonicalTree(output.ToArray());
 }
Beispiel #37
0
 public void test002_WriteEmptyTree()
 {
     // One of our test packs contains the empty tree object. If the pack is
     // open when we Create it we won't write the object file out as a loose
     // object (as it already exists in the pack).
     //
     Core.Repository newdb = createNewEmptyRepo();
     var t = new Tree(newdb);
     t.Accept(new WriteTree(trash, newdb), TreeEntry.MODIFIED_ONLY);
     Assert.AreEqual("4b825dc642cb6eb9a060e54bf8d69288fbee4904", t.Id.Name);
     var o = new FileInfo(newdb.Directory + "/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904");
     Assert.IsTrue(o.IsFile(), "Exists " + o);
     Assert.IsTrue(o.IsReadOnly, "Read-only " + o);
 }
Beispiel #38
0
		/// <summary>
		/// Construct a Tree with a known SHA-1 under another tree. Data is not yet
		///	specified and will have to be loaded on demand.
		///	</summary>
		///	<param name="parent"></param>
		///	<param name="id"></param>
		///	<param name="nameUTF8"></param>
		public Tree(Tree parent, ObjectId id, byte[] nameUTF8)
			: base(parent, id, nameUTF8)
		{
			_db = parent.Repository;
		}
Beispiel #39
0
 public SymlinkTreeEntry(Tree parent, ObjectId id, byte[] nameUTF8)
     : base(parent, id, nameUTF8)
 {
 }
Beispiel #40
0
		///	<summary>
		/// Adds a new or existing Tree with the specified name to this tree.
		///	Trees are added if necessary as the name may contain '/':s.
		///	</summary>
		///	<param name="s"> an array containing the name </param>
		///	<param name="offset"> when the name starts in the tree.</param>
		///	<returns>A <seealso cref="FileTreeEntry"/> for the added tree.</returns>
		///	<exception cref="IOException"></exception>
		public Tree AddTree(byte[] s, int offset)
		{
			int slash;

			for (slash = offset; slash < s.Length && s[slash] != '/'; slash++)
			{
				// search for path component terminator
			}

			EnsureLoaded();
			int p = BinarySearch(_contents, s, (byte)'/', offset, slash);
			if (p >= 0 && slash < s.Length && _contents[p] is Tree)
			{
				return ((Tree)_contents[p]).AddTree(s, slash + 1);
			}

			byte[] newName = SubString(s, offset, slash);
			if (p >= 0)
			{
				throw new EntryExistsException(RawParseUtils.decode(newName));
			}

            Tree t = new Tree(this, newName);
			InsertEntry(p, t);
			return slash == s.Length ? t : t.AddTree(s, slash + 1);
		}
Beispiel #41
0
        public void test023_createCommitNonAnullii()
        {
            ObjectId emptyId = new ObjectWriter(db).WriteBlob(new byte[0]);
            var almostEmptyTree = new Tree(db);
            almostEmptyTree.AddEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
            ObjectId almostEmptyTreeId = new ObjectWriter(db).WriteTree(almostEmptyTree);

            var commit = new Commit(db)
                         	{
                         		TreeId = almostEmptyTreeId,
                         		Author = new PersonIdent("Joe H\u00e4cker", "*****@*****.**", 4294967295000L, 60),
                         		Committer = new PersonIdent("Joe Hacker", "*****@*****.**", 4294967295000L, 60),
                                Encoding = Constants.CHARSET,
                         		Message = "\u00dcbergeeks"
                         	};

            ObjectId cid = new ObjectWriter(db).WriteCommit(commit);
            Assert.AreEqual("4680908112778718f37e686cbebcc912730b3154", cid.Name);
        }
Beispiel #42
0
 internal Tree(Repository repo, CoreTree tree)
     : base(repo, tree.Id)
 {
     _internal_tree = tree;
 }
Beispiel #43
0
 public void test024_createCommitNonAscii()
 {
     ObjectId emptyId = new ObjectWriter(db).WriteBlob(new byte[0]);
     var almostEmptyTree = new Tree(db);
     almostEmptyTree.AddEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
     ObjectId almostEmptyTreeId = new ObjectWriter(db).WriteTree(almostEmptyTree);
     var commit = new Commit(db)
                  	{
                  		TreeId = almostEmptyTreeId,
                  		Author = new PersonIdent("Joe H\u00e4cker", "*****@*****.**", 4294967295000L, 60),
                  		Committer = new PersonIdent("Joe Hacker", "*****@*****.**", 4294967295000L, 60),
                  		Encoding = Encoding.GetEncoding("ISO-8859-1"),
                  		Message = "\u00dcbergeeks"
                  	};
     ObjectId cid = new ObjectWriter(db).WriteCommit(commit);
     var s = new Inspector(db).Inspect(cid);
     Assert.AreEqual("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.ToString());
 }