Skip to content

Commit 92be707

Browse files
authored
Allow for easier committing from subdirectories (#33)
* Allow for easier committing from subdirectories fixes #29 * chore: rename addDirectory -> addFromDirectory * feat: Introduce `filterFiles` argument * tests: add tests for new functionality in git.ts * Fix addFromDirectory implementation
1 parent 21c9eaf commit 92be707

File tree

9 files changed

+581
-7
lines changed

9 files changed

+581
-7
lines changed

.changeset/light-days-fry.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@changesets/ghcommit": minor
3+
---
4+
5+
Introduce `filterFiles` argument for `commitChangesFromRepo`
6+
7+
Allow for a custom function to be specified to filter which files should be
8+
included in the commit

.changeset/mean-trainers-develop.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@changesets/ghcommit": minor
3+
---
4+
5+
Introduce `addFromDirectory` option for `commitChangesFromRepo` to allow users to
6+
specify a subdirectory of the git repository that should be used to add files
7+
from, rather then adding all changed files.
8+
9+
This is useful when trying to emulate the behavior of running `git add .`
10+
from a subdirectory of the repository.

.changeset/old-kings-collect.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@changesets/ghcommit": minor
3+
---
4+
5+
Automatically find root in `commitChangesFromRepo`
6+
when `repoDirectory` is unspecified.
7+
8+
While this does result in a behavioral change for an existing argument,
9+
it's considered non-breaking as before `commitChangesFromRepo` would just not
10+
work when run from a subdirectory of a repo when `repoDirectory` was not
11+
specified.

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,26 @@ In addition to `CommitFilesBasedArgs`, this function has the following arguments
9393
/**
9494
* The root of the repository.
9595
*
96-
* @default process.cwd()
96+
* When unspecified, the root of the repository will be found by recursively
97+
* searching for the `.git` directory from the current working directory.
9798
*/
9899
repoDirectory?: string;
100+
/**
101+
* The starting directory to recurse from when detecting changed files.
102+
*
103+
* Useful for monorepos where you want to add files from a specific directory only.
104+
*
105+
* Defaults to resolved value of {@link repoDirectory},
106+
* which will add all changed files in the repository.
107+
*/
108+
addFromDirectory?: string;
109+
/**
110+
* An optional function that can be used to filter which files are included
111+
* in the commit. True should be returned for files that should be included.
112+
*
113+
* By default, all files are included.
114+
*/
115+
filterFiles?: (file: string) => boolean;
99116
}
100117
```
101118

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
},
5555
"devDependencies": {
5656
"@actions/github": "^6.0.0",
57-
"@changesets/cli": "^2.27.7",
5857
"@changesets/changelog-github": "^0.5.1",
58+
"@changesets/cli": "^2.27.7",
5959
"@graphql-codegen/cli": "^5.0.2",
6060
"@graphql-codegen/import-types-preset": "^3.0.0",
6161
"@graphql-codegen/typescript": "^4.0.4",
@@ -74,6 +74,7 @@
7474
"eslint-plugin-jest": "^28.6.0",
7575
"eslint-plugin-only-warn": "^1.1.0",
7676
"jest": "^29.7.0",
77+
"mock-cwd": "^1.0.0",
7778
"pino": "^9.3.2",
7879
"pino-pretty": "^11.2.2",
7980
"prettier": "^3.3.3",

pnpm-lock.yaml

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/git.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
CommitFilesFromBuffersArgs,
77
CommitFilesResult,
88
} from "./interface";
9+
import { isAbsolute, relative } from "path";
910

1011
/**
1112
* @see https://isomorphic-git.org/docs/en/walk#walkerentry-mode
@@ -19,14 +20,18 @@ const FILE_MODES = {
1920

2021
export const commitChangesFromRepo = async ({
2122
base,
22-
repoDirectory = process.cwd(),
23+
repoDirectory,
24+
addFromDirectory,
25+
filterFiles,
2326
log,
2427
...otherArgs
2528
}: CommitChangesFromRepoArgs): Promise<CommitFilesResult> => {
2629
const ref = base?.commit ?? "HEAD";
30+
const resolvedRepoDirectory =
31+
repoDirectory ?? (await git.findRoot({ fs, filepath: process.cwd() }));
2732
const gitLog = await git.log({
2833
fs,
29-
dir: repoDirectory,
34+
dir: resolvedRepoDirectory,
3035
ref,
3136
depth: 1,
3237
});
@@ -37,6 +42,19 @@ export const commitChangesFromRepo = async ({
3742
throw new Error(`Could not determine oid for ${ref}`);
3843
}
3944

45+
if (addFromDirectory && !isAbsolute(addFromDirectory)) {
46+
throw new Error(
47+
`addFromDirectory must be an absolute path, got ${addFromDirectory}`,
48+
);
49+
}
50+
51+
/**
52+
* The directory to add files from. This is relative to the repository
53+
* root, and is used to filter files.
54+
*/
55+
const relativeStartDirectory =
56+
addFromDirectory && relative(resolvedRepoDirectory, addFromDirectory) + "/";
57+
4058
// Determine changed files
4159
const trees = [git.TREE({ ref: oid }), git.WORKDIR()];
4260
const additions: CommitFilesFromBuffersArgs["fileChanges"]["additions"] = [];
@@ -47,14 +65,14 @@ export const commitChangesFromRepo = async ({
4765
};
4866
await git.walk({
4967
fs,
50-
dir: repoDirectory,
68+
dir: resolvedRepoDirectory,
5169
trees,
5270
map: async (filepath, [commit, workdir]) => {
5371
// Don't include ignored files
5472
if (
5573
await git.isIgnored({
5674
fs,
57-
dir: repoDirectory,
75+
dir: resolvedRepoDirectory,
5876
filepath,
5977
})
6078
) {
@@ -88,6 +106,17 @@ export const commitChangesFromRepo = async ({
88106
// Iterate through these directories
89107
return true;
90108
}
109+
if (
110+
relativeStartDirectory &&
111+
!filepath.startsWith(relativeStartDirectory)
112+
) {
113+
// Ignore files that are not in the specified directory
114+
return null;
115+
}
116+
if (filterFiles && !filterFiles(filepath)) {
117+
// Ignore out files that don't match any specified filter
118+
return null;
119+
}
91120
if (!workdir) {
92121
// File was deleted
93122
deletions.push(filepath);

src/interface.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,24 @@ export interface CommitChangesFromRepoArgs extends CommitFilesBasedArgs {
107107
/**
108108
* The root of the repository.
109109
*
110-
* @default process.cwd()
110+
* When unspecified, the root of the repository will be found by recursively
111+
* searching for the `.git` directory from the current working directory.
111112
*/
112113
repoDirectory?: string;
114+
/**
115+
* The starting directory to recurse from when detecting changed files.
116+
*
117+
* Useful for monorepos where you want to add files from a specific directory only.
118+
*
119+
* Defaults to resolved value of {@link repoDirectory},
120+
* which will add all changed files in the repository.
121+
*/
122+
addFromDirectory?: string;
123+
/**
124+
* An optional function that can be used to filter which files are included
125+
* in the commit. True should be returned for files that should be included.
126+
*
127+
* By default, all files are included.
128+
*/
129+
filterFiles?: (file: string) => boolean;
113130
}

0 commit comments

Comments
 (0)