git-off

git off handles large files in git repos
git clone https://noulin.net/git/git-off.git
Log | Files | Refs | README

commit 8b13cb1840d788ac8c4798825d1a32c946e744ac
parent d9bdc4ac0462b69b536ef2b9434538ab75b6c519
Author: Remy Noulin (Spartatek) <remy.noulin@spartatek.se>
Date:   Thu, 24 Nov 2016 19:15:48 +0100

add http transport and store command

- git off mode [thisrepo] http to use http transport
- git off store to set local store path
- git off http to set store url
- git off curl to set curl options

README.md         |  18 +++-
package.json      |   2 +-
src/git-off       | 260 +++++++++++++++++++++++++++++++++++++++++++++++-------
src/gitoff.coffee |  94 +++++++++++++++++++-
4 files changed, 340 insertions(+), 34 deletions(-)

Diffstat:
MREADME.md | 18++++++++++++++++--
Mpackage.json | 2+-
Msrc/git-off | 260++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/gitoff.coffee | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 340 insertions(+), 34 deletions(-)

diff --git a/README.md b/README.md @@ -4,6 +4,12 @@ This is a prototype inspired by [git lfs](https://github.com/git-lfs/git-lfs) an By default the files are stored in the home directory. +Supported transports are: + +- copy - store locally +- ssh/scp +- http + # Install ``` @@ -111,12 +117,19 @@ host localhost git off install [thisrepo] setup git config (default global) thisrepo sets up config in current repo -git off mode [thisrepo] [copy|scp] +git off mode [thisrepo] [copy|scp|http] set/show git off mode +git off store [thisrepo] [path] + set/show git off store path for copy mode git off scp [thisrepo] [host] setup scp config host has format host:path, user@host:path, user@host:port/path Example: localhost:/tmp/offStore +git off http [thisrepo] [host] + setup http config + host has format http://host/path +git off curl [thisrepo] [options] + setup curl config git off integrity [thisrepo] [enable|disable] set/show git off integrity. when enabled, the SHA of the file received from the store is @@ -177,7 +190,8 @@ git off help [cmd] - nodejs - git -- ssh and scp for scp transport +- ssh and scp for scp mode +- curl for http mode # Platforms diff --git a/package.json b/package.json @@ -1,6 +1,6 @@ { "name": "git-off", - "version": "0.0.5", + "version": "0.0.6", "description": "large file handler for git", "bin": "./src/git-off", "scripts": { diff --git a/src/git-off b/src/git-off @@ -40,7 +40,7 @@ /* * modules */ -var COMMAND_MAP, StringDecoder, copy, exec, expandHome, externalHelpers, fs, gitConfig, mkdirParents, mkdirp, offCommands, offDEFAULTS, offHelpers, offLog, offLogRepo, oiNAME, oiOID, oiPERMISSIONS, oiPREVIOUSOID, oiPREVIOUSPERMISSIONS, readline, rimraf, rmAll, runtimeConfig, showCommandHelp, syncexec, thisrepo, transport; +var COMMAND_MAP, StringDecoder, copy, exec, expandHome, externalHelpers, fs, gitConfig, mkdirParents, mkdirp, offCommands, offDEFAULTS, offHelpers, offLog, offLogRepo, oiNAME, oiOID, oiPERMISSIONS, oiPREVIOUSOID, oiPREVIOUSPERMISSIONS, readline, rimraf, rmAll, runtimeConfig, showCommandHelp, syncexec, thisrepo, transport, walkSync; require('colors'); @@ -81,13 +81,15 @@ externalHelpers = { 'sha': 'git hash-object --no-filters', 'listAttr': 'git check-attr -a', 'ssh': 'ssh', - 'scp': 'scp' + 'scp': 'scp', + 'curl': 'curl' }; runtimeConfig = { 'currentRepoRoot': '', 'objectPath': '', 'offStore': '', + 'offHttp': '', 'offMode': '', 'offIntegrity': '', 'offScp': '', @@ -95,18 +97,25 @@ runtimeConfig = { 'offPem': '', 'offSshOptions': '', 'offScpOptions': '', - 'log': '' + 'offCurlOptions': '', + 'log': '', + 'offConfigAlways': '' }; offDEFAULTS = { 'objectPath': '/.git/off/objects', 'mode': 'copy', 'integrity': 'disable', - 'pem': '', + 'pem': 'offNoValue', + 'scpHost': 'offNoValue', + 'scpUser': '', 'sshOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3', 'scpOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p', 'store': '~/.git-off/offStore', + 'http': 'offNoValue', + 'curlOptions': '-o', 'log': '~/.git-off/log', + 'configAlways': 'offNoValue', 'prePush': '#!/bin/sh\ncommand -v git-off >/dev/null 2>&1 || { echo >&2 "\\nThis repository is configured for Git off but \'git-off\' was not found on your path. If you no longer wish to use git off, remove this hook by deleting .git/hooks/pre-push.\\n"; exit 2; }\ngit off pre-push "$@"', 'offSignature': '### git-off v1 sha:', 'shaLength': 40 @@ -136,21 +145,36 @@ gitConfig = { }, 'get': function(key) { var r; + if (offHelpers.offConfigAlways() === 'GIT_OFF_CONFIG') { + r = ''; + if (process.env.GIT_OFF_CONFIG !== void 0 && fs.existsSync(process.env.GIT_OFF_CONFIG) === true) { + r = exec('gitConfig', ['--file ' + process.env.GIT_OFF_CONFIG, key]).stdout.trim(); + } + return r; + } + if (offHelpers.offConfigAlways() === 'repo') { + r = ''; + if (fs.existsSync(offHelpers.gitRepoRoot(true) + '/.git-off') === true) { + r = exec('gitConfig', ['--file ' + offHelpers.gitRepoRoot() + '/.git-off', key]).stdout.trim(); + } + return r; + } + if (offHelpers.offConfigAlways() === 'global') { + return exec('gitConfig', [key]).stdout.trim(); + } if (process.env.GIT_OFF_CONFIG !== void 0 && fs.existsSync(process.env.GIT_OFF_CONFIG) === true) { r = exec('gitConfig', ['--file ' + process.env.GIT_OFF_CONFIG, key]).stdout.trim(); if (r !== '') { return r; } } - if (fs.existsSync(offHelpers.gitRepoRoot(true) + '/.git-off') === false) { - return exec('gitConfig', [key]).stdout.trim(); - } else { + if (fs.existsSync(offHelpers.gitRepoRoot(true) + '/.git-off') === true) { r = exec('gitConfig', ['--file ' + offHelpers.gitRepoRoot() + '/.git-off', key]).stdout.trim(); if (r !== '') { return r; } - return exec('gitConfig', [key]).stdout.trim(); } + return exec('gitConfig', [key]).stdout.trim(); }, 'getSyncexec': function(key) { return syncexec(externalHelpers.gitConfig + ' ' + key); @@ -209,6 +233,22 @@ copy = function(src, dst) { fs.createReadStream(src).pipe(fs.createWriteStream(dst)); }; +walkSync = function(dir, filelist) { + var files; + if (filelist == null) { + filelist = []; + } + files = fs.readdirSync(dir); + files.forEach(function(file) { + if (fs.statSync(dir + '/' + file).isDirectory()) { + filelist = walkSync(dir + '/' + file, filelist); + } else { + filelist.push(dir + '/' + file); + } + }); + return filelist; +}; + offHelpers = { 'gitRepoRoot': function(ignoreStderr) { var r; @@ -235,6 +275,18 @@ offHelpers = { } return runtimeConfig.offStore; }, + 'offHttp': function() { + if (runtimeConfig.offHttp === '') { + runtimeConfig.offHttp = gitConfig.get('off.http'); + } + return runtimeConfig.offHttp; + }, + 'offCurlOptions': function() { + if (runtimeConfig.offCurlOptions === '') { + runtimeConfig.offCurlOptions = gitConfig.get('off.curloptions'); + } + return runtimeConfig.offCurlOptions; + }, 'offMode': function() { if (runtimeConfig.offMode === '') { runtimeConfig.offMode = gitConfig.get('off.mode'); @@ -274,10 +326,8 @@ offHelpers = { return runtimeConfig.offScp; }, 'offScpUser': function() { - var r; if (runtimeConfig.offScpUser === '') { - r = gitConfig.get('off.scpuser'); - runtimeConfig.offScpUser = expandHome(r); + runtimeConfig.offScpUser = gitConfig.get('off.scpuser'); } return runtimeConfig.offScpUser; }, @@ -297,6 +347,14 @@ offHelpers = { } return runtimeConfig.log; }, + 'offConfigAlways': function() { + var r; + if (runtimeConfig.offConfigAlways === '') { + r = gitConfig.getSyncexec('off.configAlways'); + runtimeConfig.offConfigAlways = r.stdout.trim(); + } + return runtimeConfig.offConfigAlways; + }, 'userAt': function() { var user; if (offHelpers.offScpUser() !== '') { @@ -330,7 +388,7 @@ offHelpers = { h_l = offHelpers.getSSHConfig(); sshCmd = '"mkdir -p ' + h_l[1] + '/' + path; sshCmd += '"'; - if (offHelpers.offPem() === '') { + if (offHelpers.offPem() === '' || offHelpers.offPem() === 'offNoValue') { pem = ''; } else { pem = '-i ' + offHelpers.offPem(); @@ -343,7 +401,7 @@ offHelpers = { }, 'rmAllStore': function(path) { var h_l, pem, sshCmd; - if (offHelpers.offPem() === '') { + if (offHelpers.offPem() === '' || offHelpers.offPem() === 'offNoValue') { pem = ''; } else { pem = '-i ' + offHelpers.offPem(); @@ -357,6 +415,19 @@ offHelpers = { exec('ssh', [offHelpers.offSshOptions(), pem, '-p ' + h_l[2], h_l[0], sshCmd], true); } }, + 'copyTo': function() { + var f, files, i, j, len1, len2, tfiles; + tfiles = walkSync(offHelpers.objectPath()); + files = []; + for (i = 0, len1 = tfiles.length; i < len1; i++) { + f = tfiles[i]; + files.push(f.replace(offHelpers.objectPath() + '/', '')); + } + for (j = 0, len2 = files.length; j < len2; j++) { + f = files[j]; + transport.send(f); + } + }, 'checkIntegrity': function(path) { var path_l, r, receivedSha, result; result = true; @@ -372,8 +443,14 @@ offHelpers = { } return result; }, - 'setTransport': function() { - if (offHelpers.offMode() === 'copy') { + 'setTransport': function(mode) { + if (mode == null) { + mode = 'config'; + } + if (mode === 'config') { + mode = offHelpers.offMode(); + } + if (mode === 'copy') { transport['send'] = function(file) { var f_l; f_l = file.split('/'); @@ -390,12 +467,12 @@ offHelpers = { readStream.pipe(process.stdout); } }; - } else if (offHelpers.offMode() === 'scp') { + } else if (mode === 'scp') { transport['send'] = function(file) { var f_l, h_l, pem; f_l = file.split('/'); offHelpers.mkdirStore(f_l[0] + '/' + f_l[1]); - if (offHelpers.offPem() === '') { + if (offHelpers.offPem() === '' || offHelpers.offPem() === 'offNoValue') { pem = ''; } else { pem = '-i ' + offHelpers.offPem(); @@ -413,7 +490,7 @@ offHelpers = { if (fs.existsSync(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]) === false) { mkdirParents(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]); } - if (offHelpers.offPem() === '') { + if (offHelpers.offPem() === '' || offHelpers.offPem() === 'offNoValue') { pem = ''; } else { pem = '-i ' + offHelpers.offPem(); @@ -429,6 +506,22 @@ offHelpers = { readStream.pipe(process.stdout); } }; + } else if (mode === 'http') { + transport['send'] = function(file) { + offLogRepo('Http mode is read-only: ' + file + ' is stored in cache only'); + }; + transport['receive'] = function(file) { + var f_l, readStream; + f_l = file.split('/'); + if (fs.existsSync(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]) === false) { + mkdirParents(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]); + } + exec('curl', [offHelpers.offCurlOptions(), offHelpers.objectPath() + '/' + file, offHelpers.offHttp() + '/' + file]); + if (offHelpers.checkIntegrity(offHelpers.objectPath() + '/' + file)) { + readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file); + readStream.pipe(process.stdout); + } + }; } }, 'getOffFilePath': function(offFile) { @@ -476,11 +569,7 @@ offCommands = { } } if (offHelpers.log() === '' || setCfg !== gitConfig.set) { - if (setCfg === gitConfig.setThisRepo) { - gitConfig.setLocal('off.log', offDEFAULTS.log); - } else { - setCfg('off.log', offDEFAULTS.log); - } + gitConfig.set('off.log', offDEFAULTS.log); } if (offHelpers.offMode() === '' || setCfg !== gitConfig.set) { setCfg('off.mode', offDEFAULTS.mode); @@ -491,6 +580,12 @@ offCommands = { if (offHelpers.offPem() === '' || setCfg !== gitConfig.set) { setCfg('off.pem', offDEFAULTS.pem); } + if (offHelpers.offScp() === '' || setCfg !== gitConfig.set) { + setCfg('off.scphost', offDEFAULTS.scpHost); + } + if (offHelpers.offScpUser() === '' || setCfg !== gitConfig.set) { + setCfg('off.scpuser', offDEFAULTS.scpUser); + } if (offHelpers.offSshOptions() === '' || setCfg !== gitConfig.set) { setCfg('off.sshoptions', offDEFAULTS.sshOptions); } @@ -500,6 +595,15 @@ offCommands = { if (offHelpers.offStore() === '' || setCfg !== gitConfig.set) { setCfg('off.store', offDEFAULTS.store); } + if (offHelpers.offHttp() === '' || setCfg !== gitConfig.set) { + setCfg('off.http', offDEFAULTS.http); + } + if (offHelpers.offCurlOptions() === '' || setCfg !== gitConfig.set) { + setCfg('off.curloptions', offDEFAULTS.curlOptions); + } + if (offHelpers.offConfigAlways() === '' || setCfg !== gitConfig.set) { + setCfg('off.configAlways', offDEFAULTS.configAlways); + } if (runtimeConfig.offMode === 'copy') { mkdirParents(runtimeConfig.offStore); } @@ -517,6 +621,16 @@ offCommands = { console.log('off.mode '.blue.bold + offHelpers.offMode()); } }, + 'store': function(setCfg) { + var len, store; + len = process.argv.length; + store = process.argv[len - 1]; + if (store !== 'store' && store !== 'thisrepo') { + setCfg('off.store', store); + } else { + console.log('off.store '.blue.bold + offHelpers.offStore()); + } + }, 'scp': function(setCfg) { var len, scpHost; len = process.argv.length; @@ -527,6 +641,26 @@ offCommands = { console.log('off.scp '.blue.bold + offHelpers.offScp()); } }, + 'http': function(setCfg) { + var http, len; + len = process.argv.length; + http = process.argv[len - 1]; + if (http !== 'http' && http !== 'thisrepo') { + setCfg('off.http', http); + } else { + console.log('off.http '.blue.bold + offHelpers.offHttp()); + } + }, + 'curl': function(setCfg) { + var curl, len; + len = process.argv.length; + curl = process.argv[len - 1]; + if (curl !== 'curl' && curl !== 'thisrepo') { + setCfg('off.curloptions', curl); + } else { + console.log('off.curloptions '.blue.bold + offHelpers.offCurlOptions()); + } + }, 'integrity': function(setCfg) { var integrity, len; len = process.argv.length; @@ -593,6 +727,16 @@ offCommands = { } } }, + 'configAlways': function() { + var configAlways, len; + len = process.argv.length; + configAlways = process.argv[len - 1]; + if (configAlways !== 'configAlways') { + gitConfig.set('off.configAlways', configAlways); + } else { + console.log('off.configAlways '.blue.bold + offHelpers.offConfigAlways()); + } + }, 'clean': function() { var file, offFile, offFilePath, r, size, writeStream; offCommands.localSetup(); @@ -692,18 +836,29 @@ offCommands = { } }); }, + 'copyTo': function() { + if (process.argv[3] === void 0) { + console.log('Choose a mode where to copy the cache'.red.bold); + return; + } + offHelpers.setTransport(process.argv[3]); + offHelpers.copyTo(); + }, 'clearAll': function() { + offCommands.clearStore(); + rmAll(offHelpers.objectPath()); + rmAll(offHelpers.getLog()); + }, + 'clearCache': function() { + rmAll(offHelpers.objectPath()); + }, + 'clearStore': function() { if (offHelpers.offMode() === 'copy') { rmAll(offHelpers.offStore()); } if (offHelpers.offMode() === 'scp') { offHelpers.rmAllStore(''); } - rmAll(offHelpers.objectPath()); - rmAll(offHelpers.getLog()); - }, - 'clearCache': function() { - rmAll(offHelpers.objectPath()); }, 'defaults': function() { var i, k, len1, ref; @@ -720,9 +875,12 @@ offCommands = { console.log('off.sshoptions '.blue.bold + offHelpers.offSshOptions()); console.log('off.scpoptions '.blue.bold + offHelpers.offScpOptions()); console.log('off.store '.blue.bold + offHelpers.offStore()); + console.log('off.http '.blue.bold + offHelpers.offHttp()); + console.log('off.curloptions '.blue.bold + offHelpers.offCurlOptions()); console.log('off.scphost '.blue.bold + offHelpers.offScp()); console.log('off.scpuser '.blue.bold + offHelpers.offScpUser()); console.log('off.log '.blue.bold + offHelpers.getLog()); + console.log('off.configAlways '.blue.bold + offHelpers.offConfigAlways()); }, 'help': function() { var c, i, len1, ref; @@ -792,7 +950,13 @@ COMMAND_MAP = { f: function() { thisrepo(offCommands['mode']); }, - h: 'git off mode [thisrepo] [copy|scp]\n set/show git off mode' + h: 'git off mode [thisrepo] [copy|scp|http]\n set/show git off mode' + }, + 'store': { + f: function() { + thisrepo(offCommands['store']); + }, + h: 'git off store [thisrepo] [path]\n set/show git off store path for copy mode' }, 'scp': { f: function() { @@ -800,6 +964,18 @@ COMMAND_MAP = { }, h: 'git off scp [thisrepo] [host]\n setup scp config\n host has format host:path, user@host:path, user@host:port/path\n Example: localhost:/tmp/offStore' }, + 'http': { + f: function() { + thisrepo(offCommands['http']); + }, + h: 'git off http [thisrepo] [host]\n setup http config\n host has format http://host/path\n Example: http://localhost/offStore' + }, + 'curl': { + f: function() { + thisrepo(offCommands['curl']); + }, + h: 'git off curl [thisrepo] [options]\n setup curl config' + }, 'integrity': { f: function() { thisrepo(offCommands['integrity']); @@ -810,7 +986,7 @@ COMMAND_MAP = { f: function() { thisrepo(offCommands['pem']); }, - h: 'git off pem [thisrepo] [pathToPrivateKey]\n set/show git off pem.\n off.pem is the private key for ssh and scp' + h: "git off pem [thisrepo] [pathToPrivateKey]\n set/show git off pem.\n off.pem is the private key for ssh and scp\n set 'offNoValue' to set an empty value (useful when there are multiple configs)" }, 'sshoptions': { f: function() { @@ -836,6 +1012,12 @@ COMMAND_MAP = { }, h: "git off track\n setup gitattribute filters\n example: git off track '*.bin'\n without parameter, list git off attributes\n calls git off install" }, + 'configAlways': { + f: function() { + offCommands.configAlways(); + }, + h: "git off configAlways [''|GIT_OFF_CONFIG|repo|global]\n '' disable configAlways\n GIT_OFF_CONFIG load all configurations from $GIT_OFF_CONFIG\n repo load all configurations from current git repo\n global load all configurations from global git config\n set 'offNoValue' to set an empty value" + }, 'clean': { f: function() { offCommands.clean(); @@ -854,6 +1036,12 @@ COMMAND_MAP = { }, h: 'git off smudge\n internal filter\n dont use directly' }, + 'copyTo': { + f: function() { + offCommands.copyTo(); + }, + h: 'git off copyTo [copy|scp]\n copy cache to store for specified mode' + }, 'clearAll': { f: function() { offCommands.clearAll(); @@ -878,6 +1066,18 @@ COMMAND_MAP = { }, h: 'git off cc\n delete cache in current git' }, + 'clearStore': { + f: function() { + offCommands.clearStore(); + }, + h: 'git off clearStore\n delete store' + }, + 'cs': { + f: function() { + offCommands.clearStore(); + }, + h: 'git off cs\n delete store' + }, 'defaults': { f: function() { offCommands.defaults(); diff --git a/src/gitoff.coffee b/src/gitoff.coffee @@ -105,6 +105,7 @@ externalHelpers = 'listAttr': 'git check-attr -a' 'ssh': 'ssh' 'scp': 'scp' + 'curl': 'curl' # config built by offHelpers # use offHelpers to access runtimeConfig @@ -112,6 +113,7 @@ runtimeConfig = 'currentRepoRoot': '' 'objectPath': '' 'offStore': '' + 'offHttp': '' 'offMode': '' 'offIntegrity': '' 'offScp': '' @@ -119,6 +121,7 @@ runtimeConfig = 'offPem': '' 'offSshOptions': '' 'offScpOptions': '' + 'offCurlOptions': '' 'log': '' 'offConfigAlways': '' @@ -129,9 +132,13 @@ offDEFAULTS = 'mode': 'copy' 'integrity': 'disable' 'pem': 'offNoValue' + 'scpHost': 'offNoValue' + 'scpUser': '' 'sshOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3' 'scpOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p' 'store': '~/.git-off/offStore' + 'http': 'offNoValue' + 'curlOptions': '-o' 'log': '~/.git-off/log' 'configAlways': 'offNoValue' 'prePush': '#!/bin/sh\ncommand -v git-off >/dev/null 2>&1 || { echo >&2 "\\nThis repository is configured for Git off but \'git-off\' was not found on your path. If you no longer wish to use git off, remove this hook by deleting .git/hooks/pre-push.\\n"; exit 2; }\ngit off pre-push "$@"' @@ -303,6 +310,16 @@ offHelpers = runtimeConfig.offStore = expandHome r runtimeConfig.offStore + 'offHttp': -> + if runtimeConfig.offHttp == '' + runtimeConfig.offHttp = gitConfig.get 'off.http' + runtimeConfig.offHttp + + 'offCurlOptions': -> + if runtimeConfig.offCurlOptions == '' + runtimeConfig.offCurlOptions = gitConfig.get 'off.curloptions' + runtimeConfig.offCurlOptions + 'offMode': -> if runtimeConfig.offMode == '' runtimeConfig.offMode = gitConfig.get 'off.mode' @@ -478,6 +495,7 @@ offHelpers = if mode == 'config' mode = offHelpers.offMode() + # copy mode if mode == 'copy' transport['send'] = (file) -> # create file directories in store @@ -494,6 +512,7 @@ offHelpers = readStream.pipe(process.stdout) return + # scp mode else if mode == 'scp' transport['send'] = (file) -> @@ -535,6 +554,24 @@ offHelpers = readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file) readStream.pipe(process.stdout) return + + # copy http + else if mode == 'http' + transport['send'] = (file) -> + offLogRepo('Http mode is read-only: ' + file + ' is stored in cache only') + return + transport['receive'] = (file) -> + # create file directories in cache + f_l = file.split '/' + if fs.existsSync(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]) == false + mkdirParents offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1] + + exec 'curl', [offHelpers.offCurlOptions(), offHelpers.objectPath() + '/' + file, offHelpers.offHttp() + '/' + file] + + if offHelpers.checkIntegrity offHelpers.objectPath() + '/' + file + readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file) + readStream.pipe(process.stdout) + return return 'getOffFilePath': (offFile) -> @@ -617,12 +654,20 @@ offCommands = setCfg('off.integrity', offDEFAULTS.integrity) if offHelpers.offPem() == '' or setCfg != gitConfig.set setCfg('off.pem', offDEFAULTS.pem) + if offHelpers.offScp() == '' or setCfg != gitConfig.set + setCfg('off.scphost', offDEFAULTS.scpHost) + if offHelpers.offScpUser() == '' or setCfg != gitConfig.set + setCfg('off.scpuser', offDEFAULTS.scpUser) if offHelpers.offSshOptions() == '' or setCfg != gitConfig.set setCfg('off.sshoptions', offDEFAULTS.sshOptions) if offHelpers.offScpOptions() == '' or setCfg != gitConfig.set setCfg('off.scpoptions', offDEFAULTS.scpOptions) if offHelpers.offStore() == '' or setCfg != gitConfig.set setCfg('off.store', offDEFAULTS.store) + if offHelpers.offHttp() == '' or setCfg != gitConfig.set + setCfg('off.http', offDEFAULTS.http) + if offHelpers.offCurlOptions() == '' or setCfg != gitConfig.set + setCfg('off.curloptions', offDEFAULTS.curlOptions) if offHelpers.offConfigAlways() == '' or setCfg != gitConfig.set setCfg('off.configAlways', offDEFAULTS.configAlways) @@ -644,6 +689,15 @@ offCommands = console.log 'off.mode '.blue.bold + offHelpers.offMode() return + 'store': (setCfg) -> + len = process.argv.length + store = process.argv[len-1] + if store != 'store' and store != 'thisrepo' + setCfg('off.store', store) + else + console.log 'off.store '.blue.bold + offHelpers.offStore() + return + 'scp': (setCfg) -> len = process.argv.length scpHost = process.argv[len-1] @@ -653,6 +707,24 @@ offCommands = console.log 'off.scp '.blue.bold + offHelpers.offScp() return + 'http': (setCfg) -> + len = process.argv.length + http = process.argv[len-1] + if http != 'http' and http != 'thisrepo' + setCfg('off.http', http) + else + console.log 'off.http '.blue.bold + offHelpers.offHttp() + return + + 'curl': (setCfg) -> + len = process.argv.length + curl = process.argv[len-1] + if curl != 'curl' and curl != 'thisrepo' + setCfg('off.curloptions', curl) + else + console.log 'off.curloptions '.blue.bold + offHelpers.offCurlOptions() + return + 'integrity': (setCfg) -> len = process.argv.length integrity = process.argv[len-1] @@ -936,6 +1008,8 @@ offCommands = console.log 'off.sshoptions '.blue.bold + offHelpers.offSshOptions() console.log 'off.scpoptions '.blue.bold + offHelpers.offScpOptions() console.log 'off.store '.blue.bold + offHelpers.offStore() + console.log 'off.http '.blue.bold + offHelpers.offHttp() + console.log 'off.curloptions '.blue.bold + offHelpers.offCurlOptions() console.log 'off.scphost '.blue.bold + offHelpers.offScp() console.log 'off.scpuser '.blue.bold + offHelpers.offScpUser() console.log 'off.log '.blue.bold + offHelpers.getLog() @@ -1008,7 +1082,13 @@ COMMAND_MAP = f: -> thisrepo offCommands['mode'] return - h: 'git off mode [thisrepo] [copy|scp]\n set/show git off mode' + h: 'git off mode [thisrepo] [copy|scp|http]\n set/show git off mode' + + 'store': + f: -> + thisrepo offCommands['store'] + return + h: 'git off store [thisrepo] [path]\n set/show git off store path for copy mode' 'scp': f: -> @@ -1016,6 +1096,18 @@ COMMAND_MAP = return h: 'git off scp [thisrepo] [host]\n setup scp config\n host has format host:path, user@host:path, user@host:port/path\n Example: localhost:/tmp/offStore' + 'http': + f: -> + thisrepo offCommands['http'] + return + h: 'git off http [thisrepo] [host]\n setup http config\n host has format http://host/path\n Example: http://localhost/offStore' + + 'curl': + f: -> + thisrepo offCommands['curl'] + return + h: 'git off curl [thisrepo] [options]\n setup curl config' + 'integrity': f: -> thisrepo offCommands['integrity']