Skip to content

Allow for easier committing from subdirectories #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/light-days-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@changesets/ghcommit": minor
---

Introduce `filterFiles` argument for `commitChangesFromRepo`

Allow for a custom function to be specified to filter which files should be
included in the commit
10 changes: 10 additions & 0 deletions .changeset/mean-trainers-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@changesets/ghcommit": minor
---

Introduce `addFromDirectory` option for `commitChangesFromRepo` to allow users to
specify a subdirectory of the git repository that should be used to add files
from, rather then adding all changed files.

This is useful when trying to emulate the behavior of running `git add .`
from a subdirectory of the repository.
11 changes: 11 additions & 0 deletions .changeset/old-kings-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@changesets/ghcommit": minor
---

Automatically find root in `commitChangesFromRepo`
when `repoDirectory` is unspecified.

While this does result in a behavioral change for an existing argument,
it's considered non-breaking as before `commitChangesFromRepo` would just not
work when run from a subdirectory of a repo when `repoDirectory` was not
specified.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,26 @@ In addition to `CommitFilesBasedArgs`, this function has the following arguments
/**
* The root of the repository.
*
* @default process.cwd()
* When unspecified, the root of the repository will be found by recursively
* searching for the `.git` directory from the current working directory.
*/
repoDirectory?: string;
/**
* The starting directory to recurse from when detecting changed files.
*
* Useful for monorepos where you want to add files from a specific directory only.
*
* Defaults to resolved value of {@link repoDirectory},
* which will add all changed files in the repository.
*/
addFromDirectory?: string;
/**
* An optional function that can be used to filter which files are included
* in the commit. True should be returned for files that should be included.
*
* By default, all files are included.
*/
filterFiles?: (file: string) => boolean;
}
```

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@
},
"devDependencies": {
"@actions/github": "^6.0.0",
"@changesets/cli": "^2.27.7",
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.27.7",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/import-types-preset": "^3.0.0",
"@graphql-codegen/typescript": "^4.0.4",
Expand All @@ -74,6 +74,7 @@
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-only-warn": "^1.1.0",
"jest": "^29.7.0",
"mock-cwd": "^1.0.0",
"pino": "^9.3.2",
"pino-pretty": "^11.2.2",
"prettier": "^3.3.3",
Expand Down
32 changes: 32 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 33 additions & 4 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
CommitFilesFromBuffersArgs,
CommitFilesResult,
} from "./interface";
import { isAbsolute, relative } from "path";

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

export const commitChangesFromRepo = async ({
base,
repoDirectory = process.cwd(),
repoDirectory,
addFromDirectory,
filterFiles,
log,
...otherArgs
}: CommitChangesFromRepoArgs): Promise<CommitFilesResult> => {
const ref = base?.commit ?? "HEAD";
const resolvedRepoDirectory =
repoDirectory ?? (await git.findRoot({ fs, filepath: process.cwd() }));
const gitLog = await git.log({
fs,
dir: repoDirectory,
dir: resolvedRepoDirectory,
ref,
depth: 1,
});
Expand All @@ -37,6 +42,19 @@ export const commitChangesFromRepo = async ({
throw new Error(`Could not determine oid for ${ref}`);
}

if (addFromDirectory && !isAbsolute(addFromDirectory)) {
throw new Error(
`addFromDirectory must be an absolute path, got ${addFromDirectory}`,
);
}

/**
* The directory to add files from. This is relative to the repository
* root, and is used to filter files.
*/
const relativeStartDirectory =
addFromDirectory && relative(resolvedRepoDirectory, addFromDirectory) + "/";

// Determine changed files
const trees = [git.TREE({ ref: oid }), git.WORKDIR()];
const additions: CommitFilesFromBuffersArgs["fileChanges"]["additions"] = [];
Expand All @@ -47,14 +65,14 @@ export const commitChangesFromRepo = async ({
};
await git.walk({
fs,
dir: repoDirectory,
dir: resolvedRepoDirectory,
trees,
map: async (filepath, [commit, workdir]) => {
// Don't include ignored files
if (
await git.isIgnored({
fs,
dir: repoDirectory,
dir: resolvedRepoDirectory,
filepath,
})
) {
Expand Down Expand Up @@ -88,6 +106,17 @@ export const commitChangesFromRepo = async ({
// Iterate through these directories
return true;
}
if (
relativeStartDirectory &&
!filepath.startsWith(relativeStartDirectory)
) {
// Ignore files that are not in the specified directory
return null;
}
if (filterFiles && !filterFiles(filepath)) {
// Ignore out files that don't match any specified filter
return null;
}
if (!workdir) {
// File was deleted
deletions.push(filepath);
Expand Down
19 changes: 18 additions & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,24 @@ export interface CommitChangesFromRepoArgs extends CommitFilesBasedArgs {
/**
* The root of the repository.
*
* @default process.cwd()
* When unspecified, the root of the repository will be found by recursively
* searching for the `.git` directory from the current working directory.
*/
repoDirectory?: string;
/**
* The starting directory to recurse from when detecting changed files.
*
* Useful for monorepos where you want to add files from a specific directory only.
*
* Defaults to resolved value of {@link repoDirectory},
* which will add all changed files in the repository.
*/
addFromDirectory?: string;
/**
* An optional function that can be used to filter which files are included
* in the commit. True should be returned for files that should be included.
*
* By default, all files are included.
*/
filterFiles?: (file: string) => boolean;
}
Loading