A command-line collection of Git utilities for automatic per-file commits, historical commit scheduling, sharing changed files, and safe project stashing.
Install globally with npm:
npm install --global commit-masterOr with Yarn:
yarn global add commit-masterOr with pnpm:
pnpm add --global commit-masterOne global installation exposes all five commands: gitauto, gitspan, gitpaths, gitbundle, and gitstash. Node.js 18.18 or newer and Git are required; no package manager is required at runtime.
If you prefer to use this workflow inside Visual Studio Code, install the Auto Commit Master extension from the Visual Studio Marketplace.
The extension provides the Visual Studio Code experience, while this package provides the gitauto, gitspan, gitpaths, gitbundle, and gitstash terminal commands.
Open your Git project in the terminal, or navigate to the project directory:
cd path/to/your-projectThen run one of the available commands inside that project:
gitauto
gitspan <duration> <commits-per-day>
gitpaths
gitbundle
gitstash ["stash title"]The commands work with the Git repository of the currently opened project.
If the current project is not a Git repository, an interactive terminal asks:
Git is not initialized in this project.
Initialize it now? (Y/n)
Press Enter or answer Yes to initialize Git in the current directory and continue the original command automatically. Answer No to cancel without changing the project.
CI, redirected input, and other non-interactive environments never initialize Git or wait for input. They ask you to initialize Git before running Commit Master. Git identity is never created or changed automatically.
This initialization flow applies to all five commands. After confirmation, the original command continues automatically in the newly initialized repository.
Use gitauto inside your project to commit every current file change separately:
gitautoEach added, updated, deleted, or renamed file receives its own commit.
Example commit messages:
Add users.ts
Update package.json
Delete legacy-config.ts
Rename old-name.ts to new-name.ts
Use gitspan inside your project to distribute current file changes across previous calendar days:
gitspan 10 5Arguments:
10 = number of days
5 = maximum commits per day
The command automatically calculates how many days are required based on the number of changed files. Scheduling ignores the existing HEAD commit timestamp and only uses historical dates up through the current time, so a recent latest commit does not reduce capacity.
For example, 58 file changes with a limit of 5 commits per day will be distributed across 12 days. With 119 changes and gitspan 10 5, the range expands to 24 days.
Use gitpaths to copy the absolute paths of eligible uncommitted files:
gitpathsIt collects staged changes, unstaged tracked changes, and untracked non-ignored files from the complete resolved repository. Deleted paths are included, and a rename appears once under its new path. Results are deduplicated and sorted by path. Sensitive files remain visible as paths, but gitpaths never reads their contents.
Example clipboard content:
/completeProjectPath/Design.md
/completeProjectPath/package.json
/completeProjectPath/src/components/Icon.vue
/completeProjectPath/src/index.ts
After a successful copy, the command prints 8 file paths copied. using the actual count. A clean tree does not overwrite the clipboard.
Use gitbundle to copy the complete current contents of eligible changed files as Markdown:
gitbundleExample clipboard content:
Repository: /completeProjectPath
### /completeProjectPath/package.json
```json
{
"name": "example"
}
```
### /completeProjectPath/src/index.ts
```ts
export const ready = true
```
------------------------------The bundle uses an extension-appropriate code-fence language and automatically lengthens fences when file content contains backticks. It uses these explicit placeholders:
[SENSITIVE FILE OMITTED]for environment files, credentials, private keys, and other protected files[FILE DELETED]for deleted files[FILE NOT FOUND]when a changed file disappears before it can be read[FILE UNREADABLE]for inaccessible or replaced files[FILE TOO LARGE]when one file exceeds 1 MiB[BINARY FILE OMITTED]for binary or unsupported special-file content
Commit Master never silently truncates file content. Individual files are limited to 1 MiB and the complete Markdown bundle is limited to 10 MiB. If the total limit is exceeded, the command stops before invoking the clipboard provider. Symbolic links are represented by their link target text and are never followed outside the repository.
After success, gitbundle prints 8 changed files bundled and copied. using the actual count.
Both clipboard commands use one shared ignore policy. Git's own ignore rules are respected first. Commit Master additionally excludes:
- Exact names:
yarn.lock,pnpm-lock.yaml,bun.lockb,Cargo.lock,generated.ts,mongoose.gen.ts,resolvers.generated.ts,typeDefs.generated.ts,types.generated.ts,tsconfig.tsbuildinfo,tsconfig.node.tsbuildinfo, and.DS_Store. - Generated patterns:
*.generated.tsandvite.config.ts.timestamp-*. - Directories at any depth:
_locales,src-tauri/target,gen,temp,ffmpeg,migrations,sql,dist,.xcode,vendor/bundle,.git,Pods,.nuxt,.next,.idea,.bundle,node_modules, andcache. - Extensions:
.log,.sql,.onnx,.TAG,.pdf,.docx,.csv, common image/audio/video formats, archives, database files, WebAssembly, and native binaries.
Filename, extension, and directory matching is case-insensitive and works at any nesting level. package.json is intentionally included. The centralized eligibility rules apply identically to gitpaths and gitbundle.
Sensitive paths—including .env variants, private-key formats, credential JSON files, .npmrc, .pypirc, and .netrc—remain in the shared eligible list. gitpaths copies only their paths, while gitbundle replaces their content with [SENSITIVE FILE OMITTED], even when the file is already tracked by Git.
Control characters in copied path displays are escaped as readable sequences such as \n, \r, and \t; the real path remains unchanged for filesystem access. Markdown-sensitive heading characters are escaped without altering valid Unicode names.
Commit Master supports macOS, Windows, and Linux without shell-string execution. It uses the native macOS and Windows clipboard tools, with PowerShell preferred on Windows for reliable Unicode text. On Linux it uses the first available supported clipboard provider: wl-copy, xclip, xsel, PowerShell or clip.exe under WSL, or Termux clipboard tools.
The command reports success only after the clipboard process exits successfully. On Linux, if no supported provider is available, it reports:
Unable to copy to the clipboard.
Install wl-copy, xclip, or xsel.
Pressing Ctrl+C exits with status 130 and reports Copy cancelled. followed by The clipboard was not updated. Commit-specific counts are not shown for clipboard commands.
Use gitstash to save all current repository changes in a new Git stash:
gitstashThe default stash title is Commit Master stash. Provide one quoted argument to use an exact custom title containing spaces, Unicode, or punctuation:
gitstash "Before updating authentication"Additional positional arguments are rejected with the concise gitstash usage message. The single accepted argument is always treated as the stash title, not as a Git option.
The command includes modified, staged, deleted, renamed, and untracked non-ignored files. Git-ignored files remain untouched. After success, both the working tree and staging area are clean, and all earlier stash entries remain available below the newly created stash@{0}.
Success output is intentionally minimal:
Changes stashed successfully.
Changes stashed successfully: Before updating authentication
A clean repository returns Nothing to stash. The working tree is clean. without creating an empty entry. Unsafe merge, rebase, cherry-pick, revert, bisect, or conflict states are rejected before stash creation.
When Git is initialized through Commit Master, gitstash continues automatically and supports the unborn repository by using a temporary internal base. That base is removed from the branch after the stash is verified; no user commit is left behind.
Git must be able to resolve the user's configured identity because stash entries are stored as Git commit objects. Commit Master never invents or changes that identity.
Ctrl+C before stash creation exits with status 130 and reports:
Stash cancelled.
Your changes were not removed.
If interruption arrives after Git created the stash, Commit Master verifies refs/stash and the working tree before reporting the final state.
Use standard Git commands to inspect or restore saved changes:
git stash list
git stash apply
git stash popgitstash only creates a stash; it never applies, pops, deletes, or overwrites an existing entry.
The toolkit:
- Uses the Git repository of the currently opened project.
- Offers to initialize Git in the current project when needed.
- Finds added, modified, deleted, and renamed files.
- Creates one commit for each logical file change.
- Generates a clear commit message from the change type.
- Uses the current timestamp with
gitauto. - Generates chronological backdated timestamps with
gitspan, independent of the existingHEADtimestamp. - Automatically expands the date range further into the past when more days are required.
- Copies absolute changed-file paths with
gitpaths. - Creates complete Markdown change bundles with
gitbundle. - Saves staged, unstaged, and untracked project changes with
gitstash. - Preserves existing commits and working-tree changes.
- Stops commit creation safely when the repository contains pre-existing staged changes, conflicts, or an active Git operation; clipboard commands intentionally include staged changes.
Open your project:
cd path/to/your-projectCommit all current changes immediately:
gitautoDistribute commits across 10 days with up to 5 commits per day:
gitspan 10 5Distribute commits across 30 days with up to 3 commits per day:
gitspan 30 3Copy changed-file paths:
gitpathsCopy changed-file contents as a Markdown bundle:
gitbundleStash all project changes with the default title:
gitstashStash all project changes with a custom title:
gitstash "Work in progress"