Skip to content
Open
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
68 changes: 48 additions & 20 deletions lib/gitremote.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,29 +93,57 @@ exports.getRemoteBranches = function(cwd) {
return remoteBranches;
};

var RE_CURRENT_BASE_BRANCHES = /^[ -+]*\*/;
var RE_BASE_BRANCHE_NAME = /.*?\[([^\]\^~]+).*/; // " +* [MS170216105211~2^2] test: fixed lint"
/**
* 解析 `git show-branch` 的输出,得到当前分支的基准分支。
* @param {String} showBranch 当前分支 `git show-branch` 的输出。
* @return {Array} base branch name
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return description should be plural to reflect that an array of names is returned. Suggest: @return {Array} base branch names.

Suggested change
* @return {Array} base branch name
* @return {Array<string>} base branch names

Copilot uses AI. Check for mistakes.
*/
exports.parseBaseBranchName = function(showBranch) {
// 上下上个部分使用 -- 分隔。
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the grammar and clarify the separator to match the actual code which splits on lines of hyphens.

Suggested change
// 上下上个部分使用 -- 分隔。
// 上下部分使用只包含连字符的行(如 --、--- 等)分隔。

Copilot uses AI. Check for mistakes.
const info = showBranch.split(/^-+$/m);
// 查找当前分支。
// -- 上面的部分包含当前分支。
const RE_CURRENT_BRANCH = /^(\s*)\*\s+\[([^\]]+)\]/m;
const m = RE_CURRENT_BRANCH.exec(info[0]);
// 输入异常,没有找到当前分支。
if (!m) {
return '';
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns a string when no current branch match is found, but the function’s JSDoc declares an Array and callers (e.g., getBaseBranches) will then receive a string. Return an empty array instead: return [];.

Suggested change
return '';
return [];

Copilot uses AI. Check for mistakes.
}
// 当前分支所在的列数
const currBranchIndent = m[1].length;
const currBranchName = m[2];

// 从 -- 下面的部分查找当前分支所在列有 *+- 符号的行所在的分支。
const brs = info[1].split(/\r\n|\r|\n/);
return brs
.map(br => {
var RE_BASE_BRANCHE_NAME = /^[ *+-]*\[([^\]\^~]+)/; // " +* [MS170216105211~2^2] test: fixed lint"
Comment on lines +118 to +120
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regular expression is recompiled for every line inside map, which is unnecessary. Hoist it outside the loop and use const, e.g., const RE_BASE_BRANCH_NAME = /^[ +-]\[([^\\]\^~]+)/; then reuse it inside map.

Suggested change
return brs
.map(br => {
var RE_BASE_BRANCHE_NAME = /^[ *+-]*\[([^\]\^~]+)/; // " +* [MS170216105211~2^2] test: fixed lint"
const RE_BASE_BRANCHE_NAME = /^[ *+-]*\[([^\]\^~]+)/; // " +* [MS170216105211~2^2] test: fixed lint"
return brs
.map(br => {

Copilot uses AI. Check for mistakes.
const m2 = RE_BASE_BRANCHE_NAME.exec(br);
// 解析异常,没有找到分支信息,一般是 \n 导致的空行。
if (!m2) {
return null;
}
const brName = m2[1];
return {
brName,
currBranchEffect: '*+-'.includes(br.charAt(currBranchIndent)),
};
})
.filter(br => {
return br &&
br.brName !== currBranchName &&
br.currBranchEffect;
})
.map(br => br.brName);
};

exports.getBaseBranches = function(cwd) {
var cwb = exports.getCurrentBranch(cwd);
var baseBranches = child_process.execSync(
var showBranch = child_process.execSync(
'git show-branch --no-color',
{cwd: cwd}
).toString()
.trim()
.split(/\r\n|\r|\n/)
.filter(function(line) {
return RE_CURRENT_BASE_BRANCHES.test(line);
})
.map(function(line) {
var m = RE_BASE_BRANCHE_NAME.exec(line);
return m ? m[1] : null;
})
.filter(function(branchName) {
return branchName !== cwb;
});
// TODO: 获取当前分支的所有祖先分支列表,并按照倒序排列,最近切出的祖先分支排第一。
return baseBranches.length >= 0 ? [baseBranches[0]] : [];
// return unique(baseBranches);
).toString();
const baseBranches = exports.parseBaseBranchName(showBranch);
return baseBranches;
};

// 转义分支名称。
Expand Down
43 changes: 43 additions & 0 deletions test/gitopen.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,49 @@ describe('gitremote()', function() {
it('gitremote.getRemoteName()', function() {
resolve(gitremote.getRemoteName()).should.be.eql('origin');
});


describe('gitremote.parseBaseBranchName()', function() {
it('gitremote.parseBaseBranchName(1)', function() {
const showBranch = `* [feat/hand-guide] feat: hand guide
! [master] sprint_demo_S915482907_20200903_merge_master:Merge branch 'sprint_demo_S915482907_20200903' into 'master'
! [sprint_demo_3_3_S916642948_20201022] PullRequest: something.
! [v3.3] PullRequest: 314 nothing
----
* [feat/hand-guide] feat: hand guide
- [master] sprint_demo_S915482907_20200903_merge_master:Merge branch 'sprint_demo_S915482907_20200903' into 'master'
---- [sprint_demo_3_3_S916642948_20201022] PullRequest: 314 something`;
gitremote.parseBaseBranchName(showBranch).should.be.eql(['sprint_demo_3_3_S916642948_20201022']);
});

it('gitremote.parseBaseBranchName(2)', function() {
const showBranch = `! [develop-1] master 2
! [develop-2] feat: 2-1
! [feat/1-1] master 2
! [feat/2-1] feat: 2-1
* [feat/2-2] feat: 2-2
! [master] master 2
------
* [feat/2-2] feat: 2-2
+ +* [develop-2] feat: 2-1
++++*+ [develop-1] master 2`;
gitremote.parseBaseBranchName(showBranch).should.be.eql(['develop-2', 'develop-1']);
});

it('gitremote.parseBaseBranchName(3)', function() {
const showBranch = `! [develop-1] master 2
! [develop-2] feat: 2-1
* [feat/1-1] master 2
! [feat/2-1] feat: 2-1
! [feat/2-2] feat: 2-2
! [master] master 2
------
+ [feat/2-2] feat: 2-2
+ ++ [develop-2] feat: 2-1
++*+++ [develop-1] master 2`;
gitremote.parseBaseBranchName(showBranch).should.be.eql(['develop-1']);
});
});
});

describe('$ cd non-git-dir && gitopen', function() {
Expand Down