コード例 #1
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);
        }