-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbranch.js
More file actions
executable file
·142 lines (120 loc) · 3.94 KB
/
Copy pathbranch.js
File metadata and controls
executable file
·142 lines (120 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const LOG = require('./log-tag');
const BRANCH_RECORD_FILE = path.join(__dirname, 'branches.json');
function usage() {
console.error(`${LOG.error} Usage:`);
console.error(`${LOG.error} git b --list Show all local branches`);
console.error(`${LOG.error} git b -d <keyword> Delete local branches and records matching keyword`);
console.error(`${LOG.error} git b -p <branch> Set the parent of the current branch`);
process.exit(1);
}
function getCurrentBranch() {
try {
return execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
} catch {
return null;
}
}
// 순수 브랜치명만 배열로 추출 (grep 대신 JavaScript 내부 필터링을 위함)
function getAllLocalBranches() {
try {
return execSync('git branch --format="%(refname:short)"')
.toString()
.trim()
.split('\n')
.filter(Boolean);
} catch {
return [];
}
}
function loadBranchMap() {
if (!fs.existsSync(BRANCH_RECORD_FILE)) return {};
try {
return JSON.parse(fs.readFileSync(BRANCH_RECORD_FILE, 'utf-8'));
} catch {
console.warn(`${LOG.warn} Failed to parse branches.json. Returning empty map.`);
return {};
}
}
function saveBranchMap(map) {
try {
fs.writeFileSync(BRANCH_RECORD_FILE, JSON.stringify(map, null, 2));
} catch {
console.warn(`${LOG.warn} Failed to save branches.json.`);
}
}
// ---------- Main ----------
const [mode, keyword] = process.argv.slice(2);
if (!mode) usage();
// 모드 1: 리스트 출력
if (mode === '--list') {
try {
execSync('git branch --list', { stdio: 'inherit' });
} catch (err) {
console.error(`${LOG.error} Failed to list branches: ${err.message}`);
process.exit(1);
}
process.exit(0);
}
// 모드 2: 키워드 기반 브랜치 삭제
if (mode === '-d') {
if (!keyword) usage();
console.log(`${LOG.info} Deleting branches matching "${keyword}"...`);
const allBranches = getAllLocalBranches();
const targetBranches = allBranches.filter(b => b.includes(keyword));
const currentBranch = getCurrentBranch();
const branchMap = loadBranchMap();
let isRecordModified = false;
// 1. 실제 로컬 Git 브랜치 삭제
if (targetBranches.length === 0) {
console.log(`${LOG.info} No local git branches matched.`);
} else {
for (const br of targetBranches) {
if (br === currentBranch) {
console.warn(`${LOG.warn} Skipping current branch: "${br}"`);
continue;
}
try {
execSync(`git branch -d ${br}`, { stdio: 'inherit' });
} catch (err) {
// 병합되지 않은 변경사항이 있을 경우 에러 발생
console.error(`${LOG.error} Failed to delete branch "${br}". (Use -D to force delete)`);
}
}
}
// 2. branches.json 내 레코드 일괄 정리
const keysToRemove = Object.keys(branchMap).filter(k => k.includes(keyword));
if (keysToRemove.length > 0) {
for (const k of keysToRemove) {
delete branchMap[k];
console.log(`${LOG.info} Removed "${k}" from branches.json`);
}
isRecordModified = true;
}
// 변경사항이 있을 때만 파일 저장
if (isRecordModified) {
saveBranchMap(branchMap);
}
console.log(`${LOG.ok} Done.`);
process.exit(0);
}
// 모드 3: 현재 브랜치의 부모 브랜치 기록
if (mode === '-p') {
if (!keyword) usage();
const currentBranch = getCurrentBranch();
if (!currentBranch || currentBranch === 'HEAD') {
console.error(`${LOG.error} Could not determine the current branch. Are you in a detached HEAD state?`);
process.exit(1);
}
const parentBranch = keyword;
const branchMap = loadBranchMap();
branchMap[currentBranch] = parentBranch;
saveBranchMap(branchMap);
console.log(`${LOG.info} Recorded parent branch: "${currentBranch}" ← "${parentBranch}"`);
process.exit(0);
}
// 지정되지 않은 모드 방어
usage();