├── .gitignore ├── README.md ├── cli.js ├── index.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git Copy History 2 | 3 | [![npm version](https://badge.fury.io/js/git-copy-history.svg)](https://www.npmjs.com/package/git-copy-history) 4 | 5 | And only the history 6 | 7 | ![](https://user-images.githubusercontent.com/584632/61998650-da56b800-b0bb-11e9-8b23-3bb9f4959e96.gif) 8 | 9 | ### Copy your commit history from 10 | 11 | - 12 | - 13 | - Or any other local Git repository 14 | 15 | ## How it works 16 | 17 | Example: your repo is not on GitHub so for others it looks like you've just stopped coding at all. 18 | 19 | - This CLI takes all of YOUR commits from your local repo 20 | - It commits only **hashes from hashes** for exact same timestamps to another repo 21 | - This another repository has no private information inside but it has perfectly timed commit history 22 | - It can be shared on GitHub without any restrictions 23 | - You can even make the repository with history private - and commit history still will be visible (see the last section below) 24 | 25 | ## Installation 26 | 27 | ```bash 28 | npm install -g git-copy-history 29 | ``` 30 | 31 | ## Usage 32 | 33 | ```bash 34 | # Create new repo 35 | mkdir just-history 36 | cd just-history 37 | git init 38 | 39 | # Point git-copy-history to the source repo 40 | # git-copy-history from [options] 41 | git-copy-history from ../local-repo 42 | ``` 43 | 44 | Create private [repository on GitHub](https://github.com/new). 45 | Follow the instructions for existing repositories. 46 | 47 | - Add origin to your new repository 48 | - Push the history to the remote repository 49 | 50 | ### Options 51 | 52 | | Option | Description | 53 | | ---------- | --------------------------------------------------------------------------------------------------------------------------------- | 54 | | `--author` | Option used to setup author name or author email. This option can be used multiple times. | 55 | | `--secret` | Option used to setup secret key to hashing algorithm that creates hashes from repo hashes.
**Every time must be the same.** | 56 | 57 | ## Update history 58 | 59 | Just run `git-copy-history` again and it will add only the new commits. 60 | 61 | ```bash 62 | git-copy-history from ../local-repo 63 | git push 64 | ``` 65 | 66 | ## Update your profile settings 67 | 68 | If you have private repository and did not check this box: go to your [Profile Settings page](https://github.com/settings/profile) and check the box: 69 | 70 | 71 | 72 | ## Feedback 73 | 74 | 75 | > Please help me to improve this Readme file by sending PR 76 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const meow = require("meow"); 4 | const gitCopyHistory = require("."); 5 | 6 | const cli = meow( 7 | ` 8 | Usage 9 | $ git-copy-history from [options] 10 | 11 | Options 12 | --author String contains author name or author email. 13 | --secret String to crypt hashes. If you too paranoid. 14 | 15 | Example 16 | $ git-copy-history from ../my-project 17 | $ git-copy-history from ../my-project --author="Pavel Frankov" 18 | $ git-copy-history from ../my-project --author="first@email.tld" --author="second@email.tld" 19 | $ git-copy-history from ../my-project --secret="every time must be the same" 20 | `, 21 | { 22 | flags: {} 23 | } 24 | ); 25 | 26 | const [command, source] = cli.input; 27 | 28 | gitCopyHistory(command, source, cli.flags); 29 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const ora = require("ora"); 2 | const chalk = require("chalk"); 3 | const { execSync } = require("child_process"); 4 | const crypto = require("crypto"); 5 | const util = require("util"); 6 | const exec = util.promisify(require("child_process").exec); 7 | 8 | const HASH_SECRET = "crypto"; 9 | const COMMANDS = ["from"]; 10 | 11 | function validationError(message) { 12 | console.error(chalk.bold.red(`✖ ${message}`)); 13 | process.exit(1); 14 | } 15 | 16 | module.exports = function(command, source, _options) { 17 | const options = Object.assign( 18 | { 19 | secret: HASH_SECRET, 20 | author: null 21 | }, 22 | _options 23 | ); 24 | 25 | if (!command) { 26 | validationError( 27 | `Probably forget ${COMMANDS.map(x => `'${x}'`).join(" or ")} argument` 28 | ); 29 | return; 30 | } 31 | if (!COMMANDS.includes(command)) { 32 | validationError( 33 | `Argument '${command}' does not exist. Use ${COMMANDS.map( 34 | x => `'${x}'` 35 | ).join(", ")} instead` 36 | ); 37 | return; 38 | } 39 | if (!source) { 40 | validationError(`Probably forget to enter a path to existing repository`); 41 | return; 42 | } 43 | 44 | function getHistory() { 45 | let author = options.author; 46 | if (!author) { 47 | author = execSync(`cd ${source} && git config user.name`, { 48 | encoding: "utf8" 49 | }).replace(/\n/, ""); 50 | } 51 | 52 | let authorString = `--author="${author}"`; 53 | 54 | if (Array.isArray(author)) { 55 | authorString = author.map(a => `--author="${a}"`).join(" "); 56 | } 57 | 58 | return execSync( 59 | `cd ${source} && git log --pretty="%H|%ad" --date=format:"%Y-%m-%d %H:%M:%S" ${authorString} --all`, 60 | { encoding: "utf8" } 61 | ); 62 | } 63 | 64 | function getCurrentDirHistory() { 65 | let author = options.author; 66 | if (!author) { 67 | author = execSync(`git config user.name`, { encoding: "utf8" }); 68 | } 69 | 70 | let authorString = `--author="${author}"`; 71 | 72 | if (Array.isArray(author)) { 73 | authorString = author.map(a => `--author="${a}"`).join(" "); 74 | } 75 | 76 | return execSync( 77 | `git log --pretty="%s|%ad" --date=format:"%Y-%m-%d %H:%M:%S" ${authorString} --all`, 78 | { encoding: "utf8" } 79 | ); 80 | } 81 | 82 | function findMissedCommits() { 83 | const historyArray = getHistory() 84 | .split("\n") 85 | .filter(x => x); 86 | let currentDirHistoryArray = getCurrentDirHistory() 87 | .split("\n") 88 | .filter(x => x); 89 | 90 | const missedArray = []; 91 | 92 | for (let i = 0; i < historyArray.length; i++) { 93 | const [hash] = historyArray[i].split("|"); 94 | 95 | let found = false; 96 | 97 | for (let j = 0; j < currentDirHistoryArray.length; j++) { 98 | if (!currentDirHistoryArray[j]) { 99 | continue; 100 | } 101 | 102 | const [hashCur] = currentDirHistoryArray[j].split("|"); 103 | 104 | if (makeHash(hash) === hashCur) { 105 | found = true; 106 | delete currentDirHistoryArray[j]; 107 | } 108 | } 109 | 110 | if (!found) { 111 | missedArray.push(historyArray[i]); 112 | } 113 | } 114 | 115 | return missedArray; 116 | } 117 | 118 | function makeHash(string) { 119 | return crypto 120 | .createHmac("sha256", options.secret) 121 | .update(string) 122 | .digest("hex"); 123 | } 124 | 125 | ({ 126 | async from() { 127 | let lines; 128 | 129 | try { 130 | lines = findMissedCommits(); 131 | } catch (e) { 132 | console.warn( 133 | chalk.bold.green(`No commits in current directory. Continue`) 134 | ); 135 | lines = getHistory() 136 | .split("\n") 137 | .filter(x => x); 138 | } 139 | 140 | if (!lines.length) { 141 | console.log(chalk.bold.green(`Nothing to update. It may be ok.`)); 142 | return; 143 | } 144 | 145 | console.log(chalk.green(`Found ${lines.length} commits`)); 146 | 147 | const spinner = ora(`Writing history`).start(); 148 | 149 | await lines.reverse().reduce(async (lastPromise, line) => { 150 | await lastPromise; 151 | 152 | const [hash, date] = line.split("|"); 153 | const newHash = makeHash(hash); 154 | 155 | return exec( 156 | `echo "${newHash}" > commit.md && git add commit.md && git commit --date "${date}" -m "${newHash}"`, 157 | { 158 | encoding: "utf8" 159 | } 160 | ); 161 | }, Promise.resolve()); 162 | 163 | spinner.succeed(); 164 | } 165 | }[command]()); 166 | }; 167 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "git-copy-history", 3 | "version": "1.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-regex": { 8 | "version": "4.1.0", 9 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 10 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 11 | }, 12 | "ansi-styles": { 13 | "version": "3.2.1", 14 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 15 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 16 | "requires": { 17 | "color-convert": "^1.9.0" 18 | } 19 | }, 20 | "array-find-index": { 21 | "version": "1.0.2", 22 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 23 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" 24 | }, 25 | "arrify": { 26 | "version": "1.0.1", 27 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 28 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" 29 | }, 30 | "camelcase": { 31 | "version": "4.1.0", 32 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 33 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 34 | }, 35 | "camelcase-keys": { 36 | "version": "4.2.0", 37 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", 38 | "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", 39 | "requires": { 40 | "camelcase": "^4.1.0", 41 | "map-obj": "^2.0.0", 42 | "quick-lru": "^1.0.0" 43 | } 44 | }, 45 | "chalk": { 46 | "version": "2.4.2", 47 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 48 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 49 | "requires": { 50 | "ansi-styles": "^3.2.1", 51 | "escape-string-regexp": "^1.0.5", 52 | "supports-color": "^5.3.0" 53 | } 54 | }, 55 | "cli-cursor": { 56 | "version": "2.1.0", 57 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 58 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 59 | "requires": { 60 | "restore-cursor": "^2.0.0" 61 | } 62 | }, 63 | "cli-spinners": { 64 | "version": "2.2.0", 65 | "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", 66 | "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==" 67 | }, 68 | "clone": { 69 | "version": "1.0.4", 70 | "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", 71 | "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" 72 | }, 73 | "color-convert": { 74 | "version": "1.9.3", 75 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 76 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 77 | "requires": { 78 | "color-name": "1.1.3" 79 | } 80 | }, 81 | "color-name": { 82 | "version": "1.1.3", 83 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 84 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 85 | }, 86 | "currently-unhandled": { 87 | "version": "0.4.1", 88 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 89 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 90 | "requires": { 91 | "array-find-index": "^1.0.1" 92 | } 93 | }, 94 | "decamelize": { 95 | "version": "1.2.0", 96 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 97 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 98 | }, 99 | "decamelize-keys": { 100 | "version": "1.1.0", 101 | "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", 102 | "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", 103 | "requires": { 104 | "decamelize": "^1.1.0", 105 | "map-obj": "^1.0.0" 106 | }, 107 | "dependencies": { 108 | "map-obj": { 109 | "version": "1.0.1", 110 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 111 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" 112 | } 113 | } 114 | }, 115 | "defaults": { 116 | "version": "1.0.3", 117 | "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", 118 | "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", 119 | "requires": { 120 | "clone": "^1.0.2" 121 | } 122 | }, 123 | "error-ex": { 124 | "version": "1.3.2", 125 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 126 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 127 | "requires": { 128 | "is-arrayish": "^0.2.1" 129 | } 130 | }, 131 | "escape-string-regexp": { 132 | "version": "1.0.5", 133 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 134 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 135 | }, 136 | "find-up": { 137 | "version": "2.1.0", 138 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 139 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 140 | "requires": { 141 | "locate-path": "^2.0.0" 142 | } 143 | }, 144 | "fs-extra": { 145 | "version": "8.1.0", 146 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 147 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 148 | "requires": { 149 | "graceful-fs": "^4.2.0", 150 | "jsonfile": "^4.0.0", 151 | "universalify": "^0.1.0" 152 | } 153 | }, 154 | "graceful-fs": { 155 | "version": "4.2.0", 156 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", 157 | "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" 158 | }, 159 | "has-flag": { 160 | "version": "3.0.0", 161 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 162 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 163 | }, 164 | "hosted-git-info": { 165 | "version": "2.7.1", 166 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 167 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" 168 | }, 169 | "indent-string": { 170 | "version": "3.2.0", 171 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", 172 | "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" 173 | }, 174 | "is-arrayish": { 175 | "version": "0.2.1", 176 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 177 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 178 | }, 179 | "is-plain-obj": { 180 | "version": "1.1.0", 181 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", 182 | "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" 183 | }, 184 | "json-parse-better-errors": { 185 | "version": "1.0.2", 186 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 187 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" 188 | }, 189 | "jsonfile": { 190 | "version": "4.0.0", 191 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 192 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 193 | "requires": { 194 | "graceful-fs": "^4.1.6" 195 | } 196 | }, 197 | "load-json-file": { 198 | "version": "4.0.0", 199 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", 200 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", 201 | "requires": { 202 | "graceful-fs": "^4.1.2", 203 | "parse-json": "^4.0.0", 204 | "pify": "^3.0.0", 205 | "strip-bom": "^3.0.0" 206 | } 207 | }, 208 | "locate-path": { 209 | "version": "2.0.0", 210 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 211 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 212 | "requires": { 213 | "p-locate": "^2.0.0", 214 | "path-exists": "^3.0.0" 215 | } 216 | }, 217 | "log-symbols": { 218 | "version": "2.2.0", 219 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 220 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 221 | "requires": { 222 | "chalk": "^2.0.1" 223 | } 224 | }, 225 | "loud-rejection": { 226 | "version": "1.6.0", 227 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 228 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 229 | "requires": { 230 | "currently-unhandled": "^0.4.1", 231 | "signal-exit": "^3.0.0" 232 | } 233 | }, 234 | "map-obj": { 235 | "version": "2.0.0", 236 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", 237 | "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=" 238 | }, 239 | "meow": { 240 | "version": "5.0.0", 241 | "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", 242 | "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", 243 | "requires": { 244 | "camelcase-keys": "^4.0.0", 245 | "decamelize-keys": "^1.0.0", 246 | "loud-rejection": "^1.0.0", 247 | "minimist-options": "^3.0.1", 248 | "normalize-package-data": "^2.3.4", 249 | "read-pkg-up": "^3.0.0", 250 | "redent": "^2.0.0", 251 | "trim-newlines": "^2.0.0", 252 | "yargs-parser": "^10.0.0" 253 | } 254 | }, 255 | "mimic-fn": { 256 | "version": "1.2.0", 257 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 258 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" 259 | }, 260 | "minimist-options": { 261 | "version": "3.0.2", 262 | "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", 263 | "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", 264 | "requires": { 265 | "arrify": "^1.0.1", 266 | "is-plain-obj": "^1.1.0" 267 | } 268 | }, 269 | "normalize-package-data": { 270 | "version": "2.5.0", 271 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 272 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 273 | "requires": { 274 | "hosted-git-info": "^2.1.4", 275 | "resolve": "^1.10.0", 276 | "semver": "2 || 3 || 4 || 5", 277 | "validate-npm-package-license": "^3.0.1" 278 | } 279 | }, 280 | "onetime": { 281 | "version": "2.0.1", 282 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 283 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 284 | "requires": { 285 | "mimic-fn": "^1.0.0" 286 | } 287 | }, 288 | "ora": { 289 | "version": "3.4.0", 290 | "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", 291 | "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", 292 | "requires": { 293 | "chalk": "^2.4.2", 294 | "cli-cursor": "^2.1.0", 295 | "cli-spinners": "^2.0.0", 296 | "log-symbols": "^2.2.0", 297 | "strip-ansi": "^5.2.0", 298 | "wcwidth": "^1.0.1" 299 | } 300 | }, 301 | "p-limit": { 302 | "version": "1.3.0", 303 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", 304 | "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", 305 | "requires": { 306 | "p-try": "^1.0.0" 307 | } 308 | }, 309 | "p-locate": { 310 | "version": "2.0.0", 311 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 312 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 313 | "requires": { 314 | "p-limit": "^1.1.0" 315 | } 316 | }, 317 | "p-try": { 318 | "version": "1.0.0", 319 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 320 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" 321 | }, 322 | "parse-json": { 323 | "version": "4.0.0", 324 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 325 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 326 | "requires": { 327 | "error-ex": "^1.3.1", 328 | "json-parse-better-errors": "^1.0.1" 329 | } 330 | }, 331 | "path-exists": { 332 | "version": "3.0.0", 333 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 334 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 335 | }, 336 | "path-parse": { 337 | "version": "1.0.6", 338 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 339 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" 340 | }, 341 | "path-type": { 342 | "version": "3.0.0", 343 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", 344 | "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", 345 | "requires": { 346 | "pify": "^3.0.0" 347 | } 348 | }, 349 | "pify": { 350 | "version": "3.0.0", 351 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 352 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 353 | }, 354 | "prettier": { 355 | "version": "1.18.2", 356 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", 357 | "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", 358 | "dev": true 359 | }, 360 | "quick-lru": { 361 | "version": "1.1.0", 362 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", 363 | "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=" 364 | }, 365 | "read-pkg": { 366 | "version": "3.0.0", 367 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", 368 | "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", 369 | "requires": { 370 | "load-json-file": "^4.0.0", 371 | "normalize-package-data": "^2.3.2", 372 | "path-type": "^3.0.0" 373 | } 374 | }, 375 | "read-pkg-up": { 376 | "version": "3.0.0", 377 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", 378 | "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", 379 | "requires": { 380 | "find-up": "^2.0.0", 381 | "read-pkg": "^3.0.0" 382 | } 383 | }, 384 | "redent": { 385 | "version": "2.0.0", 386 | "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", 387 | "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", 388 | "requires": { 389 | "indent-string": "^3.0.0", 390 | "strip-indent": "^2.0.0" 391 | } 392 | }, 393 | "resolve": { 394 | "version": "1.11.1", 395 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", 396 | "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", 397 | "requires": { 398 | "path-parse": "^1.0.6" 399 | } 400 | }, 401 | "restore-cursor": { 402 | "version": "2.0.0", 403 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 404 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 405 | "requires": { 406 | "onetime": "^2.0.0", 407 | "signal-exit": "^3.0.2" 408 | } 409 | }, 410 | "semver": { 411 | "version": "5.7.0", 412 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", 413 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" 414 | }, 415 | "signal-exit": { 416 | "version": "3.0.2", 417 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 418 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 419 | }, 420 | "spdx-correct": { 421 | "version": "3.1.0", 422 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", 423 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", 424 | "requires": { 425 | "spdx-expression-parse": "^3.0.0", 426 | "spdx-license-ids": "^3.0.0" 427 | } 428 | }, 429 | "spdx-exceptions": { 430 | "version": "2.2.0", 431 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 432 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" 433 | }, 434 | "spdx-expression-parse": { 435 | "version": "3.0.0", 436 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 437 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 438 | "requires": { 439 | "spdx-exceptions": "^2.1.0", 440 | "spdx-license-ids": "^3.0.0" 441 | } 442 | }, 443 | "spdx-license-ids": { 444 | "version": "3.0.5", 445 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", 446 | "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" 447 | }, 448 | "strip-ansi": { 449 | "version": "5.2.0", 450 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 451 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 452 | "requires": { 453 | "ansi-regex": "^4.1.0" 454 | } 455 | }, 456 | "strip-bom": { 457 | "version": "3.0.0", 458 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 459 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" 460 | }, 461 | "strip-indent": { 462 | "version": "2.0.0", 463 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", 464 | "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=" 465 | }, 466 | "supports-color": { 467 | "version": "5.5.0", 468 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 469 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 470 | "requires": { 471 | "has-flag": "^3.0.0" 472 | } 473 | }, 474 | "trim-newlines": { 475 | "version": "2.0.0", 476 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", 477 | "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=" 478 | }, 479 | "universalify": { 480 | "version": "0.1.2", 481 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 482 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 483 | }, 484 | "validate-npm-package-license": { 485 | "version": "3.0.4", 486 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 487 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 488 | "requires": { 489 | "spdx-correct": "^3.0.0", 490 | "spdx-expression-parse": "^3.0.0" 491 | } 492 | }, 493 | "wcwidth": { 494 | "version": "1.0.1", 495 | "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", 496 | "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", 497 | "requires": { 498 | "defaults": "^1.0.3" 499 | } 500 | }, 501 | "yargs-parser": { 502 | "version": "10.1.0", 503 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", 504 | "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", 505 | "requires": { 506 | "camelcase": "^4.1.0" 507 | } 508 | } 509 | } 510 | } 511 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "git-copy-history", 3 | "version": "1.2.0", 4 | "description": "Copy history from another repo", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "format": "prettier --write *" 9 | }, 10 | "bin": "./cli.js", 11 | "author": { 12 | "name": "Pavel Frankov", 13 | "email": "pavel@frankov.ru" 14 | }, 15 | "license": "MIT", 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/pfrankov/git-copy-history.git" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/pfrankov/git-copy-history/issues" 22 | }, 23 | "keywords": [ 24 | "cli", 25 | "git", 26 | "github", 27 | "gitlab", 28 | "bitbucket" 29 | ], 30 | "dependencies": { 31 | "chalk": "^2.4.2", 32 | "fs-extra": "^8.1.0", 33 | "meow": "^5.0.0", 34 | "ora": "^3.4.0" 35 | }, 36 | "devDependencies": { 37 | "prettier": "^1.18.2" 38 | } 39 | } 40 | --------------------------------------------------------------------------------