Skip to content

Commit 49c2f16

Browse files
AtkinsSJKernelDeimos
authored andcommitted
feat(git): Add start-revision and file arguments to git log
1 parent eb2b6a0 commit 49c2f16

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

packages/git/src/git-helpers.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919
import path from 'path-browserify';
20-
import git from 'isomorphic-git';
2120

2221
export const PROXY_URL = 'https://cors.isomorphic-git.org';
2322

@@ -110,3 +109,33 @@ export const determine_fetch_remote = (remote_name_or_url, remotes) => {
110109
throw new Error(`'${remote_name_or_url}' does not appear to be a git repository`);
111110
return remote_data;
112111
}
112+
113+
/**
114+
* Divide up the positional arguments into those before the `--` separator, and those after it.
115+
* @param arg_tokens Tokens array from parseArgs({ tokens: true })
116+
* @returns {{before: string[], after: string[]}}
117+
*/
118+
export const group_positional_arguments = (arg_tokens) => {
119+
let saw_separator = false;
120+
const result = {
121+
before: [],
122+
after: [],
123+
};
124+
125+
for (const token of arg_tokens) {
126+
if (token.kind === 'option-terminator') {
127+
saw_separator = true;
128+
continue;
129+
}
130+
if (token.kind === 'positional') {
131+
if (saw_separator) {
132+
result.after.push(token.value);
133+
} else {
134+
result.before.push(token.value);
135+
}
136+
continue;
137+
}
138+
}
139+
140+
return result;
141+
}

packages/git/src/subcommands/log.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919
import git from 'isomorphic-git';
20-
import { find_repo_root } from '../git-helpers.js';
20+
import { find_repo_root, group_positional_arguments } from '../git-helpers.js';
2121
import { commit_formatting_options, format_commit, process_commit_formatting_options } from '../format.js';
22+
import { SHOW_USAGE } from '../help.js';
2223

2324
export default {
2425
name: 'log',
25-
usage: 'git log [<formatting-option>...] [--max-count <n>] <revision>',
26+
usage: 'git log [<formatting-option>...] [--max-count <n>] [<revision>] [[--] <path>]',
2627
description: 'Show commit logs, starting at the given revision.',
2728
args: {
28-
allowPositionals: false,
29+
allowPositionals: true,
30+
tokens: true,
2931
options: {
3032
...commit_formatting_options,
3133
'max-count': {
@@ -38,23 +40,27 @@ export default {
3840
execute: async (ctx) => {
3941
const { io, fs, env, args } = ctx;
4042
const { stdout, stderr } = io;
41-
const { options, positionals } = args;
43+
const { options, positionals, tokens } = args;
4244

4345
process_commit_formatting_options(options);
4446

45-
// TODO: Log of a specific file
46-
// TODO: Log of a specific branch
47-
// TODO: Log of a specific commit
48-
4947
const depth = Number(options['max-count']) || undefined;
5048

5149
const { dir, gitdir } = await find_repo_root(fs, env.PWD);
5250

51+
const { before: refs, after: paths } = group_positional_arguments(tokens);
52+
if (refs.length > 1 || paths.length > 1) {
53+
stderr('error: Too many revisions or paths given. Expected [<revision>] [[--] <path>]');
54+
throw SHOW_USAGE;
55+
}
56+
5357
const log = await git.log({
5458
fs,
5559
dir,
5660
gitdir,
5761
depth,
62+
ref: refs[0],
63+
filepath: paths[0],
5864
});
5965

6066
for (const commit of log) {

0 commit comments

Comments
 (0)