gent-cli 9.0.0 → 9.1.0
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/package.json +1 -1
- package/src/commands/commit.js +3 -0
- package/src/commands/explain.js +4 -3
- package/src/commands/push.js +38 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gent-cli",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"description": "A modern, Git-like version control CLI with cloud sync, AI-powered superpowers (ask/review/docs/changelog), and zero-friction setup (gent setup/doctor/config).",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/commands/commit.js
CHANGED
|
@@ -89,6 +89,9 @@ async function commit(options) {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// ponytail: accounts with no name set fall back to email as identity
|
|
93
|
+
if (!authorName && authorEmail) authorName = authorEmail;
|
|
94
|
+
|
|
92
95
|
if (!authorName || !authorEmail) {
|
|
93
96
|
spinner.stop();
|
|
94
97
|
console.error(chalk.red('Author identity unknown'));
|
package/src/commands/explain.js
CHANGED
|
@@ -91,9 +91,10 @@ async function explain(ref, options = {}) {
|
|
|
91
91
|
);
|
|
92
92
|
void stagedTree;
|
|
93
93
|
} else {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const headHash = repository.branches[repository.currentBranch];
|
|
95
|
+
const targetHash = (!ref || ref === 'HEAD')
|
|
96
|
+
? headHash
|
|
97
|
+
: (commits.find(c => c.hash === ref || c.hash.startsWith(ref)) || {}).hash;
|
|
97
98
|
const commit = targetHash ? commitMap.get(targetHash) : null;
|
|
98
99
|
if (!commit) {
|
|
99
100
|
console.log(chalk.yellow(ref ? `Commit '${ref}' not found` : 'No commits yet'));
|
package/src/commands/push.js
CHANGED
|
@@ -95,9 +95,15 @@ async function push(remoteName, branchName, options) {
|
|
|
95
95
|
|
|
96
96
|
// Determine which commits to push (since last pushed ref)
|
|
97
97
|
config.remoteRefs = config.remoteRefs || {};
|
|
98
|
-
|
|
98
|
+
// Everything reachable from any already-pushed ref of this remote is the
|
|
99
|
+
// boundary — a merge can pull in commits from a branch that was never
|
|
100
|
+
// pushed, so we can't bound by this branch's ref alone.
|
|
101
|
+
const remoteHave = Object.entries(config.remoteRefs)
|
|
102
|
+
.filter(([name]) => name.startsWith(`${remote}/`))
|
|
103
|
+
.map(([, sha]) => sha)
|
|
104
|
+
.filter(Boolean);
|
|
99
105
|
const commits = repository.commits || [];
|
|
100
|
-
const commitsToPush = getCommitsSince(commits, localHead,
|
|
106
|
+
const commitsToPush = getCommitsSince(commits, localHead, remoteHave);
|
|
101
107
|
|
|
102
108
|
if (commitsToPush.length === 0) {
|
|
103
109
|
spinner.succeed(chalk.green('Everything up-to-date'));
|
|
@@ -257,25 +263,44 @@ async function push(remoteName, branchName, options) {
|
|
|
257
263
|
}
|
|
258
264
|
|
|
259
265
|
/**
|
|
260
|
-
* Get commits from tip
|
|
266
|
+
* Get commits reachable from tip (following BOTH parents, so merges are
|
|
267
|
+
* covered) that the remote doesn't already have. Post-order → parents precede
|
|
268
|
+
* children in the returned array.
|
|
261
269
|
* @param {Array} allCommits
|
|
262
270
|
* @param {String} tipHash
|
|
263
|
-
* @param {String
|
|
271
|
+
* @param {String[]} remoteHave - shas the remote already has (its ref tips)
|
|
264
272
|
* @returns {Array}
|
|
265
273
|
*/
|
|
266
|
-
function getCommitsSince(allCommits, tipHash,
|
|
274
|
+
function getCommitsSince(allCommits, tipHash, remoteHave) {
|
|
267
275
|
const commitMap = new Map(allCommits.map(c => [c.hash, c]));
|
|
268
|
-
const result = [];
|
|
269
|
-
let current = tipHash;
|
|
270
276
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
// Boundary = every commit reachable from a remote ref via both parents.
|
|
278
|
+
const have = new Set();
|
|
279
|
+
const stack = [...(remoteHave || [])].filter(Boolean);
|
|
280
|
+
while (stack.length) {
|
|
281
|
+
const sha = stack.pop();
|
|
282
|
+
if (!sha || have.has(sha)) continue;
|
|
283
|
+
const c = commitMap.get(sha);
|
|
284
|
+
if (!c) continue; // not local → treat as already-remote boundary
|
|
285
|
+
have.add(sha);
|
|
286
|
+
if (c.parent) stack.push(c.parent);
|
|
287
|
+
if (c.mergeParent) stack.push(c.mergeParent);
|
|
276
288
|
}
|
|
277
289
|
|
|
278
|
-
|
|
290
|
+
const result = [];
|
|
291
|
+
const visited = new Set();
|
|
292
|
+
const visit = (sha) => {
|
|
293
|
+
if (!sha || visited.has(sha) || have.has(sha)) return;
|
|
294
|
+
const c = commitMap.get(sha);
|
|
295
|
+
if (!c) return;
|
|
296
|
+
visited.add(sha);
|
|
297
|
+
visit(c.parent);
|
|
298
|
+
visit(c.mergeParent);
|
|
299
|
+
result.push(c); // after both parents → oldest first
|
|
300
|
+
};
|
|
301
|
+
visit(tipHash);
|
|
302
|
+
|
|
303
|
+
return result;
|
|
279
304
|
}
|
|
280
305
|
|
|
281
306
|
module.exports = push;
|