Sam Atkins преди 1 година
родител
ревизия
10f715f726
променени са 3 файла, в които са добавени 135 реда и са изтрити 0 реда
  1. 37 0
      packages/git/src/format.js
  2. 2 0
      packages/git/src/subcommands/__exports__.js
  3. 96 0
      packages/git/src/subcommands/show.js

+ 37 - 0
packages/git/src/format.js

@@ -175,3 +175,40 @@ export const format_commit = (commit, oid, options = {}) => {
         }
     }
 }
+
+/**
+ * Produce a string representation of a tree.
+ * @param oid
+ * @param tree
+ * @param options
+ * @returns {string}
+ */
+export const format_tree = (oid, tree, options = {}) => {
+    let s = '';
+    s += `tree ${oid}\n`;
+    s += '\n';
+    for (const tree_entry of tree) {
+        s += `${tree_entry.path}\n`;
+    }
+    s += '\n';
+    return s;
+}
+
+/**
+ * Produce a string representation of a tag.
+ * Note that this only includes the tag itself, and not the tag's target,
+ * which must be separately retrieved and formatted.
+ * @param tag
+ * @param options
+ * @returns {string}
+ */
+export const format_tag = (tag, options = {}) => {
+    let s = '';
+    s += `tag ${tag.tag}\n`;
+    s += `Tagger: ${format_person(tag.tagger)}\n`;
+    s += `Date:   ${format_date(tag.tagger, options)}\n`;
+    if (tag.message) {
+        s += `\n${tag.message}\n\n`;
+    }
+    return s;
+}

+ 2 - 0
packages/git/src/subcommands/__exports__.js

@@ -23,6 +23,7 @@ import module_config from './config.js'
 import module_help from './help.js'
 import module_init from './init.js'
 import module_log from './log.js'
+import module_show from './show.js'
 import module_status from './status.js'
 import module_version from './version.js'
 
@@ -33,6 +34,7 @@ export default {
     "help": module_help,
     "init": module_init,
     "log": module_log,
+    "show": module_show,
     "status": module_status,
     "version": module_version,
 };

+ 96 - 0
packages/git/src/subcommands/show.js

@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024  Puter Technologies Inc.
+ *
+ * This file is part of Puter's Git client.
+ *
+ * Puter's Git client is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+import git from 'isomorphic-git';
+import { find_repo_root } from '../git-helpers.js';
+import { commit_formatting_options, process_commit_formatting_options, format_commit, format_tag, format_tree } from '../format.js';
+
+export default {
+    name: 'show',
+    usage: 'git show [<formatting-option>...] <object>',
+    description: 'Show information about an object (commit, tree, tag, blob, etc.) in git.',
+    args: {
+        allowPositionals: true,
+        options: {
+            ...commit_formatting_options,
+        },
+    },
+    execute: async (ctx) => {
+        const { io, fs, env, args } = ctx;
+        const { stdout, stderr } = io;
+        const { options, positionals } = args;
+
+        process_commit_formatting_options(options);
+
+        const { repository_dir, git_dir } = await find_repo_root(fs, env.PWD);
+
+        const objects = [...positionals];
+
+        const cache = {};
+
+        const format_object = async (parsed_object, options) => {
+            switch (parsed_object.type) {
+                case 'blob':
+                    return parsed_object.object;
+                case 'commit':
+                    return format_commit(parsed_object.object, parsed_object.oid, options);
+                case 'tree':
+                    return format_tree(parsed_object.oid, parsed_object.object, options);
+                case 'tag': {
+                    const tag = parsed_object.object;
+                    let s = format_tag(tag, options);
+                    // Formatting a tag also outputs the formatted object it points to.
+                    // That may also be a tag, so we recurse.
+                    const target = await git.readObject({
+                        fs,
+                        dir: repository_dir,
+                        gitdir: git_dir,
+                        oid: tag.object,
+                        format: 'parsed',
+                        cache,
+                    });
+                    s += await format_object(target, options);
+                    return s;
+                }
+            }
+        }
+
+        for (const ref of objects) {
+            // Could be any ref, so first get the oid that's referred to.
+            const oid = await git.resolveRef({
+                fs,
+                dir: repository_dir,
+                gitdir: git_dir,
+                ref,
+            });
+
+            // Then obtain the object and parse it.
+            const parsed_object = await git.readObject({
+                fs,
+                dir: repository_dir,
+                gitdir: git_dir,
+                oid,
+                format: 'parsed',
+                cache,
+            });
+
+            // Then, print it out
+            stdout(await format_object(parsed_object, options));
+        }
+    }
+}