Skip to content
Draft
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Follows [Semantic Versioning](https://semver.org/).

## Unreleased

### Added

- Support for storing git-mob settings in a custom git config file via the GITMOB_CONFIG_FILE environment variable. When set, git-mob will use git config --file <path> ... for its settings instead of --global. This is non-breaking and intended for per-machine / dotfiles workflows. (Closes #282)

### Tests

- Unit tests added to verify file-scoped vs global config behavior for git-mob settings.

## git-mob-core 0.10.1

### Fixed
Expand Down
8 changes: 8 additions & 0 deletions packages/git-mob-core/src/git-mob-api/config-scope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function configScopeFlag(): string {
const file = process.env.GITMOB_CONFIG_FILE;
if (file && file.length > 0) {
// callers should provide an absolute/expanded path
return `--file ${file}`;
}
return '--global';

Check failure on line 7 in packages/git-mob-core/src/git-mob-api/config-scope.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Expected blank line before this statement.

Check failure on line 7 in packages/git-mob-core/src/git-mob-api/config-scope.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Expected blank line before this statement.

Check failure on line 7 in packages/git-mob-core/src/git-mob-api/config-scope.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Expected blank line before this statement.
}
13 changes: 9 additions & 4 deletions packages/git-mob-core/src/git-mob-api/git-mob-config.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { getConfig, getAllConfig, execCommand } from './exec-command.js';
import { configScopeFlag } from './config-scope.js';

export async function localTemplate() {
const localTemplate = await getConfig('--local git-mob-config.use-local-template');
return localTemplate === 'true';
}

export async function fetchFromGitHub() {
const githubFetch = await getConfig('--global git-mob-config.github-fetch');
const scope = configScopeFlag();
const githubFetch = await getConfig(`${scope} git-mob-config.github-fetch`);
return githubFetch === 'true';
}

export async function getSetCoAuthors() {
return getAllConfig('--global git-mob.co-author');
const scope = configScopeFlag();
return getAllConfig(`${scope} git-mob.co-author`);
}

export async function addCoAuthor(coAuthor: string) {
const addAuthorQuery = `git config --add --global git-mob.co-author "${coAuthor}"`;
const scope = configScopeFlag();
const addAuthorQuery = `git config --add ${scope} git-mob.co-author "${coAuthor}"`;

return execCommand(addAuthorQuery);
}

export async function removeGitMobSection() {
try {
return await execCommand('git config --global --remove-section git-mob');
const scope = configScopeFlag();
return await execCommand(`git config ${scope} --remove-section git-mob`);
} catch {}
}
43 changes: 43 additions & 0 deletions packages/git-mob-core/test/git-mob-config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import test from 'ava';

Check failure on line 1 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

AVA ignores this file.

Check failure on line 1 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

AVA ignores this file.

Check failure on line 1 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

AVA ignores this file.
import sinon from 'sinon';

Check failure on line 2 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

'sinon' should be listed in the project's dependencies. Run 'npm i -S sinon' to add it

Check failure on line 2 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

'sinon' should be listed in the project's dependencies. Run 'npm i -S sinon' to add it

Check failure on line 2 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

'sinon' should be listed in the project's dependencies. Run 'npm i -S sinon' to add it
import * as execModule from '../src/git-mob-api/exec-command.js';
import * as gitMobConfig from '../src/git-mob-api/git-mob-config.js';

test.afterEach(() => {
delete process.env.GITMOB_CONFIG_FILE;
sinon.restore();

Check failure on line 8 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Caution: `sinon` also has a named export `restore`. Check if you meant to write `import {restore} from 'sinon'` instead.

Check failure on line 8 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Caution: `sinon` also has a named export `restore`. Check if you meant to write `import {restore} from 'sinon'` instead.

Check failure on line 8 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Caution: `sinon` also has a named export `restore`. Check if you meant to write `import {restore} from 'sinon'` instead.
});

test.serial('addCoAuthor uses --global when GITMOB_CONFIG_FILE not set', async t => {
const stub = sinon.stub(execModule, 'execCommand').resolves();

Check failure on line 12 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 12 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 12 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.
await gitMobConfig.addCoAuthor('Jane Doe <[email protected]>');
t.true(
stub.calledWith(
'git config --add --global git-mob.co-author "Jane Doe <[email protected]>"'
)
);
});

test.serial('addCoAuthor uses --file when GITMOB_CONFIG_FILE is set', async t => {
process.env.GITMOB_CONFIG_FILE = '/tmp/.gitconfig.local';
const stub = sinon.stub(execModule, 'execCommand').resolves();

Check failure on line 23 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 23 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 23 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.
await gitMobConfig.addCoAuthor('Bob Doe <[email protected]>');
t.true(
stub.calledWith(
'git config --add --file /tmp/.gitconfig.local git-mob.co-author "Bob Doe <[email protected]>"'
)
);
});

test.serial('getSetCoAuthors uses --global when GITMOB_CONFIG_FILE not set', async t => {

Check failure on line 32 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Replace `'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',` with `⏎··'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',⏎·`

Check failure on line 32 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Replace `'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',` with `⏎··'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',⏎·`

Check failure on line 32 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Replace `'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',` with `⏎··'getSetCoAuthors·uses·--global·when·GITMOB_CONFIG_FILE·not·set',⏎·`
const stub = sinon.stub(execModule, 'getAllConfig').resolves([]);

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Insert `··`

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Insert `··`

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Caution: `sinon` also has a named export `stub`. Check if you meant to write `import {stub} from 'sinon'` instead.

Check failure on line 33 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Insert `··`
await gitMobConfig.getSetCoAuthors();

Check failure on line 34 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 18

Replace `··` with `····`

Check failure on line 34 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 22

Replace `··` with `····`

Check failure on line 34 in packages/git-mob-core/test/git-mob-config.spec.ts

View workflow job for this annotation

GitHub Actions / Node.js 20

Replace `··` with `····`
t.true(stub.calledWith('--global git-mob.co-author'));
});

test.serial('getSetCoAuthors uses --file when GITMOB_CONFIG_FILE is set', async t => {
process.env.GITMOB_CONFIG_FILE = '/tmp/customgitconfig';
const stub = sinon.stub(execModule, 'getAllConfig').resolves([]);
await gitMobConfig.getSetCoAuthors();
t.true(stub.calledWith('--file /tmp/customgitconfig git-mob.co-author'));
});
40 changes: 34 additions & 6 deletions packages/git-mob/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

_Add co-authors to commits_ when you collaborate on code. Use when pairing with a buddy or mobbing with your team.

<a href="https://www.buymeacoffee.com/rkotze" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-green.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 180px !important;" ></a>
<a href="https://www.buymeacoffee.com/rkotze" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-green.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 180px ..." /></a>

[✨ Git Mob VS Code extension](https://github.com/rkotze/git-mob-vs-code)

Expand All @@ -23,6 +23,7 @@ _Add co-authors to commits_ when you collaborate on code. Use when pairing with
- [Git Mob config](#git-mob-config)
- [Use local commit template](#use-local-commit-template)
- [Enable GitHub author fetch](#enable-github-author-fetch)
- [Use a custom git config file for git-mob settings](#use-a-custom-git-config-file-for-git-mob-settings)
- [More commands](#more-commands)
- [List all co-authors](#list-all-co-authors)
- [Overwrite the main author](#overwrite-the-main-author)
Expand Down Expand Up @@ -126,9 +127,9 @@ $ git solo
Jane Doe <[email protected]>
```

Selected co-authors are **stored globally** meaning when switching between projects your co-authors stay the same\*.
Selected co-authors are **stored globally** meaning when switching between projects your co-authors stay the same*.

**\*Note**: If you've set a **local** commit template in your config then that template will be updated. However, **not** when you switch projects and you will see a warning. You can run `git mob` to update the commit template. [Read more here](https://github.com/rkotze/git-mob/discussions/81)
**\*Note**: If you've set a **local** commit template in your config then set this option to `true`. Only reads from the local git config. The README previously had additional content here.

### Add co-author from GitHub

Expand All @@ -149,7 +150,7 @@ How to append co-authors to the message when using message flag - `git commit -m
1. Add `prepare-commit-msg` hook file in `.git/hooks` dir. See [hook-examples](https://github.com/rkotze/git-mob/tree/master/hook-examples)
2. The **hook** will need to be executable `chmod +x prepare-commit-msg`

`prepare-commit-msg` will need a script to read the co-authors, which can be done via `git mob-print`. See [hook-examples](https://github.com/rkotze/git-mob/tree/master/hook-examples) folder for working scripts.
`prepare-commit-msg` will need a script to read the co-authors, which can be done via `git mob-print`. See [hook-examples](https://github.com/rkotze/git-mob/tree/master/hook-examples) folder for ...

The command `git mob-print` will output to `stdout` the formatted co-authors.

Expand Down Expand Up @@ -196,6 +197,33 @@ To fetch authors from GitHub you need to enable it using the config.

`git config --global git-mob-config.github-fetch true`

### Use a custom git config file for git-mob settings

By default git-mob stores selected co-authors and related settings in your global Git config. To keep machine-specific settings out of your dotfiles you can tell git-mob to write/read its settings from a custom git config file by setting the GITMOB_CONFIG_FILE environment variable.

Example:
```bash
export GITMOB_CONFIG_FILE="$HOME/.gitconfig.local"
```

When GITMOB_CONFIG_FILE is set, git-mob will use:
- git config --file <path> ... for git-mob settings (for example adding/removing git-mob.co-author), instead of git config --global ...
- repository-local settings (git config --local ...) are unchanged and still operate at the repository scope.

Notes:
- Provide an absolute/expanded path (the leading `~` is not expanded automatically).
- This is non-breaking: when the env var is not set git-mob continues to use the global config as before.
- Useful for per-machine dotfiles workflows where a machine-specific include is used in ~/.gitconfig.

Example usage:
```bash
# Add a co-author to the per-machine config file
export GITMOB_CONFIG_FILE="$HOME/.gitconfig.local"
git add-coauthor jd "Jane Doe" [email protected]
# Or add directly to the file via git config
git config --add --file "$GITMOB_CONFIG_FILE" git-mob.co-author "jd Jane Doe <[email protected]>"
```

## More commands

### List all co-authors
Expand Down Expand Up @@ -273,7 +301,7 @@ function git_initials {
fi
}

export PS1="\$(pwd)\$(git_initials) -> "
export PS1="$(pwd)$(git_initials) -> "
```

#### Fish
Expand All @@ -299,4 +327,4 @@ end

Read our blog post to find out why git-mob exists: [Co-author commits with Git Mob](http://tech.findmypast.com/co-author-commits-with-git-mob)

<sup>\* [If you have git-duet installed, you'll need to uninstall it](https://github.com/rkotze/git-mob/issues/2) since it conflicts with the git-solo command.</sup>
<sup>* [If you have git-duet installed, you'll need to uninstall it](https://github.com/rkotze/git-mob/issues/2) since it conflicts with the git-solo command.</sup>