Exemplo n.º 1
0
        /// <summary>
        /// Creates a commit object that represents the current
        /// state of the index, writes the commit to the `objects` directory
        /// and points `HEAD` at the commit.
        /// </summary>
        public static string Commit(CommitOptions options)
        {
            Files.AssertInRepo();
            Config.AssertNotBare();

            // Write a tree object that represents the current state of the
            // index.
            var treeHash = WriteTree();

            var headDesc = Refs.IsHeadDetached() ? "detached HEAD" : Refs.HeadBranchName();

            // If the hash of the new tree is the same as the hash of the tree
            // that the `HEAD` commit points at, abort because there is
            // nothing new to commit.
            if (Refs.Hash("HEAD") != null &&
                treeHash == Objects.TreeHash(Objects.Read(Refs.Hash("HEAD"))))
            {
                throw new Exception("# On " + headDesc + "\nnothing to commit, working directory clean");
            }

            // Abort if the repository is in the merge state and there are
            // unresolved merge conflicts.
            string[] conflictedPaths = Index.ConflictedPaths();
            if (Core.Merge.IsMergeInProgress() && conflictedPaths.Length > 0)
            {
                throw new Exception(
                          string.Join("\n", conflictedPaths.Select(p => "U " + p))
                          + "\ncannot commit because you have unmerged files");
            }

            // Otherwise, do the commit.

            // If the repository is in the merge state, use a pre-written
            // merge commit message.  If the repository is not in the
            // merge state, use the message passed with `-m`.
            var m =
                Core.Merge.IsMergeInProgress()
                    ? Files.Read(Path.Combine(Files.GitletPath(), "MERGE_MSG"))
                    : options.m;

            // Write the new commit to the `objects` directory.
            var commitHash = Objects.WriteCommit(treeHash, m, Refs.CommitParentHashes());

            // Point `HEAD` at new commit.
            UpdateRef("HEAD", commitHash);

            // If `MERGE_HEAD` exists, the repository was in the merge
            // state. Remove `MERGE_HEAD` and `MERGE_MSG`to exit the merge
            // state.  Report that the merge is complete.
            if (Core.Merge.IsMergeInProgress())
            {
                File.Delete(Path.Combine(Files.GitletPath(), "MERGE_MSG"));
                Refs.Rm("MERGE_HEAD");
                return("Merge made by the three-way strategy");
            }

            // Repository was not in the merge state, so just report that
            // the commit is complete.
            return("[" + headDesc + " " + commitHash + "] " + m);
        }