diff --git a/packages/git/src/format.js b/packages/git/src/format.js
index b01c5bd11b..da3d320af8 100644
--- a/packages/git/src/format.js
+++ b/packages/git/src/format.js
@@ -268,7 +268,7 @@ export const diff_formatting_options = {
* @param options Parsed command-line options.
* @returns {{raw: boolean, numstat: boolean, summary: boolean, patch: boolean, context_lines: number, no_patch: boolean, source_prefix: string, dest_prefix: string }}
*/
-export const process_diff_formatting_options = (options) => {
+export const process_diff_formatting_options = (options, { show_patch_by_default = true } = {}) => {
const result = {
raw: false,
numstat: false,
@@ -280,6 +280,10 @@ export const process_diff_formatting_options = (options) => {
dest_prefix: 'b/',
};
+ result.display_diff = () => {
+ return !result.no_patch && (result.raw || result.numstat || result.summary || result.patch);
+ };
+
if (options['raw'])
result.raw = true;
if (options['numstat'])
@@ -312,7 +316,7 @@ export const process_diff_formatting_options = (options) => {
}
// If nothing is specified, default to --patch
- if (!result.raw && !result.numstat && !result.summary && !result.patch)
+ if (show_patch_by_default && !result.raw && !result.numstat && !result.summary && !result.patch)
result.patch = true;
// --no-patch overrides the others
diff --git a/packages/git/src/subcommands/log.js b/packages/git/src/subcommands/log.js
index 6f14fa1976..470f8d8dcb 100644
--- a/packages/git/src/subcommands/log.js
+++ b/packages/git/src/subcommands/log.js
@@ -16,10 +16,18 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import git from 'isomorphic-git';
+import git, { TREE } from 'isomorphic-git';
import { find_repo_root, group_positional_arguments } from '../git-helpers.js';
-import { commit_formatting_options, format_commit, process_commit_formatting_options } from '../format.js';
+import {
+ commit_formatting_options,
+ diff_formatting_options,
+ format_commit, format_diffs,
+ process_commit_formatting_options,
+ process_diff_formatting_options,
+} from '../format.js';
+import path from 'path-browserify';
import { SHOW_USAGE } from '../help.js';
+import { diff_git_trees } from '../diff.js';
export default {
name: 'log',
@@ -30,6 +38,7 @@ export default {
tokens: true,
options: {
...commit_formatting_options,
+ ...diff_formatting_options,
'max-count': {
description: 'Maximum number of commits to output.',
type: 'string',
@@ -41,8 +50,10 @@ export default {
const { io, fs, env, args } = ctx;
const { stdout, stderr } = io;
const { options, positionals, tokens } = args;
+ const cache = {};
process_commit_formatting_options(options);
+ const diff_options = process_diff_formatting_options(options, { show_patch_by_default: false });
const depth = Number(options['max-count']) || undefined;
@@ -62,9 +73,27 @@ export default {
ref: refs[0],
filepath: paths[0],
});
+ const diff_ctx = {
+ fs, dir, gitdir, cache, env,
+ context_lines: diff_options.context_lines,
+ path_filters: paths.map(it => path.resolve(env.PWD, it)),
+ };
+ const read_tree = walker => walker?.content()?.then(it => new TextDecoder().decode(it));
for (const commit of log) {
stdout(format_commit(commit.commit, commit.oid, options));
+ if (diff_options.display_diff()) {
+ const diffs = await diff_git_trees({
+ ...diff_ctx,
+ // NOTE: Using an empty string for a non-existent parent prevents the default value 'HEAD' getting used.
+ // TREE() then fails to resolve that ref, and defaults to the empty commit, which is what we want.
+ a_tree: TREE({ ref: commit.commit.parent[0] ?? '' }),
+ b_tree: TREE({ ref: commit.oid }),
+ read_a: read_tree,
+ read_b: read_tree,
+ });
+ stdout(format_diffs(diffs, diff_options));
+ }
}
}
}
diff --git a/packages/git/src/subcommands/show.js b/packages/git/src/subcommands/show.js
index d705905468..b14c538894 100644
--- a/packages/git/src/subcommands/show.js
+++ b/packages/git/src/subcommands/show.js
@@ -16,9 +16,18 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import git from 'isomorphic-git';
+import git, { TREE } 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';
+import {
+ commit_formatting_options,
+ diff_formatting_options,
+ format_commit, format_diffs,
+ format_tag,
+ format_tree,
+ process_commit_formatting_options,
+ process_diff_formatting_options,
+} from '../format.js';
+import { diff_git_trees } from '../diff.js';
export default {
name: 'show',
@@ -28,6 +37,7 @@ export default {
allowPositionals: true,
options: {
...commit_formatting_options,
+ ...diff_formatting_options,
},
},
execute: async (ctx) => {
@@ -36,19 +46,41 @@ export default {
const { options, positionals } = args;
process_commit_formatting_options(options);
+ const diff_options = process_diff_formatting_options(options);
const { dir, gitdir } = await find_repo_root(fs, env.PWD);
const objects = [...positionals];
const cache = {};
+ const diff_ctx = {
+ fs, dir, gitdir, cache, env,
+ context_lines: diff_options.context_lines,
+ path_filters: [],
+ };
- const format_object = async (parsed_object, options) => {
+ const read_tree = walker => walker?.content()?.then(it => new TextDecoder().decode(it));
+
+ const format_object = async (parsed_object) => {
switch (parsed_object.type) {
case 'blob':
return parsed_object.object;
- case 'commit':
- return format_commit(parsed_object.object, parsed_object.oid, options);
+ case 'commit': {
+ let s = format_commit(parsed_object.object, parsed_object.oid, options);
+ if (diff_options.display_diff()) {
+ const diffs = await diff_git_trees({
+ ...diff_ctx,
+ // NOTE: Using an empty string for a non-existent parent prevents the default value 'HEAD' getting used.
+ // TREE() then fails to resolve that ref, and defaults to the empty commit, which is what we want.
+ a_tree: TREE({ ref: parsed_object.object.parent[0] ?? '' }),
+ b_tree: TREE({ ref: parsed_object.oid }),
+ read_a: read_tree,
+ read_b: read_tree,
+ });
+ s += format_diffs(diffs, diff_options);
+ }
+ return s;
+ }
case 'tree':
return format_tree(parsed_object.oid, parsed_object.object, options);
case 'tag': {
@@ -64,7 +96,7 @@ export default {
format: 'parsed',
cache,
});
- s += await format_object(target, options);
+ s += await format_object(target);
return s;
}
}
@@ -90,7 +122,7 @@ export default {
});
// Then, print it out
- stdout(await format_object(parsed_object, options));
+ stdout(await format_object(parsed_object));
}
}
}