添加脚本命令

1.创建一个名字为rebase的js文件

#!/usr/bin/env node

const path = require('path');
const chalk = require('chalk');
const shell = require('shelljs');
const inquirer = require('inquirer');

const currentRepo = {
  root: path.resolve(__dirname, '..'),
};

function error(str) {
  console.log(chalk.red(`[Rabaser] ${str}`));
  throw new Error(str);
}

function green(str) {
  if (str) {
    console.log(chalk.green(`[Rabaser] ${str}`));
  }
}

function warn(str) {
  console.log(chalk.yellow(`[Rabaser] ${str}`));
}

function line() {
  console.log('');
}

function exec(str, successInfo) {
  const res = shell.exec(str);
  if (res.code !== 0) {
    error(res.stderr);
  } else {
    green(successInfo);
    green('====================');
    return res;
  }
  return null;
}

async function rebase(repo, baseBranch) {
  shell.cd(repo.root);
  line();
  green(`========== At ${repo.root} ==========`);

  // Get current branch name
  const workBranch = exec('git symbolic-ref --short -q HEAD')
    .stdout.replace('\n', '');
  warn(`You are currently on branch ${workBranch}.`);
  if (workBranch === 'master' || workBranch === 'pre') {
    error(`You can not perform this operation on branch \`${workBranch}\`!!`);
  }
  await inquirer.prompt([{
    type: 'input',
    message: `You are trying to rebase branch ${workBranch} onto branch ${baseBranch}. Press any key to continue.`,
    name: 'msg',
  }]).then((answers) => answers.msg);

  const res = exec('git status');
  if (res.stdout.match('尚未暂存')) {
    await inquirer.prompt([{
      type: 'input',
      message: '当前分支有尚未提交的修改,是否提交?',
      name: 'msg',
    }]).then((answers) => answers.msg);
    exec('git add .');
    exec('git commit -m "快速提交。"');
    exec('git push');
  }

  const backupBranchPrefix = `${workBranch}-backup-9860-`;
  try {
    const backupBranchesStr = exec(`git branch | grep ${backupBranchPrefix}`);
    if (backupBranchesStr) {
      const backupBranches = backupBranchesStr.split('\n').filter(str => str);
      backupBranches.forEach(branchName => {
        exec(`git branch -D ${branchName}`, `Deleted backup branch ${branchName}`);
      });
    }
  } catch (e) {
    warn('No backup branch exists.');
  }
  // Copy workbranch to a new branch as backup
  const backupBranchName = `${backupBranchPrefix}${new Date().getTime()}`;
  exec(`git branch ${backupBranchName}`, `Created backup branch ${backupBranchName}`);

  // Switch to the base branch
  exec(`git checkout ${baseBranch}`, `Switched to local branch ${baseBranch}`);
  const out = exec('git status');
  if (out.match('Changes not staged for') || out.match('Changes to be committed')) {
    error('There are changes unsaved for base branch. Aborting.');
  }
  // Synchronize
  exec(`git pull origin ${baseBranch}`, 'Synchronized local base branch with remote base branch.');

  // Compare local base branch with remote base branch
  warn('Remote base branch hash:');
  const hashes = exec(`git rev-parse origin ${baseBranch}`).stdout.split('\n').filter(str => str);
  console.log(hashes);
  const remoteBaseCurrentHash = hashes[hashes.length - 1];
  warn('Local base branch hash:');
  const localBaseHash = exec('git rev-parse HEAD').stdout.replace('\n', '');
  if (localBaseHash !== remoteBaseCurrentHash) {
    exec(`git checkout ${workBranch}`);
    error('Local base branch is not the same with remote base branch!! Aborting.');
  }

  // Switch to the target branch
  exec(`git checkout ${workBranch}`);
  try {
    exec(`git rebase ${baseBranch} ${workBranch}`, 'Rebased successfully');
  } catch (e) {
    chalk.red('Conflicts occured in the rebase process. Resolve conflicts, execute "git add ." and "git rebase --continue" to finish rebase, then run this script again.');
    throw new Error();
  }

  try {
    let msg = await inquirer.prompt([{
      type: 'input',
      message: 'Input your commit message:',
      name: 'msg',
    }]).then((answers) => answers.msg);
    if (!msg) msg = '快速提交。';

    exec(`git reset ${localBaseHash}`);
    exec('git add .', 'Added');
    exec(`git commit -m "${msg || repo.msg}"`, 'Committed');
    exec(`git push -f --set-upstream origin ${workBranch}`, `Caution: Pushed to \`origin ${workBranch}\` by force.`);
    console.log('end');
  } catch (e) {
    const res = exec('git status').stdout;
    if (
      res.match('Your branch is behind')
      || res.match('Your branch is ahead of')
      || res.match('have diverged')
    ) {
      exec(`git push -f --set-upstream origin ${workBranch}`, `Caution: Pushed to \`origin ${workBranch}\` by force.`);
    }
    if (res.match('Your branch is up to date')) {
      warn('Nothing to push');
    }
  }
}

rebase(currentRepo, 'pre');

2.在package.json的scripts里面添加

"rebase:onto:pre": "node ./rebase.js"
3.在项目所在文件夹下执行rebase:onto:pre命令,即可执行rebase文件中的内容
posted @ 2020-12-30 19:59  瑞瑞大人  阅读(406)  评论(0编辑  收藏  举报