use clap::{ArgGroup, Parser, Subcommand}; use mit::commands::{ add::add, branch::branch, commit::commit, init::init, log::log, remove::remove, restore::restore, status::status, switch::switch, }; /// Rust实现的简易版本的Git,用于学习Rust语言 #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Cli { /// The subcommand to run. #[clap(subcommand)] command: Command, } /// @see Rust Clap库学习 - 掘金 #[derive(Subcommand)] enum Command { /// 初始化仓库 Init, /// 添加文件到暂存区 /// @see git add .,git add -A,git add -u,git add * 的区别与联系 Add { /// 要添加的文件 files: Vec, /// 将工作区中所有的文件改动提交至暂存区(包括新增、修改和删除) #[clap(short = 'A', long)] all: bool, /// 将工作区中已跟踪的文件(tracked)更新到暂存区(修改 & 删除);But不包含新增 #[clap(short, long)] update: bool, }, /// 删除文件 Rm { /// 要删除的文件 files: Vec, /// flag 删除暂存区的文件 #[clap(long, action)] cached: bool, /// flag 递归删除目录 #[clap(short, long)] recursive: bool, }, /// 提交暂存区的文件 Commit { #[clap(short, long)] message: String, #[clap(long, action)] allow_empty: bool, }, /// 查看当前状态 Status, /// log 现实提交历史 #[clap(group = ArgGroup::new("sub").required(false))] Log { #[clap(short = 'A', long)] all: bool, #[clap(short, long)] number: Option, }, /// branch Branch { /// 新分支名 #[clap(group = "sub")] new_branch: Option, /// 基于某个commit创建分支 #[clap(requires = "new_branch")] commit_hash: Option, /// 列出所有分支 #[clap(short, long, action, group = "sub", default_value = "true")] list: bool, /// 删除制定分支,不能删除当前所在分支 #[clap(short = 'D', long, group = "sub")] delete: Option, /// 显示当前分支 #[clap(long, action, group = "sub")] show_current: bool, }, /// 切换分支 Switch { /// 要切换的分支 #[clap(required_unless_present("create"))] branch: Option, /// 创建并切换到新分支 #[clap(long, short, group = "sub")] create: Option, /// 是否允许切换到commit #[clap(long, short, action, default_value = "false", group = "sub")] detach: bool, }, /// restore Restore { // TODO 行为不确定 /// 要恢复的文件 #[clap(required = true)] path: Vec, /// source #[clap(long, short)] source: Option, /// worktree #[clap(long, short, action)] worktree: bool, /// staged #[clap(long, short, action)] staged: bool, }, } pub fn handle_command() { let cli = Cli::parse(); match cli.command { Command::Init => { init().expect("初始化失败"); } Command::Add { files, all, update } => { add(files, all, update); } Command::Rm { files, cached, recursive } => { remove(files, cached, recursive).expect("删除失败"); } Command::Commit { message, allow_empty } => { commit(message, allow_empty); } Command::Status => { status(); } Command::Log { all, number } => { log(all, number); } Command::Branch { list, delete, new_branch, commit_hash, show_current } => { branch(new_branch, commit_hash, list, delete, show_current); } Command::Switch { branch, create, detach } => { switch(branch, create, detach); } Command::Restore { path, mut source, mut worktree, staged } => { // 未指定stage和worktree时,默认操作stage if !staged { worktree = true; } // 未指定source时,默认操作HEAD if source.is_none() { source = Some("HEAD".to_string()); } restore(path, source.unwrap(), worktree, staged); } } }