resulgit 1.0.6 → 1.0.8
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 +13 -8
- package/package.json +1 -1
- package/resulgit.js +91 -9
package/README.md
CHANGED
|
@@ -37,10 +37,12 @@ resulgit <command> [options]
|
|
|
37
37
|
- `resulgit repo head --repo <id> [--branch <name>]` - Get HEAD commit
|
|
38
38
|
- `resulgit repo select` - Interactive repository selection
|
|
39
39
|
|
|
40
|
-
### Clone &
|
|
40
|
+
### Clone & Initialize
|
|
41
41
|
|
|
42
|
-
- `resulgit init
|
|
43
|
-
- `resulgit
|
|
42
|
+
- `resulgit init <name>` - Initialize a new repository (creates folder and remote repo automatically)
|
|
43
|
+
- `resulgit init <name> --dir <path>` - Initialize in a specific directory
|
|
44
|
+
- `resulgit clone <name>` - Clone a repository by name
|
|
45
|
+
- `resulgit clone --repo <name> --branch <branch>` - Clone with specific branch
|
|
44
46
|
- `resulgit workspace set-root --path <dir>` - Set workspace root directory
|
|
45
47
|
|
|
46
48
|
### Branch Operations
|
|
@@ -63,6 +65,8 @@ resulgit <command> [options]
|
|
|
63
65
|
### Version Control
|
|
64
66
|
|
|
65
67
|
- `resulgit commit --message <text>` - Create a commit
|
|
68
|
+
- `resulgit commit -m <text>` - Short form (same as above)
|
|
69
|
+
- `resulgit commit -a -m <text>` - Add all changes and commit
|
|
66
70
|
- `resulgit push` - Push changes to remote
|
|
67
71
|
- `resulgit pull` - Pull changes from remote
|
|
68
72
|
- `resulgit merge --branch <name> [--squash] [--no-push]` - Merge branches
|
|
@@ -131,18 +135,19 @@ resulgit auth login --email user@example.com --password mypassword
|
|
|
131
135
|
# List repositories
|
|
132
136
|
resulgit repo list
|
|
133
137
|
|
|
134
|
-
# Initialize a new repository
|
|
135
|
-
resulgit init
|
|
138
|
+
# Initialize a new repository (creates folder + remote repo automatically)
|
|
139
|
+
resulgit init MyProject
|
|
136
140
|
|
|
137
|
-
#
|
|
138
|
-
resulgit clone
|
|
141
|
+
# Or clone an existing repository
|
|
142
|
+
resulgit clone MyProject
|
|
139
143
|
|
|
140
144
|
# Check status
|
|
145
|
+
cd MyProject
|
|
141
146
|
resulgit status
|
|
142
147
|
|
|
143
148
|
# Create and commit changes
|
|
144
149
|
resulgit add file.txt --content "Hello World"
|
|
145
|
-
resulgit commit
|
|
150
|
+
resulgit commit -m "Add file.txt"
|
|
146
151
|
resulgit push
|
|
147
152
|
|
|
148
153
|
# Create a branch
|
package/package.json
CHANGED
package/resulgit.js
CHANGED
|
@@ -37,12 +37,20 @@ function parseArgs(argv) {
|
|
|
37
37
|
const t = tokens[i]
|
|
38
38
|
if (t.startsWith('--')) {
|
|
39
39
|
const key = t.slice(2)
|
|
40
|
-
const val = tokens[i + 1] && !tokens[i + 1].startsWith('
|
|
40
|
+
const val = tokens[i + 1] && !tokens[i + 1].startsWith('-') ? tokens[++i] : 'true'
|
|
41
|
+
opts[key] = val
|
|
42
|
+
} else if (t.startsWith('-') && t.length === 2) {
|
|
43
|
+
// Short flag like -m, -a
|
|
44
|
+
const key = t.slice(1)
|
|
45
|
+
const val = tokens[i + 1] && !tokens[i + 1].startsWith('-') ? tokens[++i] : 'true'
|
|
41
46
|
opts[key] = val
|
|
42
47
|
} else if (cmd.length < 2) {
|
|
43
48
|
cmd.push(t)
|
|
44
49
|
}
|
|
45
50
|
}
|
|
51
|
+
// Map short flags to long flags
|
|
52
|
+
if (opts.m && !opts.message) { opts.message = opts.m; delete opts.m }
|
|
53
|
+
if (opts.a && !opts.all) { opts.all = opts.a; delete opts.a }
|
|
46
54
|
return { cmd, opts }
|
|
47
55
|
}
|
|
48
56
|
|
|
@@ -2297,7 +2305,6 @@ async function cmdReset(opts) {
|
|
|
2297
2305
|
}
|
|
2298
2306
|
|
|
2299
2307
|
async function cmdInit(opts) {
|
|
2300
|
-
const dir = path.resolve(opts.dir || '.')
|
|
2301
2308
|
const cfg = loadConfig()
|
|
2302
2309
|
const server = getServer(opts, cfg)
|
|
2303
2310
|
const token = getToken(opts, cfg)
|
|
@@ -2305,8 +2312,71 @@ async function cmdInit(opts) {
|
|
|
2305
2312
|
const repo = opts.repo ? validation.validateRepoName(opts.repo) : ''
|
|
2306
2313
|
// Branch name defaults to 'main' if not supplied
|
|
2307
2314
|
const branch = opts.branch ? opts.branch : 'main'
|
|
2308
|
-
|
|
2309
|
-
|
|
2315
|
+
|
|
2316
|
+
// Determine target directory:
|
|
2317
|
+
// - If --dir is specified, use that
|
|
2318
|
+
// - Otherwise, if repo name is provided, create folder with that name
|
|
2319
|
+
// - Fallback to current directory
|
|
2320
|
+
let targetDir
|
|
2321
|
+
if (opts.dir) {
|
|
2322
|
+
targetDir = path.resolve(opts.dir)
|
|
2323
|
+
} else if (repo) {
|
|
2324
|
+
targetDir = path.resolve(repo)
|
|
2325
|
+
} else {
|
|
2326
|
+
targetDir = path.resolve('.')
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
// Create the target directory if it doesn't exist
|
|
2330
|
+
await fs.promises.mkdir(targetDir, { recursive: true })
|
|
2331
|
+
|
|
2332
|
+
const spinner = createSpinner(`Initializing repository${repo ? ` '${repo}'` : ''}...`, opts.json)
|
|
2333
|
+
|
|
2334
|
+
let repoId = repo
|
|
2335
|
+
let remoteCreated = false
|
|
2336
|
+
|
|
2337
|
+
// If a repo name is provided and we have server, try to create remote repo
|
|
2338
|
+
if (repo && server) {
|
|
2339
|
+
if (!token) {
|
|
2340
|
+
spinnerUpdate(spinner, 'No auth token set. Run "resulgit auth login" first for remote repo creation.')
|
|
2341
|
+
}
|
|
2342
|
+
try {
|
|
2343
|
+
spinnerUpdate(spinner, 'Creating remote repository...')
|
|
2344
|
+
const createUrl = new URL('/api/repositories', server).toString()
|
|
2345
|
+
const createRes = await request('POST', createUrl, {
|
|
2346
|
+
name: repo,
|
|
2347
|
+
description: opts.description || '',
|
|
2348
|
+
visibility: opts.visibility || 'private',
|
|
2349
|
+
initializeWithReadme: false
|
|
2350
|
+
}, token)
|
|
2351
|
+
// Use the ID returned by the server (could be numeric or string)
|
|
2352
|
+
repoId = String(createRes.id || repo)
|
|
2353
|
+
remoteCreated = true
|
|
2354
|
+
spinnerUpdate(spinner, `Remote repository '${repo}' created (ID: ${repoId})`)
|
|
2355
|
+
} catch (err) {
|
|
2356
|
+
// If repo already exists (409), try to fetch its ID
|
|
2357
|
+
if (err.message && (err.message.includes('409') || err.message.includes('already exists'))) {
|
|
2358
|
+
spinnerUpdate(spinner, `Remote repository '${repo}' already exists, linking...`)
|
|
2359
|
+
try {
|
|
2360
|
+
const listUrl = new URL('/api/repositories', server).toString()
|
|
2361
|
+
const repos = await request('GET', listUrl, null, token)
|
|
2362
|
+
const found = (repos || []).find(r => r.name === repo)
|
|
2363
|
+
if (found) {
|
|
2364
|
+
repoId = String(found.id)
|
|
2365
|
+
remoteCreated = true
|
|
2366
|
+
}
|
|
2367
|
+
} catch { /* ignore */ }
|
|
2368
|
+
} else if (err.message && err.message.includes('401')) {
|
|
2369
|
+
spinnerUpdate(spinner, 'Authentication required. Run "resulgit auth login" to set up credentials.')
|
|
2370
|
+
} else {
|
|
2371
|
+
// Other error - continue with local init only
|
|
2372
|
+
spinnerUpdate(spinner, `Could not create remote repo: ${err.message}`)
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
spinnerUpdate(spinner, 'Setting up local repository...')
|
|
2378
|
+
const metaDir = path.join(targetDir, '.vcs-next')
|
|
2379
|
+
const gitDir = path.join(targetDir, '.git')
|
|
2310
2380
|
await fs.promises.mkdir(metaDir, { recursive: true })
|
|
2311
2381
|
await fs.promises.mkdir(path.join(gitDir, 'refs', 'heads'), { recursive: true })
|
|
2312
2382
|
await fs.promises.writeFile(path.join(gitDir, 'HEAD'), `ref: refs/heads/${branch}\n`, 'utf8')
|
|
@@ -2320,16 +2390,24 @@ async function cmdInit(opts) {
|
|
|
2320
2390
|
'',
|
|
2321
2391
|
'[vcs-next]',
|
|
2322
2392
|
`\tserver = ${opts.server || server || ''}`,
|
|
2323
|
-
`\trepoId = ${
|
|
2393
|
+
`\trepoId = ${repoId}`,
|
|
2324
2394
|
`\tbranch = ${branch}`,
|
|
2325
2395
|
`\ttoken = ${opts.token || token || ''}`
|
|
2326
2396
|
].join('\n')
|
|
2327
2397
|
await fs.promises.writeFile(path.join(gitDir, 'config'), gitConfig, 'utf8')
|
|
2328
|
-
const remoteMeta = { repoId:
|
|
2398
|
+
const remoteMeta = { repoId: repoId, branch, commitId: '', server: opts.server || server || '', token: opts.token || token || '' }
|
|
2329
2399
|
await fs.promises.writeFile(path.join(metaDir, 'remote.json'), JSON.stringify(remoteMeta, null, 2))
|
|
2330
2400
|
const localMeta = { baseCommitId: '', baseFiles: {}, pendingCommit: null }
|
|
2331
2401
|
await fs.promises.writeFile(path.join(metaDir, 'local.json'), JSON.stringify(localMeta, null, 2))
|
|
2332
|
-
|
|
2402
|
+
|
|
2403
|
+
if (remoteCreated) {
|
|
2404
|
+
spinnerSuccess(spinner, `Initialized repository '${repo}' in ${targetDir} (remote linked)`)
|
|
2405
|
+
} else if (repo) {
|
|
2406
|
+
spinnerSuccess(spinner, `Initialized local repository in ${targetDir} (remote not created - check auth)`)
|
|
2407
|
+
} else {
|
|
2408
|
+
spinnerSuccess(spinner, `Initialized repository in ${targetDir}`)
|
|
2409
|
+
}
|
|
2410
|
+
print({ initialized: targetDir, branch, repoId: repoId, remoteCreated }, opts.json === 'true')
|
|
2333
2411
|
}
|
|
2334
2412
|
|
|
2335
2413
|
async function cmdMv(opts) {
|
|
@@ -3168,8 +3246,12 @@ async function main() {
|
|
|
3168
3246
|
return
|
|
3169
3247
|
}
|
|
3170
3248
|
if (cmd[0] === 'init') {
|
|
3171
|
-
|
|
3172
|
-
|
|
3249
|
+
// Allow positional repo name: resulgit init MyRepo
|
|
3250
|
+
if (cmd[1] && !cmd[1].startsWith('-') && !opts.repo) {
|
|
3251
|
+
opts.repo = cmd[1];
|
|
3252
|
+
}
|
|
3253
|
+
await cmdInit(opts);
|
|
3254
|
+
return;
|
|
3173
3255
|
}
|
|
3174
3256
|
if (cmd[0] === 'remote') {
|
|
3175
3257
|
await cmdRemote(cmd[1], opts)
|