@anhducmata/git-manager 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -18
- package/index.js +62 -4
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@ If you use **multiple GitHub/GitLab accounts** on one laptop (e.g. Work + Person
|
|
|
8
8
|
|
|
9
9
|
## ✨ Features
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **Per-repo config** — `gitm init` sets the account locally for each repo (recommended)
|
|
12
|
+
- **Global switch** — `gitm switch` changes the global config when you need it
|
|
12
13
|
- **Auto-generates SSH keys** — creates a dedicated `ed25519` key per profile
|
|
13
14
|
- **No more SSH conflicts** — uses `core.sshCommand` with `IdentitiesOnly=yes` so Git always uses the correct key
|
|
14
15
|
- **Interactive prompts** — no flags to memorize, just follow the menu
|
|
@@ -58,23 +59,22 @@ gitm new
|
|
|
58
59
|
|
|
59
60
|
Repeat the same process for your other account (e.g. `Personal`).
|
|
60
61
|
|
|
61
|
-
### 3.
|
|
62
|
+
### 3. Set account per repo (recommended)
|
|
62
63
|
|
|
63
64
|
```bash
|
|
64
|
-
|
|
65
|
+
cd ~/projects/work-project
|
|
66
|
+
gitm init
|
|
65
67
|
```
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
This sets the Git user + SSH key **locally** for that repo only. Other repos are not affected.
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
Current active user: John Doe <john@work.com>
|
|
71
|
+
### 4. Or switch globally
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
Personal (Johnny <johnny@gmail.com>)
|
|
73
|
+
```bash
|
|
74
|
+
gitm switch
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
This changes the global Git config — useful when you want to quickly switch everything at once.
|
|
78
78
|
|
|
79
79
|
---
|
|
80
80
|
|
|
@@ -83,8 +83,9 @@ Select the one you want — done! Your Git user **and** SSH key are both switche
|
|
|
83
83
|
| Command | Description |
|
|
84
84
|
|---|---|
|
|
85
85
|
| `gitm new` | Add a new Git account with SSH key |
|
|
86
|
-
| `gitm
|
|
87
|
-
| `gitm
|
|
86
|
+
| `gitm init` | Set account for current repo (local config) |
|
|
87
|
+
| `gitm switch` | Switch global git account |
|
|
88
|
+
| `gitm list` / `gitm ls` | Show all saved accounts + current active user |
|
|
88
89
|
| `gitm remove` | Remove a saved account (optionally delete its SSH key) |
|
|
89
90
|
| `gitm --help` | Show help |
|
|
90
91
|
|
|
@@ -92,17 +93,19 @@ Select the one you want — done! Your Git user **and** SSH key are both switche
|
|
|
92
93
|
|
|
93
94
|
## 🔧 How It Works
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
`gitm init` (local, per-repo) and `gitm switch` (global) both do the same three things:
|
|
96
97
|
|
|
97
98
|
```bash
|
|
98
99
|
# 1. Set Git identity
|
|
99
|
-
git config --global user.name "Your Name"
|
|
100
|
-
git config --global user.email "your@email.com"
|
|
100
|
+
git config [--local|--global] user.name "Your Name"
|
|
101
|
+
git config [--local|--global] user.email "your@email.com"
|
|
101
102
|
|
|
102
103
|
# 2. Force Git to use the correct SSH key
|
|
103
|
-
git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_gm_work -o IdentitiesOnly=yes"
|
|
104
|
+
git config [--local|--global] core.sshCommand "ssh -i ~/.ssh/id_ed25519_gm_work -o IdentitiesOnly=yes"
|
|
104
105
|
```
|
|
105
106
|
|
|
107
|
+
> 💡 **Tip:** Use `gitm init` per repo so each project is permanently tied to the right account. Use `gitm switch` only when you need a quick global change.
|
|
108
|
+
|
|
106
109
|
The `IdentitiesOnly=yes` flag is critical — it tells SSH to **only** use the specified key and ignore any other keys loaded in your SSH agent. This prevents the common problem where `git push` uses the wrong account.
|
|
107
110
|
|
|
108
111
|
---
|
|
@@ -127,9 +130,9 @@ Yes! When `gitm new` asks for the SSH key path, just type the full path to your
|
|
|
127
130
|
? Enter SSH key path: /Users/you/.ssh/id_rsa
|
|
128
131
|
```
|
|
129
132
|
|
|
130
|
-
###
|
|
133
|
+
### Should I use `gitm init` or `gitm switch`?
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
Use `gitm init` — it sets config **locally** per repo, so each project always uses the correct account. Use `gitm switch` only when you need a quick global change and don't want to configure each repo individually.
|
|
133
136
|
|
|
134
137
|
### What if I already have `~/.ssh/config` set up?
|
|
135
138
|
|
package/index.js
CHANGED
|
@@ -11,6 +11,9 @@ import { execSync } from 'child_process';
|
|
|
11
11
|
const configDir = path.join(os.homedir(), '.config', 'git-manager');
|
|
12
12
|
const accountsFile = path.join(configDir, 'accounts.json');
|
|
13
13
|
|
|
14
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
15
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf-8'));
|
|
16
|
+
|
|
14
17
|
// Ensure config dir exists
|
|
15
18
|
if (!fs.existsSync(configDir)) {
|
|
16
19
|
fs.mkdirSync(configDir, { recursive: true });
|
|
@@ -43,10 +46,11 @@ function getCurrentGitUser() {
|
|
|
43
46
|
program
|
|
44
47
|
.name('gitm')
|
|
45
48
|
.description('Git Account Manager CLI')
|
|
46
|
-
.version(
|
|
49
|
+
.version(pkg.version);
|
|
47
50
|
|
|
48
51
|
program
|
|
49
52
|
.command('list')
|
|
53
|
+
.alias('ls')
|
|
50
54
|
.description('List all available git accounts')
|
|
51
55
|
.action(() => {
|
|
52
56
|
const accounts = loadAccounts();
|
|
@@ -137,7 +141,7 @@ function switchAccount(profileName, accounts) {
|
|
|
137
141
|
|
|
138
142
|
program
|
|
139
143
|
.command('switch')
|
|
140
|
-
.description('Switch
|
|
144
|
+
.description('Switch global git account')
|
|
141
145
|
.action(async () => {
|
|
142
146
|
const accounts = loadAccounts();
|
|
143
147
|
if (accounts.length === 0) {
|
|
@@ -146,7 +150,7 @@ program
|
|
|
146
150
|
}
|
|
147
151
|
|
|
148
152
|
const current = getCurrentGitUser();
|
|
149
|
-
console.log(chalk.blue(`Current
|
|
153
|
+
console.log(chalk.blue(`Current global user: ${current.name} <${current.email}>\n`));
|
|
150
154
|
|
|
151
155
|
const choices = accounts.map(acc => ({
|
|
152
156
|
name: `${acc.profileName} (${acc.name} <${acc.email}>)`,
|
|
@@ -154,13 +158,67 @@ program
|
|
|
154
158
|
}));
|
|
155
159
|
|
|
156
160
|
const selectedProfile = await select({
|
|
157
|
-
message: 'Select an account to switch to:',
|
|
161
|
+
message: 'Select an account to switch to (global):',
|
|
158
162
|
choices
|
|
159
163
|
});
|
|
160
164
|
|
|
161
165
|
switchAccount(selectedProfile, accounts);
|
|
162
166
|
});
|
|
163
167
|
|
|
168
|
+
program
|
|
169
|
+
.command('init')
|
|
170
|
+
.description('Set git account for the current repo (local config)')
|
|
171
|
+
.action(async () => {
|
|
172
|
+
// Check if we're in a git repo
|
|
173
|
+
try {
|
|
174
|
+
execSync('git rev-parse --git-dir', { stdio: 'ignore' });
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.log(chalk.red('Not a git repository. Run this inside a git project.'));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const accounts = loadAccounts();
|
|
181
|
+
if (accounts.length === 0) {
|
|
182
|
+
console.log(chalk.yellow('No accounts found. Add one with `gitm new`.'));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Show current local config if any
|
|
187
|
+
try {
|
|
188
|
+
const localName = execSync('git config --local user.name').toString().trim();
|
|
189
|
+
const localEmail = execSync('git config --local user.email').toString().trim();
|
|
190
|
+
console.log(chalk.blue(`Current local config: ${localName} <${localEmail}>\n`));
|
|
191
|
+
} catch (e) {
|
|
192
|
+
console.log(chalk.gray('No local git config set for this repo yet.\n'));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const choices = accounts.map(acc => ({
|
|
196
|
+
name: `${acc.profileName} (${acc.name} <${acc.email}>)`,
|
|
197
|
+
value: acc.profileName
|
|
198
|
+
}));
|
|
199
|
+
|
|
200
|
+
const selectedProfile = await select({
|
|
201
|
+
message: 'Select an account for this repo:',
|
|
202
|
+
choices
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const account = accounts.find(a => a.profileName === selectedProfile);
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
execSync(`git config --local user.name "${account.name}"`);
|
|
209
|
+
execSync(`git config --local user.email "${account.email}"`);
|
|
210
|
+
execSync(`git config --local core.sshCommand "ssh -i ${account.sshKeyPath} -o IdentitiesOnly=yes"`);
|
|
211
|
+
|
|
212
|
+
console.log(chalk.green(`\nThis repo is now using profile '${account.profileName}'!`));
|
|
213
|
+
console.log(chalk.cyan(`User: ${account.name}`));
|
|
214
|
+
console.log(chalk.cyan(`Email: ${account.email}`));
|
|
215
|
+
console.log(chalk.cyan(`SSH: ${account.sshKeyPath}`));
|
|
216
|
+
console.log(chalk.gray('\nThis config is local — it won\'t affect other repos.'));
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.log(chalk.red('Failed to set local config:', error.message));
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
164
222
|
program
|
|
165
223
|
.command('remove')
|
|
166
224
|
.description('Remove a git account')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anhducmata/git-manager",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "CLI to easily manage and switch between multiple Git accounts",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,17 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
12
|
},
|
|
13
|
-
"keywords": [
|
|
13
|
+
"keywords": [
|
|
14
|
+
"git",
|
|
15
|
+
"git-account",
|
|
16
|
+
"git-switch",
|
|
17
|
+
"ssh",
|
|
18
|
+
"ssh-key",
|
|
19
|
+
"multiple-accounts",
|
|
20
|
+
"git-manager",
|
|
21
|
+
"git-profile",
|
|
22
|
+
"cli"
|
|
23
|
+
],
|
|
14
24
|
"author": "",
|
|
15
25
|
"license": "ISC",
|
|
16
26
|
"dependencies": {
|