git-bolt
Version:
Git utilities for faster development
135 lines (117 loc) • 4.39 kB
JavaScript
import chalk from 'chalk';
import fs from 'fs';
import git from 'isomorphic-git';
async function getHeadInfo() {
try {
// Get current branch
const currentBranch = await git.currentBranch({ fs, dir: '.' });
// Get HEAD commit hash
const headCommit = await git.resolveRef({ fs, dir: '.', ref: 'HEAD' });
// Get commit details
const commit = await git.readCommit({ fs, dir: '.', oid: headCommit });
// Get remote tracking info
let remoteInfo = null;
try {
const remoteTrackingBranch = await git.resolveRef({
fs,
dir: '.',
ref: `refs/remotes/origin/${currentBranch}`
}).catch(() => null);
if (remoteTrackingBranch) {
remoteInfo = {
branch: currentBranch,
commit: remoteTrackingBranch
};
}
} catch (error) {
// Remote tracking branch doesn't exist or other error
}
return {
branch: currentBranch,
commit: headCommit,
author: commit.commit.author,
message: commit.commit.message,
remote: remoteInfo
};
} catch (error) {
return null;
}
}
async function statusCommand() {
try {
// Get repository information
const headInfo = await getHeadInfo();
if (headInfo) {
console.log(chalk.cyan('📂 Repository Information:'));
console.log(chalk.cyan(` Branch: ${headInfo.branch}`));
console.log(chalk.cyan(` Commit: ${headInfo.commit.substring(0, 7)}`));
console.log(chalk.cyan(` Author: ${headInfo.author.name} <${headInfo.author.email}>`));
console.log(chalk.cyan(` Date: ${new Date(headInfo.author.timestamp * 1000).toLocaleString()}`));
console.log(chalk.cyan(` Message: ${headInfo.message.split('\n')[0]}`));
if (headInfo.remote) {
// Check if local is ahead or behind remote
if (headInfo.commit === headInfo.remote.commit) {
console.log(chalk.green(' ✓ Up-to-date with remote'));
} else {
console.log(chalk.yellow(' ⚠️ Local branch may differ from remote'));
}
} else {
console.log(chalk.yellow(' ⚠️ No remote tracking branch found'));
}
console.log('');
}
const matrix = await git.statusMatrix({ fs, dir: '.' });
if (matrix.length === 0) {
console.log(chalk.green('Working directory clean'));
return;
}
console.log(chalk.blue('Changes:'));
let staged = 0;
let modified = 0;
let deleted = 0;
let untracked = 0;
for (const [filepath, headStatus, workdirStatus, stageStatus] of matrix) {
let status = '';
let color = chalk.white;
if (headStatus === 0 && workdirStatus === 2 && stageStatus === 0) {
status = 'untracked';
color = chalk.red;
untracked++;
} else if (headStatus === 1 && workdirStatus === 2 && stageStatus === 1) {
status = 'modified, not staged';
color = chalk.red;
modified++;
} else if (headStatus === 1 && workdirStatus === 2 && stageStatus === 2) {
status = 'modified, staged';
color = chalk.green;
staged++;
} else if (headStatus === 1 && workdirStatus === 0 && stageStatus === 1) {
status = 'deleted, not staged';
color = chalk.red;
deleted++;
} else if (headStatus === 1 && workdirStatus === 0 && stageStatus === 0) {
status = 'deleted, staged';
color = chalk.green;
deleted++;
} else if (headStatus === 0 && workdirStatus === 2 && stageStatus === 2) {
status = 'new, staged';
color = chalk.green;
staged++;
} else {
status = `unknown (${headStatus}, ${workdirStatus}, ${stageStatus})`;
color = chalk.yellow;
}
console.log(` ${color(filepath)} (${status})`);
}
console.log('');
console.log(chalk.blue('Summary:'));
if (staged > 0) console.log(chalk.green(` ${staged} staged changes`));
if (modified > 0) console.log(chalk.red(` ${modified} unstaged modifications`));
if (deleted > 0) console.log(chalk.red(` ${deleted} deleted files`));
if (untracked > 0) console.log(chalk.red(` ${untracked} untracked files`));
} catch (error) {
console.error(chalk.red('Error getting status:'), error.message);
process.exit(1);
}
}
export { statusCommand };