commit 909b4a0c817c812f78a2eacab720c6aa0709eaef
parent 252b803afe458ec9452b7c14d7d1ccbc8f5c059c
Author: Remy Noulin <loader2x@gmail.com>
Date: Wed, 28 Dec 2016 22:05:37 +0100
add git off push command and rsync transport
README.md | 10 +-
c/git-off.c | 375 ++++++++++++++++++++++++++++++++++++++++++------------
c/gitoff.c | 375 ++++++++++++++++++++++++++++++++++++++++++------------
package.json | 2 +-
src/git-off | 92 +++++++++++++-
src/gitoff.coffee | 94 +++++++++++++-
6 files changed, 766 insertions(+), 182 deletions(-)
Diffstat:
| M | README.md | | | 10 | ++++++++-- |
| M | c/git-off.c | | | 375 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
| M | c/gitoff.c | | | 375 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
| M | package.json | | | 2 | +- |
| M | src/git-off | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
| M | src/gitoff.coffee | | | 94 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
6 files changed, 766 insertions(+), 182 deletions(-)
diff --git a/README.md b/README.md
@@ -7,6 +7,7 @@ By default the files are stored in the home directory.
Supported transports are:
- copy - store locally
+- rsync
- ssh/scp
- http (read-only)
- s3
@@ -227,7 +228,7 @@ git off s3bucket mybucketname
git off install [thisrepo]
setup git config (default global)
thisrepo sets up config in current repo
-git off mode [thisrepo] [copy|scp|http|s3]
+git off mode [thisrepo] [copy|rsync|scp|http|s3]
set/show git off mode
git off store [thisrepo] [path]
set/show git off store path for copy mode
@@ -252,6 +253,8 @@ git off sshoptions [thisrepo] [options]
set/show git off sshoptions
git off scpoptions [thisrepo] [options]
set/show git off scpoptions
+git off rsyncoptions [thisrepo] [options]
+ set/show git off rsyncoptions
git off scpuser [thisrepo] [username]
setup scp username config
git off track
@@ -286,8 +289,10 @@ git off pre-push
git off smudge
internal filter
dont use directly
-git off copyTo [copy|scp|s3]
+git off copyTo [copy|rsync|scp|s3]
copy cache to store for specified mode
+git off push
+ copy cache to store for selected mode
git off clearAll
delete store, cache and log
git off ca
@@ -318,6 +323,7 @@ git off help [cmd]
- nodejs
- git
+- rsync for rsync mode
- ssh and scp for scp mode
- curl for http mode
diff --git a/c/git-off.c b/c/git-off.c
@@ -122,6 +122,7 @@ char *offHelpers_offIntegrity();
char *offHelpers_offPem();
char *offHelpers_offSshOptions();
char *offHelpers_offScpOptions();
+char *offHelpers_offRsyncOptions();
char *offHelpers_offScp();
char *offHelpers_offScpUser();
char *offHelpers_log();
@@ -140,6 +141,8 @@ void offHelpers_copyTo();
bool offHelpers_checkIntegrity(char *p);
void transportCopySend(char *file);
void transportCopyReceive(char *file);
+void transportRsyncSend(char *file);
+void transportRsyncReceive(char *file);
void transportScpSend(char *file);
void transportScpReceive(char *file);
void transportHttpSend(char *file);
@@ -164,6 +167,7 @@ void offCommands_prepush();
void offCommands_push(char *line);
void offCommands_smudge();
void offCommands_copyTo();
+void offCommands_pushTo();
void offCommands_clearAll();
void offCommands_clearCache();
void offCommands_clearStore();
@@ -181,6 +185,7 @@ void integrityF();
void pemF();
void sshoptionsF();
void scpoptionsF();
+void rsyncoptionsF();
void scpuserF();
void trackF();
void configAlwaysF();
@@ -193,6 +198,7 @@ void cleanF();
void prepushF();
void smudgeF();
void copyToF();
+void pushF();
void clearAllF();
void caF();
void clearCacheF();
@@ -222,18 +228,18 @@ int argc; char **argv;
// shell commands to be used with the exec function
// example: exec 'gitRepoRoot'
-enum { gitConfigGlobal, gitConfig, gitRepoRoot, gitList, gitDff, gitCat, sha, listAttr, ssh, scp, curl, mv, mkdirE, cp, rm };
-char* externalHelpers[15] = { "git config --global", "git config", "git rev-parse --show-toplevel", "git rev-list", "git diff-tree -r", "git cat-file -p", "git hash-object --no-filters", "git check-attr -a", "ssh", "scp", "curl", "mv", "mkdir -p", "cp", "rm -rf" };
+enum { gitConfigGlobal, gitConfig, gitRepoRoot, gitList, gitDff, gitCat, sha, listAttr, ssh, scp, rsync, curl, mv, mkdirE, cp, rm };
+char* externalHelpers[16] = { "git config --global", "git config", "git rev-parse --show-toplevel", "git rev-list", "git diff-tree -r", "git cat-file -p", "git hash-object --no-filters", "git check-attr -a", "ssh", "scp", "rsync", "curl", "mv", "mkdir -p", "cp -u", "rm -rf" };
// config built by offHelpers
// use offHelpers to access runtimeConfig
-enum { currentRepoRoot, objectPath, offStore, offHttp, offMode, offIntegrity, offScp, offScpUser, offPem, offSshOptions, offScpOptions, offCurlOptions, log, offConfigAlways, s3Region, s3Bucket, transform, transformTo, transformFrom, scpHost, scpPath, scpPort };
-char* runtimeConfig[22] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+enum { currentRepoRoot, objectPath, offStore, offHttp, offMode, offIntegrity, offScp, offScpUser, offPem, offSshOptions, offScpOptions, offRsyncOptions, offCurlOptions, log, offConfigAlways, s3Region, s3Bucket, transform, transformTo, transformFrom, scpHost, scpPath, scpPort };
+char* runtimeConfig[23] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
// default configuration for first time install
// objectPath is git off cache in repo
-enum { objectPathD, modeD, integrityD, pemD, scpHostD, scpUserD, sshOptionsD, scpOptionsD, storeD, httpD, curlOptionsD, logD, configAlwaysD, s3RegionD, s3BucketD, transformD, transformToD, transformFromD, prePushD, offSignatureD, lastD };
-char* offDEFAULTS[21] = { "/.git/off/objects", "copy", "disable", "offNoValue", "offNoValue", "", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p", "~/.git-off/offStore", "offNoValue", "-o", "~/.git-off/log", "offNoValue", "offNoValue", "offNoValue", "disable", "pbzip2 -9 -c _1 > _2", "pbzip2 -d -c _1 > _2", "#!/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 \"$@\"", "### git-off v1 sha:", "not used" };
+enum { objectPathD, modeD, integrityD, pemD, scpHostD, scpUserD, sshOptionsD, scpOptionsD, rsyncOptionsD, storeD, httpD, curlOptionsD, logD, configAlwaysD, s3RegionD, s3BucketD, transformD, transformToD, transformFromD, prePushD, offSignatureD, lastD };
+char* offDEFAULTS[22] = { "/.git/off/objects", "copy", "disable", "offNoValue", "offNoValue", "", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p", "-az -e \"ssh -i _i\"", "~/.git-off/offStore", "offNoValue", "-o", "~/.git-off/log", "offNoValue", "offNoValue", "offNoValue", "disable", "pbzip2 -9 -c _1 > _2", "pbzip2 -d -c _1 > _2", "#!/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 \"$@\"", "### git-off v1 sha:", "not used" };
#define offDEFAULTS_shaLength 40
@@ -325,7 +331,7 @@ char *exec(int cmdName, char* paramsArray) {
free(cmd);
read = getline(&line, &len, fp);
- fclose(fp);
+ pclose(fp);
if (read == -1) {
// nothing was read
@@ -444,19 +450,22 @@ char *gitConfig_get(char *key) {
}
}
- p = malloc(strlen(offHelpers_gitRepoRoot()) + 1 + 9);
- sprintf(p, "%s/.git-off", offHelpers_gitRepoRoot());
- if (access(p, F_OK) != -1) {
- free(p);
- p = malloc(strlen(offHelpers_gitRepoRoot()) + strlen(key) + 1 + 17);
- sprintf(p, "--file %s/.git-off %s", offHelpers_gitRepoRoot() , key);
- r = exec(gitConfig, p);
- if (r != NULL) {
+ if (offHelpers_gitRepoRoot()) {
+ // skip repo config when running outside a git repo
+ p = malloc(strlen(offHelpers_gitRepoRoot()) + 1 + 9);
+ sprintf(p, "%s/.git-off", offHelpers_gitRepoRoot());
+ if (access(p, F_OK) != -1) {
free(p);
- return(r);
- }
+ p = malloc(strlen(offHelpers_gitRepoRoot()) + strlen(key) + 1 + 17);
+ sprintf(p, "--file %s/.git-off %s", offHelpers_gitRepoRoot() , key);
+ r = exec(gitConfig, p);
+ if (r != NULL) {
+ free(p);
+ return(r);
}
- free(p);
+ }
+ free(p);
+ }
r = gitConfig_getDefault(key);
return(r);
}
@@ -532,7 +541,7 @@ char **execOut(char *cmd) {
count++;
}
- fclose(fp);
+ pclose(fp);
return(list);
}
@@ -587,7 +596,11 @@ char **split(char *string, char* delim) {
}
r[count] = strdup(token);
count++;
+ // macOS sets workingString to NULL at the end
+ if (!workingString) {
+ break;
}
+ }
free(startString);
return(r);
@@ -727,6 +740,14 @@ char *offHelpers_offScpOptions() {
return(runtimeConfig[offScpOptions]);
}
+char *offHelpers_offRsyncOptions() {
+
+ if (runtimeConfig[offRsyncOptions] == NULL) {
+ runtimeConfig[offRsyncOptions] = gitConfig_get("off.rsyncoptions");
+ }
+ return(runtimeConfig[offRsyncOptions]);
+}
+
char *offHelpers_offScp() {
if (runtimeConfig[offScp] == NULL) {
@@ -1111,6 +1132,158 @@ void transportCopyReceive(char *file) {
}
+void transportRsyncSend(char *file) {
+ // create file directories in store
+ char **f_l = NULL;
+ char *p = NULL;
+ char *pem = NULL;
+ char *params = NULL;
+ char *options = NULL;
+ char *options2 = NULL;
+ char *tmp = NULL;
+
+ f_l = split(file, "/");
+ p = malloc(strlen(f_l[0]) + strlen(f_l[1]) + 1 + 1);
+ sprintf(p, "%s/%s", f_l[0], f_l[1]);
+ offHelpers_mkdirStore(p);
+ free(p);
+
+ options = strdup(offHelpers_offRsyncOptions());
+
+ // set pem or not? check rsyncoptions
+ // find _i index in options
+ tmp = strstr(options, " _i");
+ if (tmp != NULL) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
+ options2 = strdup(options);
+ }
+ else {
+ tmp[1] = 0;
+ options2 = malloc(strlen(options) + strlen(offHelpers_offPem()) + strlen(tmp+3) + 1 + 0);
+ sprintf(options2, "%s%s%s", options, offHelpers_offPem(), tmp+3);
+ }
+ }
+ else {
+ options2 = strdup(options);
+ }
+
+ char *dest;
+
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_objectPath(), file);
+ dest = malloc(strlen(offHelpers_offScp()) + strlen(file) + 1 + 1);
+ sprintf(dest, "%s/%s", offHelpers_offScp(), file);
+
+ params = malloc(strlen(options2) + strlen(p) + strlen(dest) + 1 + 2);
+ sprintf(params, "%s %s %s", options2, p, dest);
+
+ exec(rsync, params);
+
+ free(p);
+ free(dest);
+ free(pem);
+ free(params);
+ free(options);
+ free(options2);
+}
+
+void transportRsyncReceive(char *file) {
+ char *p = NULL;
+ char **f_l = NULL;
+ DIR *d = NULL;
+ char *pem = NULL;
+ char *params = NULL;
+ char *options = NULL;
+ char *options2 = NULL;
+ char *tmp = NULL;
+
+ // create file directories in cache
+ f_l = split(file, "/");
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(f_l[0]) + strlen(f_l[1]) + 1 + 2);
+ sprintf(p, "%s/%s/%s", offHelpers_objectPath(), f_l[0], f_l[1]);
+ d = opendir(p);;
+ if (d == NULL) {
+ mkdirParents(p);
+ }
+ free(p);
+ freeList((void **)f_l);
+
+
+ options = strdup(offHelpers_offRsyncOptions());
+
+ // set pem or not? check rsyncoptions
+ // find _i index in options
+ tmp = strstr(options, " _i");
+ if (tmp != NULL) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
+ options2 = strdup(options);
+ }
+ else {
+ tmp[1] = 0;
+ options2 = malloc(strlen(options) + strlen(offHelpers_offPem()) + strlen(tmp+3) + 1 + 0);
+ sprintf(options2, "%s%s%s", options, offHelpers_offPem(), tmp+3);
+ }
+ }
+ else {
+ options2 = strdup(options);
+ }
+
+ char *dest;
+
+ dest = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(dest, "%s/%s", offHelpers_objectPath(), file);
+ p = malloc(strlen(offHelpers_offScp()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_offScp(), file);
+
+ params = malloc(strlen(options2) + strlen(p) + strlen(dest) + 1 + 2);
+ sprintf(params, "%s %s %s", options2, p, dest);
+
+ exec(rsync, params);
+
+ free(p);
+ free(dest);
+ free(pem);
+ free(params);
+ free(options);
+ free(options2);
+
+ // transform
+ int sR;
+ char b[1024];
+ FILE *f;
+
+ if ((strEq(offHelpers_transform(), "enable")) && (offHelpers_transformFrom() != NULL)) {
+ transport_transformFrom(file);
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 8);
+ sprintf(p, "%s/../tmp/%s", offHelpers_objectPath(), file);
+ if (offHelpers_checkIntegrity(p)) {
+ f = fopen(p, "r");
+ sR = fread(b, 1, 1024, f);
+ while (sR != 0) {
+ fwrite(b, 1, sR, stdout);
+ sR = fread(b, 1, 1024, f);
+ }
+ fclose(f);
+ }
+ }
+ else {
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_objectPath(), file);
+ if (offHelpers_checkIntegrity(p)) {
+ f = fopen(p, "r");
+ sR = fread(b, 1, 1024, f);
+ while (sR != 0) {
+ fwrite(b, 1, sR, stdout);
+ sR = fread(b, 1, 1024, f);
+ }
+ fclose(f);
+ }
+ }
+
+ free(p);
+}
+
+
void transportScpSend(char *file) {
// create file directories in store
char **f_l = NULL;
@@ -1128,7 +1301,7 @@ void transportScpSend(char *file) {
h_l = offHelpers_getSSHConfig();
// setup ssh/scp private key
- if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue")) || (offHelpers_offPem() == NULL)) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
pem = strdup("");
}
else {
@@ -1183,7 +1356,7 @@ void transportScpReceive(char *file) {
h_l = offHelpers_getSSHConfig();
// setup ssh/scp private key
- if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue")) || (offHelpers_offPem() == NULL)) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
pem = strdup("");
}
else {
@@ -1338,6 +1511,12 @@ void offHelpers_setTransport(char *mode ) {
transport.receive = transportCopyReceive;
}
+ // rsync mode
+ else if (strEq(m, "rsync")) {
+ transport.send = transportRsyncSend;
+ transport.receive = transportRsyncReceive;
+ }
+
// scp mode
else if (strEq(m, "scp")) {
transport.send = transportScpSend;
@@ -1528,14 +1707,14 @@ void thisrepo(cmdSetF_t cmd) {
-enum { installH, modeH, storeH, scpH, httpH, curlH, integrityH, pemH, sshoptionsH, scpoptionsH, scpuserH, trackH, configAlwaysH, s3regionH, s3bucketH, transformH, transformToH, transformFromH, cleanH, prepushH, smudgeH, copyToH, clearAllH, caH, clearCacheH, ccH, clearStoreH, csH, clearTmpH, ctH, defaultsH, envH, helpH, lastH };
-char* COMMAND_HELP[34] = { "git off install [thisrepo]\n setup git config (default global)\n thisrepo sets up config in current repo", "git off mode [thisrepo] [copy|scp|http|s3]\n set/show git off mode", "git off store [thisrepo] [path]\n set/show git off store path for copy mode", "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", "git off http [thisrepo] [host]\n setup http config\n host has format http host/path\n Example http localhost/offStore", "git off curl [thisrepo] [options]\n setup curl config", "git off integrity [thisrepo] [enable|disable]\n set/show git off integrity.\n when enabled, the SHA of the file received from the store is\n checked again the SHA of the original file", "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)", "git off sshoptions [thisrepo] [options]\n set/show git off sshoptions", "git off scpoptions [thisrepo] [options]\n set/show git off scpoptions", "git off scpuser [thisrepo] [username]\n setup scp username config", "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", "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", "git off s3region [thisrepo] [region]\n setup amazon s3 region for the bucket", "git off s3bucket [thisrepo] [bucket]\n setup amazon s3 bucket", "git off transform [thisrepo] [enable|disable]\n enable transform in clean and smudge filters", "git off transformTo [thisrepo] [\"cmd _1 _2\"]\n setup transform command for clear filter\n When the command is empty the regular transport is performed", "git off transformFrom [thisrepo] [\"cmd _1 _2\"]\n setup transform command for smudge filter\n When the command is empty the regular transport is performed", "git off clean\n internal filter\n dont use directly", "git off pre-push\n internal filter\n dont use directly", "git off smudge\n internal filter\n dont use directly", "git off copyTo [copy|scp|s3]\n copy cache to store for specified mode", "git off clearAll\n delete store, cache and log", "git off ca\n delete store, cache and log", "git off clearCache\n delete cache in current git", "git off cc\n delete cache in current git", "git off clearStore\n delete store", "git off cs\n delete store", "git off clearTmp\n delete tmp in git off cache\n Useful when transform is enabled", "git off ct\n delete tmp in git off cache\n Useful when transform is enabled", "git off defaults\n shows first time config", "git off env\n shows config", "git off help [cmd]\n git off help. Run git off help command to get help for a specific command.", "not a command" };
+enum { installH, modeH, storeH, scpH, httpH, curlH, integrityH, pemH, sshoptionsH, scpoptionsH, rsyncoptionsH, scpuserH, trackH, configAlwaysH, s3regionH, s3bucketH, transformH, transformToH, transformFromH, cleanH, prepushH, smudgeH, copyToH, pushH, clearAllH, caH, clearCacheH, ccH, clearStoreH, csH, clearTmpH, ctH, defaultsH, envH, helpH, lastH };
+char* COMMAND_HELP[36] = { "git off install [thisrepo]\n setup git config (default global)\n thisrepo sets up config in current repo", "git off mode [thisrepo] [copy|rsync|scp|http|s3]\n set/show git off mode", "git off store [thisrepo] [path]\n set/show git off store path for copy mode", "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", "git off http [thisrepo] [host]\n setup http config\n host has format http://host/path\n Example http://localhost/offStore", "git off curl [thisrepo] [options]\n setup curl config", "git off integrity [thisrepo] [enable|disable]\n set/show git off integrity.\n when enabled, the SHA of the file received from the store is\n checked again the SHA of the original file", "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)", "git off sshoptions [thisrepo] [options]\n set/show git off sshoptions", "git off scpoptions [thisrepo] [options]\n set/show git off scpoptions", "git off rsyncoptions [thisrepo] [options]\n set/show git off rsyncoptions", "git off scpuser [thisrepo] [username]\n setup scp username config", "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", "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", "git off s3region [thisrepo] [region]\n setup amazon s3 region for the bucket", "git off s3bucket [thisrepo] [bucket]\n setup amazon s3 bucket", "git off transform [thisrepo] [enable|disable]\n enable transform in clean and smudge filters", "git off transformTo [thisrepo] [\"cmd _1 _2\"]\n setup transform command for clear filter\n When the command is empty the regular transport is performed", "git off transformFrom [thisrepo] [\"cmd _1 _2\"]\n setup transform command for smudge filter\n When the command is empty the regular transport is performed", "git off clean\n internal filter\n dont use directly", "git off pre-push\n internal filter\n dont use directly", "git off smudge\n internal filter\n dont use directly", "git off copyTo [copy|rsync|scp|s3]\n copy cache to store for specified mode", "git off push\n copy cache to store for selected mode", "git off clearAll\n delete store, cache and log", "git off ca\n delete store, cache and log", "git off clearCache\n delete cache in current git", "git off cc\n delete cache in current git", "git off clearStore\n delete store", "git off cs\n delete store", "git off clearTmp\n delete tmp in git off cache\n Useful when transform is enabled", "git off ct\n delete tmp in git off cache\n Useful when transform is enabled", "git off defaults\n shows first time config", "git off env\n shows config", "git off help [cmd]\n git off help. Run git off help command to get help for a specific command.", "not a command" };
-enum { installC, modeC, storeC, scpC, httpC, curlC, integrityC, pemC, sshoptionsC, scpoptionsC, scpuserC, trackC, configAlwaysC, s3regionC, s3bucketC, transformC, transformToC, transformFromC, cleanC, prepushC, smudgeC, copyToC, clearAllC, caC, clearCacheC, ccC, clearStoreC, csC, clearTmpC, ctC, defaultsC, envC, helpC, lastC };
-char* COMMAND_MAP[34] = { "install", "mode", "store", "scp", "http", "curl", "integrity", "pem", "sshoptions", "scpoptions", "scpuser", "track", "configAlways", "s3region", "s3bucket", "transform", "transformTo", "transformFrom", "clean", "pre-push", "smudge", "copyTo", "clearAll", "ca", "clearCache", "cc", "clearStore", "cs", "clearTmp", "ct", "defaults", "env", "help", "not a command" };
+enum { installC, modeC, storeC, scpC, httpC, curlC, integrityC, pemC, sshoptionsC, scpoptionsC, rsyncoptionsC, scpuserC, trackC, configAlwaysC, s3regionC, s3bucketC, transformC, transformToC, transformFromC, cleanC, prepushC, smudgeC, copyToC, pushC, clearAllC, caC, clearCacheC, ccC, clearStoreC, csC, clearTmpC, ctC, defaultsC, envC, helpC, lastC };
+char* COMMAND_MAP[36] = { "install", "mode", "store", "scp", "http", "curl", "integrity", "pem", "sshoptions", "scpoptions", "rsyncoptions", "scpuser", "track", "configAlways", "s3region", "s3bucket", "transform", "transformTo", "transformFrom", "clean", "pre-push", "smudge", "copyTo", "push", "clearAll", "ca", "clearCache", "cc", "clearStore", "cs", "clearTmp", "ct", "defaults", "env", "help", "not a command" };
-enum { installG, modeG, storeG, scpG, httpG, curlG, integrityG, pemG, sshoptionsG, scpoptionsG, scpuserG, trackG, configAlwaysG, s3regionG, s3bucketG, transformG, transformToG, transformFromG, cleanG, prepushG, smudgeG, copyToG, clearAllG, caG, clearCacheG, ccG, clearStoreG, csG, clearTmpG, ctG, defaultsG, envG, helpG, lastG };
-char* COMMAND_GITCONFIG[34] = { "empty", "off.mode", "off.store", "off.scp", "off.http", "off.curloptions", "off.integrity", "off.pem", "off.sshoptions", "off.scpoptions", "off.scpuser", "empty", "off.configAlways", "off.s3region", "off.s3bucket", "off.transform", "off.transformTo", "off.transformFrom", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "not a command" };
+enum { installG, modeG, storeG, scpG, httpG, curlG, integrityG, pemG, sshoptionsG, scpoptionsG, rsyncoptionsG, scpuserG, trackG, configAlwaysG, s3regionG, s3bucketG, transformG, transformToG, transformFromG, cleanG, prepushG, smudgeG, copyToG, pushG, clearAllG, caG, clearCacheG, ccG, clearStoreG, csG, clearTmpG, ctG, defaultsG, envG, helpG, lastG };
+char* COMMAND_GITCONFIG[36] = { "empty", "off.mode", "off.store", "off.scp", "off.http", "off.curloptions", "off.integrity", "off.pem", "off.sshoptions", "off.scpoptions", "off.rsyncoptions", "off.scpuser", "empty", "off.configAlways", "off.s3region", "off.s3bucket", "off.transform", "off.transformTo", "off.transformFrom", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "not a command" };
// functions called for commands
typedef void (*cmdF_t)();
@@ -1662,6 +1841,9 @@ void offCommands_install(gConfig_set_t setF ) {
if ((offHelpers_offScpOptions() == NULL) || (setF != gitConfig_set)) {
setF("off.scpoptions", offDEFAULTS[scpOptionsD]);
}
+ if ((offHelpers_offRsyncOptions() == NULL) || (setF != gitConfig_set)) {
+ setF("off.rsyncoptions", offDEFAULTS[rsyncOptionsD]);
+ }
if ((offHelpers_offStore() == NULL) || (setF != gitConfig_set)) {
setF("off.store", offDEFAULTS[storeD]);
}
@@ -1696,7 +1878,7 @@ void offCommands_install(gConfig_set_t setF ) {
mkdirParents(runtimeConfig[offStore]);
}
- if (strEq(runtimeConfig[offMode], "scp")) {
+ if (strEq(runtimeConfig[offMode], "scp") || strEq(runtimeConfig[offMode], "rsync")) {
offHelpers_mkdirStore("");
}
}
@@ -1752,10 +1934,17 @@ void offCommands_configAlways() {
gitConfig_set(COMMAND_GITCONFIG[configAlwaysC], argv[argc-1]);
}
else {
- printf("%s %s", COMMAND_GITCONFIG[configAlwaysC], COMMAND_HELPERS[configAlwaysC]());
- printf("\n");
+ if (COMMAND_HELPERS[configAlwaysC]()) {
+ // print when config is available
+ printf("%s %s", COMMAND_GITCONFIG[configAlwaysC], COMMAND_HELPERS[configAlwaysC]());
+ printf("\n");
+ }
+ else {
+ printf("Not in config: %s", COMMAND_GITCONFIG[configAlwaysC]);
+ printf("\n");
}
}
+ }
void offCommands_setGetGitConfig(gConfig_set_t setF) {
int i;
@@ -1765,10 +1954,16 @@ void offCommands_setGetGitConfig(gConfig_set_t setF) {
setF(COMMAND_GITCONFIG[i], argv[argc-1]);
}
else {
- printf("%s %s", COMMAND_GITCONFIG[i], COMMAND_HELPERS[i]());
- printf("\n");
+ if (COMMAND_HELPERS[i]()) {
+ printf("%s %s", COMMAND_GITCONFIG[i], COMMAND_HELPERS[i]());
+ printf("\n");
+ }
+ else {
+ printf("Not in config: %s", COMMAND_GITCONFIG[i]);
+ printf("\n");
}
}
+ }
void offCommands_clean() {
char *file = NULL;
@@ -2155,6 +2350,16 @@ void offCommands_copyTo() {
offHelpers_copyTo();
}
+void offCommands_pushTo() {
+
+ if (offHelpers_offMode() != NULL) {
+ printf("mode: %s", offHelpers_offMode());
+ printf("\n");
+ offHelpers_setTransport(offHelpers_offMode());
+ offHelpers_copyTo();
+}
+ }
+
void offCommands_clearAll() {
// delete store, cache in current git and log
@@ -2179,7 +2384,7 @@ void offCommands_clearStore() {
if (strEq(offHelpers_offMode(), "copy")) {
rmAll(offHelpers_offStore());
}
- if (strEq(offHelpers_offMode(), "scp")) {
+ if (strEq(offHelpers_offMode(), "scp") || strEq(offHelpers_offMode(), "rsync")) {
offHelpers_rmAllStore("");
}
}
@@ -2232,6 +2437,11 @@ void offCommands_env() {
printf("off.scpoptions %s", offHelpers_offScpOptions());
printf("\n");
}
+ s = offHelpers_offRsyncOptions();
+ if (s != NULL) {
+ printf("off.rsyncoptions %s", offHelpers_offRsyncOptions());
+ printf("\n");
+ }
s = offHelpers_offStore();
if (s != NULL) {
printf("off.store %s", offHelpers_offStore());
@@ -2334,7 +2544,7 @@ void offCommands_help() {
showAllCommandsHelp();
- printf("More information at");
+ printf("More information at https://github.com/RemyNoulin/git-off");
printf("\n");
}
else {
@@ -2403,6 +2613,11 @@ void scpoptionsF() {
thisrepo(offCommands_setGetGitConfig);
}
+void rsyncoptionsF() {
+
+ thisrepo(offCommands_setGetGitConfig);
+}
+
void scpuserF() {
thisrepo(offCommands_setGetGitConfig);
@@ -2463,6 +2678,11 @@ void copyToF() {
offCommands_copyTo();
}
+void pushF() {
+
+ offCommands_pushTo();
+}
+
void clearAllF() {
offCommands_clearAll();
@@ -2531,29 +2751,31 @@ void initCOMMAND_FUNC() {
COMMAND_FUNC[7] = pemF;
COMMAND_FUNC[8] = sshoptionsF;
COMMAND_FUNC[9] = scpoptionsF;
- COMMAND_FUNC[10] = scpuserF;
- COMMAND_FUNC[11] = trackF;
- COMMAND_FUNC[12] = configAlwaysF;
- COMMAND_FUNC[13] = s3regionF;
- COMMAND_FUNC[14] = s3bucketF;
- COMMAND_FUNC[15] = transformF;
- COMMAND_FUNC[16] = transformToF;
- COMMAND_FUNC[17] = transformFromF;
- COMMAND_FUNC[18] = cleanF;
- COMMAND_FUNC[19] = prepushF;
- COMMAND_FUNC[20] = smudgeF;
- COMMAND_FUNC[21] = copyToF;
- COMMAND_FUNC[22] = clearAllF;
- COMMAND_FUNC[23] = caF;
- COMMAND_FUNC[24] = clearCacheF;
- COMMAND_FUNC[25] = ccF;
- COMMAND_FUNC[26] = clearStoreF;
- COMMAND_FUNC[27] = csF;
- COMMAND_FUNC[28] = clearTmpF;
- COMMAND_FUNC[29] = ctF;
- COMMAND_FUNC[30] = defaultsF;
- COMMAND_FUNC[31] = envF;
- COMMAND_FUNC[32] = helpF;
+ COMMAND_FUNC[10] = rsyncoptionsF;
+ COMMAND_FUNC[11] = scpuserF;
+ COMMAND_FUNC[12] = trackF;
+ COMMAND_FUNC[13] = configAlwaysF;
+ COMMAND_FUNC[14] = s3regionF;
+ COMMAND_FUNC[15] = s3bucketF;
+ COMMAND_FUNC[16] = transformF;
+ COMMAND_FUNC[17] = transformToF;
+ COMMAND_FUNC[18] = transformFromF;
+ COMMAND_FUNC[19] = cleanF;
+ COMMAND_FUNC[20] = prepushF;
+ COMMAND_FUNC[21] = smudgeF;
+ COMMAND_FUNC[22] = copyToF;
+ COMMAND_FUNC[23] = pushF;
+ COMMAND_FUNC[24] = clearAllF;
+ COMMAND_FUNC[25] = caF;
+ COMMAND_FUNC[26] = clearCacheF;
+ COMMAND_FUNC[27] = ccF;
+ COMMAND_FUNC[28] = clearStoreF;
+ COMMAND_FUNC[29] = csF;
+ COMMAND_FUNC[30] = clearTmpF;
+ COMMAND_FUNC[31] = ctF;
+ COMMAND_FUNC[32] = defaultsF;
+ COMMAND_FUNC[33] = envF;
+ COMMAND_FUNC[34] = helpF;
COMMAND_FUNC[lastC] = NULL;
COMMAND_HELPERS[0] = NULL;
@@ -2566,15 +2788,15 @@ void initCOMMAND_FUNC() {
COMMAND_HELPERS[7] = offHelpers_offPem;
COMMAND_HELPERS[8] = offHelpers_offSshOptions;
COMMAND_HELPERS[9] = offHelpers_offScpOptions;
- COMMAND_HELPERS[10] = offHelpers_offScpUser;
- COMMAND_HELPERS[11] = NULL;
- COMMAND_HELPERS[12] = offHelpers_offConfigAlways;
- COMMAND_HELPERS[13] = offHelpers_s3Region;
- COMMAND_HELPERS[14] = offHelpers_s3Bucket;
- COMMAND_HELPERS[15] = offHelpers_transform;
- COMMAND_HELPERS[16] = offHelpers_transformTo;
- COMMAND_HELPERS[17] = offHelpers_transformFrom;
- COMMAND_HELPERS[18] = NULL;
+ COMMAND_HELPERS[10] = offHelpers_offRsyncOptions;
+ COMMAND_HELPERS[11] = offHelpers_offScpUser;
+ COMMAND_HELPERS[12] = NULL;
+ COMMAND_HELPERS[13] = offHelpers_offConfigAlways;
+ COMMAND_HELPERS[14] = offHelpers_s3Region;
+ COMMAND_HELPERS[15] = offHelpers_s3Bucket;
+ COMMAND_HELPERS[16] = offHelpers_transform;
+ COMMAND_HELPERS[17] = offHelpers_transformTo;
+ COMMAND_HELPERS[18] = offHelpers_transformFrom;
COMMAND_HELPERS[19] = NULL;
COMMAND_HELPERS[20] = NULL;
COMMAND_HELPERS[21] = NULL;
@@ -2589,6 +2811,8 @@ void initCOMMAND_FUNC() {
COMMAND_HELPERS[30] = NULL;
COMMAND_HELPERS[31] = NULL;
COMMAND_HELPERS[32] = NULL;
+ COMMAND_HELPERS[33] = NULL;
+ COMMAND_HELPERS[34] = NULL;
COMMAND_HELPERS[lastC] = NULL;
}
@@ -2598,32 +2822,15 @@ void initCOMMAND_FUNC() {
#endif
int MAIN(int ARGC, char** ARGV) {
int dummy;
- char **test = NULL;
// TODO remove dummy
- argc = ARGC; argv = ARGV;
- // init transport functions
+ argc = ARGC; argv = ARGV;;// init transport functions
transport.send = send;
transport.receive = receive;
initCOMMAND_FUNC();
// parse CLI arguments
- // TODO remove argv prints
- //dummy = 0
- //while dummy < argc
- // print argv[dummy]
- // dummy++;
-
-
- // TODO remove offHelpers_getOffFilePath test
- //transport_transformFrom("12/34/1234WERWER");
- //test = offHelpers_getOffFilePath("1234WERWER")
- //dummy = 0
- //while test[dummy] != NULL
- // print test[dummy]
- // dummy++;
-
if (argc == 1) {
offCommands_help();
}
diff --git a/c/gitoff.c b/c/gitoff.c
@@ -121,6 +121,7 @@ char *offHelpers_offIntegrity();
char *offHelpers_offPem();
char *offHelpers_offSshOptions();
char *offHelpers_offScpOptions();
+char *offHelpers_offRsyncOptions();
char *offHelpers_offScp();
char *offHelpers_offScpUser();
char *offHelpers_log();
@@ -139,6 +140,8 @@ void offHelpers_copyTo();
bool offHelpers_checkIntegrity(char *p);
void transportCopySend(char *file);
void transportCopyReceive(char *file);
+void transportRsyncSend(char *file);
+void transportRsyncReceive(char *file);
void transportScpSend(char *file);
void transportScpReceive(char *file);
void transportHttpSend(char *file);
@@ -163,6 +166,7 @@ void offCommands_prepush();
void offCommands_push(char *line);
void offCommands_smudge();
void offCommands_copyTo();
+void offCommands_pushTo();
void offCommands_clearAll();
void offCommands_clearCache();
void offCommands_clearStore();
@@ -180,6 +184,7 @@ void integrityF();
void pemF();
void sshoptionsF();
void scpoptionsF();
+void rsyncoptionsF();
void scpuserF();
void trackF();
void configAlwaysF();
@@ -192,6 +197,7 @@ void cleanF();
void prepushF();
void smudgeF();
void copyToF();
+void pushF();
void clearAllF();
void caF();
void clearCacheF();
@@ -221,18 +227,18 @@ int argc; char **argv;
// shell commands to be used with the exec function
// example: exec 'gitRepoRoot'
-enum { gitConfigGlobal, gitConfig, gitRepoRoot, gitList, gitDff, gitCat, sha, listAttr, ssh, scp, curl, mv, mkdirE, cp, rm };
-char* externalHelpers[15] = { "git config --global", "git config", "git rev-parse --show-toplevel", "git rev-list", "git diff-tree -r", "git cat-file -p", "git hash-object --no-filters", "git check-attr -a", "ssh", "scp", "curl", "mv", "mkdir -p", "cp", "rm -rf" };
+enum { gitConfigGlobal, gitConfig, gitRepoRoot, gitList, gitDff, gitCat, sha, listAttr, ssh, scp, rsync, curl, mv, mkdirE, cp, rm };
+char* externalHelpers[16] = { "git config --global", "git config", "git rev-parse --show-toplevel", "git rev-list", "git diff-tree -r", "git cat-file -p", "git hash-object --no-filters", "git check-attr -a", "ssh", "scp", "rsync", "curl", "mv", "mkdir -p", "cp -u", "rm -rf" };
// config built by offHelpers
// use offHelpers to access runtimeConfig
-enum { currentRepoRoot, objectPath, offStore, offHttp, offMode, offIntegrity, offScp, offScpUser, offPem, offSshOptions, offScpOptions, offCurlOptions, log, offConfigAlways, s3Region, s3Bucket, transform, transformTo, transformFrom, scpHost, scpPath, scpPort };
-char* runtimeConfig[22] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+enum { currentRepoRoot, objectPath, offStore, offHttp, offMode, offIntegrity, offScp, offScpUser, offPem, offSshOptions, offScpOptions, offRsyncOptions, offCurlOptions, log, offConfigAlways, s3Region, s3Bucket, transform, transformTo, transformFrom, scpHost, scpPath, scpPort };
+char* runtimeConfig[23] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
// default configuration for first time install
// objectPath is git off cache in repo
-enum { objectPathD, modeD, integrityD, pemD, scpHostD, scpUserD, sshOptionsD, scpOptionsD, storeD, httpD, curlOptionsD, logD, configAlwaysD, s3RegionD, s3BucketD, transformD, transformToD, transformFromD, prePushD, offSignatureD, lastD };
-char* offDEFAULTS[21] = { "/.git/off/objects", "copy", "disable", "offNoValue", "offNoValue", "", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p", "~/.git-off/offStore", "offNoValue", "-o", "~/.git-off/log", "offNoValue", "offNoValue", "offNoValue", "disable", "pbzip2 -9 -c _1 > _2", "pbzip2 -d -c _1 > _2", "#!/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 \"$@\"", "### git-off v1 sha:", "not used" };
+enum { objectPathD, modeD, integrityD, pemD, scpHostD, scpUserD, sshOptionsD, scpOptionsD, rsyncOptionsD, storeD, httpD, curlOptionsD, logD, configAlwaysD, s3RegionD, s3BucketD, transformD, transformToD, transformFromD, prePushD, offSignatureD, lastD };
+char* offDEFAULTS[22] = { "/.git/off/objects", "copy", "disable", "offNoValue", "offNoValue", "", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3", "-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p", "-az -e \"ssh -i _i\"", "~/.git-off/offStore", "offNoValue", "-o", "~/.git-off/log", "offNoValue", "offNoValue", "offNoValue", "disable", "pbzip2 -9 -c _1 > _2", "pbzip2 -d -c _1 > _2", "#!/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 \"$@\"", "### git-off v1 sha:", "not used" };
#define offDEFAULTS_shaLength 40
@@ -324,7 +330,7 @@ char *exec(int cmdName, char* paramsArray) {
free(cmd);
read = getline(&line, &len, fp);
- fclose(fp);
+ pclose(fp);
if (read == -1) {
// nothing was read
@@ -443,19 +449,22 @@ char *gitConfig_get(char *key) {
}
}
- p = malloc(strlen(offHelpers_gitRepoRoot()) + 1 + 9);
- sprintf(p, "%s/.git-off", offHelpers_gitRepoRoot());
- if (access(p, F_OK) != -1) {
- free(p);
- p = malloc(strlen(offHelpers_gitRepoRoot()) + strlen(key) + 1 + 17);
- sprintf(p, "--file %s/.git-off %s", offHelpers_gitRepoRoot() , key);
- r = exec(gitConfig, p);
- if (r != NULL) {
+ if (offHelpers_gitRepoRoot()) {
+ // skip repo config when running outside a git repo
+ p = malloc(strlen(offHelpers_gitRepoRoot()) + 1 + 9);
+ sprintf(p, "%s/.git-off", offHelpers_gitRepoRoot());
+ if (access(p, F_OK) != -1) {
free(p);
- return(r);
- }
+ p = malloc(strlen(offHelpers_gitRepoRoot()) + strlen(key) + 1 + 17);
+ sprintf(p, "--file %s/.git-off %s", offHelpers_gitRepoRoot() , key);
+ r = exec(gitConfig, p);
+ if (r != NULL) {
+ free(p);
+ return(r);
}
- free(p);
+ }
+ free(p);
+ }
r = gitConfig_getDefault(key);
return(r);
}
@@ -531,7 +540,7 @@ char **execOut(char *cmd) {
count++;
}
- fclose(fp);
+ pclose(fp);
return(list);
}
@@ -586,7 +595,11 @@ char **split(char *string, char* delim) {
}
r[count] = strdup(token);
count++;
+ // macOS sets workingString to NULL at the end
+ if (!workingString) {
+ break;
}
+ }
free(startString);
return(r);
@@ -726,6 +739,14 @@ char *offHelpers_offScpOptions() {
return(runtimeConfig[offScpOptions]);
}
+char *offHelpers_offRsyncOptions() {
+
+ if (runtimeConfig[offRsyncOptions] == NULL) {
+ runtimeConfig[offRsyncOptions] = gitConfig_get("off.rsyncoptions");
+ }
+ return(runtimeConfig[offRsyncOptions]);
+}
+
char *offHelpers_offScp() {
if (runtimeConfig[offScp] == NULL) {
@@ -1110,6 +1131,158 @@ void transportCopyReceive(char *file) {
}
+void transportRsyncSend(char *file) {
+ // create file directories in store
+ char **f_l = NULL;
+ char *p = NULL;
+ char *pem = NULL;
+ char *params = NULL;
+ char *options = NULL;
+ char *options2 = NULL;
+ char *tmp = NULL;
+
+ f_l = split(file, "/");
+ p = malloc(strlen(f_l[0]) + strlen(f_l[1]) + 1 + 1);
+ sprintf(p, "%s/%s", f_l[0], f_l[1]);
+ offHelpers_mkdirStore(p);
+ free(p);
+
+ options = strdup(offHelpers_offRsyncOptions());
+
+ // set pem or not? check rsyncoptions
+ // find _i index in options
+ tmp = strstr(options, " _i");
+ if (tmp != NULL) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
+ options2 = strdup(options);
+ }
+ else {
+ tmp[1] = 0;
+ options2 = malloc(strlen(options) + strlen(offHelpers_offPem()) + strlen(tmp+3) + 1 + 0);
+ sprintf(options2, "%s%s%s", options, offHelpers_offPem(), tmp+3);
+ }
+ }
+ else {
+ options2 = strdup(options);
+ }
+
+ char *dest;
+
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_objectPath(), file);
+ dest = malloc(strlen(offHelpers_offScp()) + strlen(file) + 1 + 1);
+ sprintf(dest, "%s/%s", offHelpers_offScp(), file);
+
+ params = malloc(strlen(options2) + strlen(p) + strlen(dest) + 1 + 2);
+ sprintf(params, "%s %s %s", options2, p, dest);
+
+ exec(rsync, params);
+
+ free(p);
+ free(dest);
+ free(pem);
+ free(params);
+ free(options);
+ free(options2);
+}
+
+void transportRsyncReceive(char *file) {
+ char *p = NULL;
+ char **f_l = NULL;
+ DIR *d = NULL;
+ char *pem = NULL;
+ char *params = NULL;
+ char *options = NULL;
+ char *options2 = NULL;
+ char *tmp = NULL;
+
+ // create file directories in cache
+ f_l = split(file, "/");
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(f_l[0]) + strlen(f_l[1]) + 1 + 2);
+ sprintf(p, "%s/%s/%s", offHelpers_objectPath(), f_l[0], f_l[1]);
+ d = opendir(p);;
+ if (d == NULL) {
+ mkdirParents(p);
+ }
+ free(p);
+ freeList((void **)f_l);
+
+
+ options = strdup(offHelpers_offRsyncOptions());
+
+ // set pem or not? check rsyncoptions
+ // find _i index in options
+ tmp = strstr(options, " _i");
+ if (tmp != NULL) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
+ options2 = strdup(options);
+ }
+ else {
+ tmp[1] = 0;
+ options2 = malloc(strlen(options) + strlen(offHelpers_offPem()) + strlen(tmp+3) + 1 + 0);
+ sprintf(options2, "%s%s%s", options, offHelpers_offPem(), tmp+3);
+ }
+ }
+ else {
+ options2 = strdup(options);
+ }
+
+ char *dest;
+
+ dest = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(dest, "%s/%s", offHelpers_objectPath(), file);
+ p = malloc(strlen(offHelpers_offScp()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_offScp(), file);
+
+ params = malloc(strlen(options2) + strlen(p) + strlen(dest) + 1 + 2);
+ sprintf(params, "%s %s %s", options2, p, dest);
+
+ exec(rsync, params);
+
+ free(p);
+ free(dest);
+ free(pem);
+ free(params);
+ free(options);
+ free(options2);
+
+ // transform
+ int sR;
+ char b[1024];
+ FILE *f;
+
+ if ((strEq(offHelpers_transform(), "enable")) && (offHelpers_transformFrom() != NULL)) {
+ transport_transformFrom(file);
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 8);
+ sprintf(p, "%s/../tmp/%s", offHelpers_objectPath(), file);
+ if (offHelpers_checkIntegrity(p)) {
+ f = fopen(p, "r");
+ sR = fread(b, 1, 1024, f);
+ while (sR != 0) {
+ fwrite(b, 1, sR, stdout);
+ sR = fread(b, 1, 1024, f);
+ }
+ fclose(f);
+ }
+ }
+ else {
+ p = malloc(strlen(offHelpers_objectPath()) + strlen(file) + 1 + 1);
+ sprintf(p, "%s/%s", offHelpers_objectPath(), file);
+ if (offHelpers_checkIntegrity(p)) {
+ f = fopen(p, "r");
+ sR = fread(b, 1, 1024, f);
+ while (sR != 0) {
+ fwrite(b, 1, sR, stdout);
+ sR = fread(b, 1, 1024, f);
+ }
+ fclose(f);
+ }
+ }
+
+ free(p);
+}
+
+
void transportScpSend(char *file) {
// create file directories in store
char **f_l = NULL;
@@ -1127,7 +1300,7 @@ void transportScpSend(char *file) {
h_l = offHelpers_getSSHConfig();
// setup ssh/scp private key
- if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue")) || (offHelpers_offPem() == NULL)) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
pem = strdup("");
}
else {
@@ -1182,7 +1355,7 @@ void transportScpReceive(char *file) {
h_l = offHelpers_getSSHConfig();
// setup ssh/scp private key
- if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue")) || (offHelpers_offPem() == NULL)) {
+ if ((offHelpers_offPem() == NULL) || (strEq(offHelpers_offPem(), "offNoValue"))) {
pem = strdup("");
}
else {
@@ -1337,6 +1510,12 @@ void offHelpers_setTransport(char *mode ) {
transport.receive = transportCopyReceive;
}
+ // rsync mode
+ else if (strEq(m, "rsync")) {
+ transport.send = transportRsyncSend;
+ transport.receive = transportRsyncReceive;
+ }
+
// scp mode
else if (strEq(m, "scp")) {
transport.send = transportScpSend;
@@ -1527,14 +1706,14 @@ void thisrepo(cmdSetF_t cmd) {
-enum { installH, modeH, storeH, scpH, httpH, curlH, integrityH, pemH, sshoptionsH, scpoptionsH, scpuserH, trackH, configAlwaysH, s3regionH, s3bucketH, transformH, transformToH, transformFromH, cleanH, prepushH, smudgeH, copyToH, clearAllH, caH, clearCacheH, ccH, clearStoreH, csH, clearTmpH, ctH, defaultsH, envH, helpH, lastH };
-char* COMMAND_HELP[34] = { "git off install [thisrepo]\n setup git config (default global)\n thisrepo sets up config in current repo", "git off mode [thisrepo] [copy|scp|http|s3]\n set/show git off mode", "git off store [thisrepo] [path]\n set/show git off store path for copy mode", "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", "git off http [thisrepo] [host]\n setup http config\n host has format http host/path\n Example http localhost/offStore", "git off curl [thisrepo] [options]\n setup curl config", "git off integrity [thisrepo] [enable|disable]\n set/show git off integrity.\n when enabled, the SHA of the file received from the store is\n checked again the SHA of the original file", "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)", "git off sshoptions [thisrepo] [options]\n set/show git off sshoptions", "git off scpoptions [thisrepo] [options]\n set/show git off scpoptions", "git off scpuser [thisrepo] [username]\n setup scp username config", "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", "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", "git off s3region [thisrepo] [region]\n setup amazon s3 region for the bucket", "git off s3bucket [thisrepo] [bucket]\n setup amazon s3 bucket", "git off transform [thisrepo] [enable|disable]\n enable transform in clean and smudge filters", "git off transformTo [thisrepo] [\"cmd _1 _2\"]\n setup transform command for clear filter\n When the command is empty the regular transport is performed", "git off transformFrom [thisrepo] [\"cmd _1 _2\"]\n setup transform command for smudge filter\n When the command is empty the regular transport is performed", "git off clean\n internal filter\n dont use directly", "git off pre-push\n internal filter\n dont use directly", "git off smudge\n internal filter\n dont use directly", "git off copyTo [copy|scp|s3]\n copy cache to store for specified mode", "git off clearAll\n delete store, cache and log", "git off ca\n delete store, cache and log", "git off clearCache\n delete cache in current git", "git off cc\n delete cache in current git", "git off clearStore\n delete store", "git off cs\n delete store", "git off clearTmp\n delete tmp in git off cache\n Useful when transform is enabled", "git off ct\n delete tmp in git off cache\n Useful when transform is enabled", "git off defaults\n shows first time config", "git off env\n shows config", "git off help [cmd]\n git off help. Run git off help command to get help for a specific command.", "not a command" };
+enum { installH, modeH, storeH, scpH, httpH, curlH, integrityH, pemH, sshoptionsH, scpoptionsH, rsyncoptionsH, scpuserH, trackH, configAlwaysH, s3regionH, s3bucketH, transformH, transformToH, transformFromH, cleanH, prepushH, smudgeH, copyToH, pushH, clearAllH, caH, clearCacheH, ccH, clearStoreH, csH, clearTmpH, ctH, defaultsH, envH, helpH, lastH };
+char* COMMAND_HELP[36] = { "git off install [thisrepo]\n setup git config (default global)\n thisrepo sets up config in current repo", "git off mode [thisrepo] [copy|rsync|scp|http|s3]\n set/show git off mode", "git off store [thisrepo] [path]\n set/show git off store path for copy mode", "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", "git off http [thisrepo] [host]\n setup http config\n host has format http://host/path\n Example http://localhost/offStore", "git off curl [thisrepo] [options]\n setup curl config", "git off integrity [thisrepo] [enable|disable]\n set/show git off integrity.\n when enabled, the SHA of the file received from the store is\n checked again the SHA of the original file", "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)", "git off sshoptions [thisrepo] [options]\n set/show git off sshoptions", "git off scpoptions [thisrepo] [options]\n set/show git off scpoptions", "git off rsyncoptions [thisrepo] [options]\n set/show git off rsyncoptions", "git off scpuser [thisrepo] [username]\n setup scp username config", "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", "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", "git off s3region [thisrepo] [region]\n setup amazon s3 region for the bucket", "git off s3bucket [thisrepo] [bucket]\n setup amazon s3 bucket", "git off transform [thisrepo] [enable|disable]\n enable transform in clean and smudge filters", "git off transformTo [thisrepo] [\"cmd _1 _2\"]\n setup transform command for clear filter\n When the command is empty the regular transport is performed", "git off transformFrom [thisrepo] [\"cmd _1 _2\"]\n setup transform command for smudge filter\n When the command is empty the regular transport is performed", "git off clean\n internal filter\n dont use directly", "git off pre-push\n internal filter\n dont use directly", "git off smudge\n internal filter\n dont use directly", "git off copyTo [copy|rsync|scp|s3]\n copy cache to store for specified mode", "git off push\n copy cache to store for selected mode", "git off clearAll\n delete store, cache and log", "git off ca\n delete store, cache and log", "git off clearCache\n delete cache in current git", "git off cc\n delete cache in current git", "git off clearStore\n delete store", "git off cs\n delete store", "git off clearTmp\n delete tmp in git off cache\n Useful when transform is enabled", "git off ct\n delete tmp in git off cache\n Useful when transform is enabled", "git off defaults\n shows first time config", "git off env\n shows config", "git off help [cmd]\n git off help. Run git off help command to get help for a specific command.", "not a command" };
-enum { installC, modeC, storeC, scpC, httpC, curlC, integrityC, pemC, sshoptionsC, scpoptionsC, scpuserC, trackC, configAlwaysC, s3regionC, s3bucketC, transformC, transformToC, transformFromC, cleanC, prepushC, smudgeC, copyToC, clearAllC, caC, clearCacheC, ccC, clearStoreC, csC, clearTmpC, ctC, defaultsC, envC, helpC, lastC };
-char* COMMAND_MAP[34] = { "install", "mode", "store", "scp", "http", "curl", "integrity", "pem", "sshoptions", "scpoptions", "scpuser", "track", "configAlways", "s3region", "s3bucket", "transform", "transformTo", "transformFrom", "clean", "pre-push", "smudge", "copyTo", "clearAll", "ca", "clearCache", "cc", "clearStore", "cs", "clearTmp", "ct", "defaults", "env", "help", "not a command" };
+enum { installC, modeC, storeC, scpC, httpC, curlC, integrityC, pemC, sshoptionsC, scpoptionsC, rsyncoptionsC, scpuserC, trackC, configAlwaysC, s3regionC, s3bucketC, transformC, transformToC, transformFromC, cleanC, prepushC, smudgeC, copyToC, pushC, clearAllC, caC, clearCacheC, ccC, clearStoreC, csC, clearTmpC, ctC, defaultsC, envC, helpC, lastC };
+char* COMMAND_MAP[36] = { "install", "mode", "store", "scp", "http", "curl", "integrity", "pem", "sshoptions", "scpoptions", "rsyncoptions", "scpuser", "track", "configAlways", "s3region", "s3bucket", "transform", "transformTo", "transformFrom", "clean", "pre-push", "smudge", "copyTo", "push", "clearAll", "ca", "clearCache", "cc", "clearStore", "cs", "clearTmp", "ct", "defaults", "env", "help", "not a command" };
-enum { installG, modeG, storeG, scpG, httpG, curlG, integrityG, pemG, sshoptionsG, scpoptionsG, scpuserG, trackG, configAlwaysG, s3regionG, s3bucketG, transformG, transformToG, transformFromG, cleanG, prepushG, smudgeG, copyToG, clearAllG, caG, clearCacheG, ccG, clearStoreG, csG, clearTmpG, ctG, defaultsG, envG, helpG, lastG };
-char* COMMAND_GITCONFIG[34] = { "empty", "off.mode", "off.store", "off.scp", "off.http", "off.curloptions", "off.integrity", "off.pem", "off.sshoptions", "off.scpoptions", "off.scpuser", "empty", "off.configAlways", "off.s3region", "off.s3bucket", "off.transform", "off.transformTo", "off.transformFrom", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "not a command" };
+enum { installG, modeG, storeG, scpG, httpG, curlG, integrityG, pemG, sshoptionsG, scpoptionsG, rsyncoptionsG, scpuserG, trackG, configAlwaysG, s3regionG, s3bucketG, transformG, transformToG, transformFromG, cleanG, prepushG, smudgeG, copyToG, pushG, clearAllG, caG, clearCacheG, ccG, clearStoreG, csG, clearTmpG, ctG, defaultsG, envG, helpG, lastG };
+char* COMMAND_GITCONFIG[36] = { "empty", "off.mode", "off.store", "off.scp", "off.http", "off.curloptions", "off.integrity", "off.pem", "off.sshoptions", "off.scpoptions", "off.rsyncoptions", "off.scpuser", "empty", "off.configAlways", "off.s3region", "off.s3bucket", "off.transform", "off.transformTo", "off.transformFrom", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "empty", "not a command" };
// functions called for commands
typedef void (*cmdF_t)();
@@ -1661,6 +1840,9 @@ void offCommands_install(gConfig_set_t setF ) {
if ((offHelpers_offScpOptions() == NULL) || (setF != gitConfig_set)) {
setF("off.scpoptions", offDEFAULTS[scpOptionsD]);
}
+ if ((offHelpers_offRsyncOptions() == NULL) || (setF != gitConfig_set)) {
+ setF("off.rsyncoptions", offDEFAULTS[rsyncOptionsD]);
+ }
if ((offHelpers_offStore() == NULL) || (setF != gitConfig_set)) {
setF("off.store", offDEFAULTS[storeD]);
}
@@ -1695,7 +1877,7 @@ void offCommands_install(gConfig_set_t setF ) {
mkdirParents(runtimeConfig[offStore]);
}
- if (strEq(runtimeConfig[offMode], "scp")) {
+ if (strEq(runtimeConfig[offMode], "scp") || strEq(runtimeConfig[offMode], "rsync")) {
offHelpers_mkdirStore("");
}
}
@@ -1751,10 +1933,17 @@ void offCommands_configAlways() {
gitConfig_set(COMMAND_GITCONFIG[configAlwaysC], argv[argc-1]);
}
else {
- printf("%s %s", COMMAND_GITCONFIG[configAlwaysC], COMMAND_HELPERS[configAlwaysC]());
- printf("\n");
+ if (COMMAND_HELPERS[configAlwaysC]()) {
+ // print when config is available
+ printf("%s %s", COMMAND_GITCONFIG[configAlwaysC], COMMAND_HELPERS[configAlwaysC]());
+ printf("\n");
+ }
+ else {
+ printf("Not in config: %s", COMMAND_GITCONFIG[configAlwaysC]);
+ printf("\n");
}
}
+ }
void offCommands_setGetGitConfig(gConfig_set_t setF) {
int i;
@@ -1764,10 +1953,16 @@ void offCommands_setGetGitConfig(gConfig_set_t setF) {
setF(COMMAND_GITCONFIG[i], argv[argc-1]);
}
else {
- printf("%s %s", COMMAND_GITCONFIG[i], COMMAND_HELPERS[i]());
- printf("\n");
+ if (COMMAND_HELPERS[i]()) {
+ printf("%s %s", COMMAND_GITCONFIG[i], COMMAND_HELPERS[i]());
+ printf("\n");
+ }
+ else {
+ printf("Not in config: %s", COMMAND_GITCONFIG[i]);
+ printf("\n");
}
}
+ }
void offCommands_clean() {
char *file = NULL;
@@ -2154,6 +2349,16 @@ void offCommands_copyTo() {
offHelpers_copyTo();
}
+void offCommands_pushTo() {
+
+ if (offHelpers_offMode() != NULL) {
+ printf("mode: %s", offHelpers_offMode());
+ printf("\n");
+ offHelpers_setTransport(offHelpers_offMode());
+ offHelpers_copyTo();
+}
+ }
+
void offCommands_clearAll() {
// delete store, cache in current git and log
@@ -2178,7 +2383,7 @@ void offCommands_clearStore() {
if (strEq(offHelpers_offMode(), "copy")) {
rmAll(offHelpers_offStore());
}
- if (strEq(offHelpers_offMode(), "scp")) {
+ if (strEq(offHelpers_offMode(), "scp") || strEq(offHelpers_offMode(), "rsync")) {
offHelpers_rmAllStore("");
}
}
@@ -2231,6 +2436,11 @@ void offCommands_env() {
printf("off.scpoptions %s", offHelpers_offScpOptions());
printf("\n");
}
+ s = offHelpers_offRsyncOptions();
+ if (s != NULL) {
+ printf("off.rsyncoptions %s", offHelpers_offRsyncOptions());
+ printf("\n");
+ }
s = offHelpers_offStore();
if (s != NULL) {
printf("off.store %s", offHelpers_offStore());
@@ -2333,7 +2543,7 @@ void offCommands_help() {
showAllCommandsHelp();
- printf("More information at");
+ printf("More information at https://github.com/RemyNoulin/git-off");
printf("\n");
}
else {
@@ -2402,6 +2612,11 @@ void scpoptionsF() {
thisrepo(offCommands_setGetGitConfig);
}
+void rsyncoptionsF() {
+
+ thisrepo(offCommands_setGetGitConfig);
+}
+
void scpuserF() {
thisrepo(offCommands_setGetGitConfig);
@@ -2462,6 +2677,11 @@ void copyToF() {
offCommands_copyTo();
}
+void pushF() {
+
+ offCommands_pushTo();
+}
+
void clearAllF() {
offCommands_clearAll();
@@ -2530,29 +2750,31 @@ void initCOMMAND_FUNC() {
COMMAND_FUNC[7] = pemF;
COMMAND_FUNC[8] = sshoptionsF;
COMMAND_FUNC[9] = scpoptionsF;
- COMMAND_FUNC[10] = scpuserF;
- COMMAND_FUNC[11] = trackF;
- COMMAND_FUNC[12] = configAlwaysF;
- COMMAND_FUNC[13] = s3regionF;
- COMMAND_FUNC[14] = s3bucketF;
- COMMAND_FUNC[15] = transformF;
- COMMAND_FUNC[16] = transformToF;
- COMMAND_FUNC[17] = transformFromF;
- COMMAND_FUNC[18] = cleanF;
- COMMAND_FUNC[19] = prepushF;
- COMMAND_FUNC[20] = smudgeF;
- COMMAND_FUNC[21] = copyToF;
- COMMAND_FUNC[22] = clearAllF;
- COMMAND_FUNC[23] = caF;
- COMMAND_FUNC[24] = clearCacheF;
- COMMAND_FUNC[25] = ccF;
- COMMAND_FUNC[26] = clearStoreF;
- COMMAND_FUNC[27] = csF;
- COMMAND_FUNC[28] = clearTmpF;
- COMMAND_FUNC[29] = ctF;
- COMMAND_FUNC[30] = defaultsF;
- COMMAND_FUNC[31] = envF;
- COMMAND_FUNC[32] = helpF;
+ COMMAND_FUNC[10] = rsyncoptionsF;
+ COMMAND_FUNC[11] = scpuserF;
+ COMMAND_FUNC[12] = trackF;
+ COMMAND_FUNC[13] = configAlwaysF;
+ COMMAND_FUNC[14] = s3regionF;
+ COMMAND_FUNC[15] = s3bucketF;
+ COMMAND_FUNC[16] = transformF;
+ COMMAND_FUNC[17] = transformToF;
+ COMMAND_FUNC[18] = transformFromF;
+ COMMAND_FUNC[19] = cleanF;
+ COMMAND_FUNC[20] = prepushF;
+ COMMAND_FUNC[21] = smudgeF;
+ COMMAND_FUNC[22] = copyToF;
+ COMMAND_FUNC[23] = pushF;
+ COMMAND_FUNC[24] = clearAllF;
+ COMMAND_FUNC[25] = caF;
+ COMMAND_FUNC[26] = clearCacheF;
+ COMMAND_FUNC[27] = ccF;
+ COMMAND_FUNC[28] = clearStoreF;
+ COMMAND_FUNC[29] = csF;
+ COMMAND_FUNC[30] = clearTmpF;
+ COMMAND_FUNC[31] = ctF;
+ COMMAND_FUNC[32] = defaultsF;
+ COMMAND_FUNC[33] = envF;
+ COMMAND_FUNC[34] = helpF;
COMMAND_FUNC[lastC] = NULL;
COMMAND_HELPERS[0] = NULL;
@@ -2565,15 +2787,15 @@ void initCOMMAND_FUNC() {
COMMAND_HELPERS[7] = offHelpers_offPem;
COMMAND_HELPERS[8] = offHelpers_offSshOptions;
COMMAND_HELPERS[9] = offHelpers_offScpOptions;
- COMMAND_HELPERS[10] = offHelpers_offScpUser;
- COMMAND_HELPERS[11] = NULL;
- COMMAND_HELPERS[12] = offHelpers_offConfigAlways;
- COMMAND_HELPERS[13] = offHelpers_s3Region;
- COMMAND_HELPERS[14] = offHelpers_s3Bucket;
- COMMAND_HELPERS[15] = offHelpers_transform;
- COMMAND_HELPERS[16] = offHelpers_transformTo;
- COMMAND_HELPERS[17] = offHelpers_transformFrom;
- COMMAND_HELPERS[18] = NULL;
+ COMMAND_HELPERS[10] = offHelpers_offRsyncOptions;
+ COMMAND_HELPERS[11] = offHelpers_offScpUser;
+ COMMAND_HELPERS[12] = NULL;
+ COMMAND_HELPERS[13] = offHelpers_offConfigAlways;
+ COMMAND_HELPERS[14] = offHelpers_s3Region;
+ COMMAND_HELPERS[15] = offHelpers_s3Bucket;
+ COMMAND_HELPERS[16] = offHelpers_transform;
+ COMMAND_HELPERS[17] = offHelpers_transformTo;
+ COMMAND_HELPERS[18] = offHelpers_transformFrom;
COMMAND_HELPERS[19] = NULL;
COMMAND_HELPERS[20] = NULL;
COMMAND_HELPERS[21] = NULL;
@@ -2588,6 +2810,8 @@ void initCOMMAND_FUNC() {
COMMAND_HELPERS[30] = NULL;
COMMAND_HELPERS[31] = NULL;
COMMAND_HELPERS[32] = NULL;
+ COMMAND_HELPERS[33] = NULL;
+ COMMAND_HELPERS[34] = NULL;
COMMAND_HELPERS[lastC] = NULL;
}
@@ -2597,32 +2821,15 @@ void initCOMMAND_FUNC() {
#endif
int MAIN(int ARGC, char** ARGV) {
int dummy;
- char **test = NULL;
// TODO remove dummy
- argc = ARGC; argv = ARGV;
- // init transport functions
+ argc = ARGC; argv = ARGV;;// init transport functions
transport.send = send;
transport.receive = receive;
initCOMMAND_FUNC();
// parse CLI arguments
- // TODO remove argv prints
- //dummy = 0
- //while dummy < argc
- // print argv[dummy]
- // dummy++;
-
-
- // TODO remove offHelpers_getOffFilePath test
- //transport_transformFrom("12/34/1234WERWER");
- //test = offHelpers_getOffFilePath("1234WERWER")
- //dummy = 0
- //while test[dummy] != NULL
- // print test[dummy]
- // dummy++;
-
if (argc == 1) {
offCommands_help();
}
diff --git a/package.json b/package.json
@@ -1,6 +1,6 @@
{
"name": "git-off",
- "version": "0.0.12",
+ "version": "0.0.13",
"description": "large file handler for git",
"bin": "./src/git-off",
"scripts": {
diff --git a/src/git-off b/src/git-off
@@ -87,7 +87,8 @@ externalHelpers = {
'ssh': 'ssh',
'scp': 'scp',
'curl': 'curl',
- 'mv': 'mv'
+ 'mv': 'mv',
+ 'rsync': 'rsync'
};
runtimeConfig = {
@@ -102,6 +103,7 @@ runtimeConfig = {
'offPem': '',
'offSshOptions': '',
'offScpOptions': '',
+ 'offRsyncOptions': '',
'offCurlOptions': '',
'log': '',
'offConfigAlways': '',
@@ -121,6 +123,7 @@ offDEFAULTS = {
'scpUser': '',
'sshOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3',
'scpOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p',
+ 'rsyncOptions': '-az -e \'ssh -i _i\'',
'store': '~/.git-off/offStore',
'http': 'offNoValue',
'curlOptions': '-o',
@@ -335,6 +338,12 @@ offHelpers = {
}
return runtimeConfig.offScpOptions;
},
+ 'offRsyncOptions': function() {
+ if (runtimeConfig.offRsyncOptions === '') {
+ runtimeConfig.offRsyncOptions = gitConfig.get('off.rsyncoptions');
+ }
+ return runtimeConfig.offRsyncOptions;
+ },
'offScp': function() {
if (runtimeConfig.offScp === '') {
runtimeConfig.offScp = gitConfig.get('off.scphost');
@@ -525,6 +534,45 @@ offHelpers = {
}
}
};
+ } else if (mode === 'rsync') {
+ transport['send'] = function(file) {
+ var f_l, options;
+ f_l = file.split('/');
+ offHelpers.mkdirStore(f_l[0] + '/' + f_l[1]);
+ options = offHelpers.offRsyncOptions();
+ if (options.indexOf('_i') !== -1) {
+ if (offHelpers.offPem() !== '' && offHelpers.offPem() !== 'offNoValue') {
+ options = options.replace('_i', offHelpers.offPem());
+ }
+ }
+ exec('rsync', [options, offHelpers.objectPath() + '/' + file, offHelpers.offScp() + '/' + file]);
+ };
+ transport['receive'] = function(file) {
+ var f_l, options, 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]);
+ }
+ options = offHelpers.offRsyncOptions();
+ if (options.indexOf('_i') !== -1) {
+ if (offHelpers.offPem() !== '' && offHelpers.offPem() !== 'offNoValue') {
+ options = options.replace('_i', offHelpers.offPem());
+ }
+ }
+ exec('rsync', [options, offHelpers.offScp() + '/' + file, offHelpers.objectPath() + '/' + file]);
+ if (offHelpers.transform() === 'enable' && offHelpers.transformFrom() !== '') {
+ transport['transformFrom'](file);
+ if (offHelpers.checkIntegrity(offHelpers.objectPath() + '/../tmp/' + file)) {
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/../tmp/' + file);
+ readStream.pipe(process.stdout);
+ }
+ } else {
+ if (offHelpers.checkIntegrity(offHelpers.objectPath() + '/' + file)) {
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file);
+ readStream.pipe(process.stdout);
+ }
+ }
+ };
} else if (mode === 'scp') {
transport['send'] = function(file) {
var f_l, h_l, pem;
@@ -731,6 +779,9 @@ offCommands = {
if (offHelpers.offScpOptions() === '' || setCfg !== gitConfig.set) {
setCfg('off.scpoptions', offDEFAULTS.scpOptions);
}
+ if (offHelpers.offRsyncOptions() === '' || setCfg !== gitConfig.set) {
+ setCfg('off.rsyncoptions', offDEFAULTS.rsyncOptions);
+ }
if (offHelpers.offStore() === '' || setCfg !== gitConfig.set) {
setCfg('off.store', offDEFAULTS.store);
}
@@ -761,7 +812,7 @@ offCommands = {
if (runtimeConfig.offMode === 'copy') {
mkdirParents(runtimeConfig.offStore);
}
- if (runtimeConfig.offMode === 'scp') {
+ if (runtimeConfig.offMode === 'scp' || runtimeConfig.offMode === 'rsync') {
offHelpers.mkdirStore('');
}
},
@@ -855,6 +906,16 @@ offCommands = {
console.log('off.scpoptions '.blue.bold + offHelpers.offScpOptions());
}
},
+ 'rsyncoptions': function(setCfg) {
+ var len, rsyncoptions;
+ len = process.argv.length;
+ rsyncoptions = process.argv[len - 1];
+ if (rsyncoptions !== 'rsyncoptions' && rsyncoptions !== 'thisrepo') {
+ setCfg('off.rsyncoptions', rsyncoptions);
+ } else {
+ console.log('off.rsyncoptions '.blue.bold + offHelpers.offRsyncOptions());
+ }
+ },
'scpUser': function(setCfg) {
var len, scpUser;
len = process.argv.length;
@@ -1080,6 +1141,12 @@ offCommands = {
offHelpers.setTransport(process.argv[3]);
offHelpers.copyTo();
},
+ 'pushTo': function() {
+ if (offHelpers.offMode() !== void 0) {
+ offHelpers.setTransport(offHelpers.offMode());
+ offHelpers.copyTo();
+ }
+ },
'clearAll': function() {
offCommands.clearStore();
offCommands.clearCache();
@@ -1092,7 +1159,7 @@ offCommands = {
if (offHelpers.offMode() === 'copy') {
rmAll(offHelpers.offStore());
}
- if (offHelpers.offMode() === 'scp') {
+ if (offHelpers.offMode() === 'scp' || offHelpers.offMode() === 'rsync') {
offHelpers.rmAllStore('');
}
},
@@ -1113,6 +1180,7 @@ offCommands = {
console.log('off.pem '.blue.bold + offHelpers.offPem());
console.log('off.sshoptions '.blue.bold + offHelpers.offSshOptions());
console.log('off.scpoptions '.blue.bold + offHelpers.offScpOptions());
+ console.log('off.rsyncoptions '.blue.bold + offHelpers.offRsyncOptions());
console.log('off.store '.blue.bold + offHelpers.offStore());
console.log('off.http '.blue.bold + offHelpers.offHttp());
console.log('off.curloptions '.blue.bold + offHelpers.offCurlOptions());
@@ -1194,7 +1262,7 @@ COMMAND_MAP = {
f: function() {
thisrepo(offCommands['mode']);
},
- h: 'git off mode [thisrepo] [copy|scp|http|s3]\n set/show git off mode'
+ h: 'git off mode [thisrepo] [copy|rsync|scp|http|s3]\n set/show git off mode'
},
'store': {
f: function() {
@@ -1230,7 +1298,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\n set 'offNoValue' to set an empty value (useful when there are multiple configs)"
+ h: "git off pem [thisrepo] [pathToPrivateKey]\n set/show git off pem.\n off.pem is the private key for ssh, rsync and scp\n set 'offNoValue' to set an empty value (useful when there are multiple configs)"
},
'sshoptions': {
f: function() {
@@ -1244,6 +1312,12 @@ COMMAND_MAP = {
},
h: 'git off scpoptions [thisrepo] [options]\n set/show git off scpoptions'
},
+ 'rsyncoptions': {
+ f: function() {
+ thisrepo(offCommands['rsyncoptions']);
+ },
+ h: 'git off rsyncoptions [thisrepo] [options]\n set/show git off rsyncoptions'
+ },
'scpuser': {
f: function() {
thisrepo(offCommands['scpUser']);
@@ -1314,7 +1388,13 @@ COMMAND_MAP = {
f: function() {
offCommands.copyTo();
},
- h: 'git off copyTo [copy|scp|s3]\n copy cache to store for specified mode'
+ h: 'git off copyTo [copy|rsync|scp|s3]\n copy cache to store for specified mode'
+ },
+ 'push': {
+ f: function() {
+ offCommands.pushTo();
+ },
+ h: 'git off push\n copy cache to store for selected mode'
},
'clearAll': {
f: function() {
diff --git a/src/gitoff.coffee b/src/gitoff.coffee
@@ -109,6 +109,7 @@ externalHelpers =
'scp': 'scp'
'curl': 'curl'
'mv': 'mv'
+ 'rsync': 'rsync'
# config built by offHelpers
# use offHelpers to access runtimeConfig
@@ -124,6 +125,7 @@ runtimeConfig =
'offPem': ''
'offSshOptions': ''
'offScpOptions': ''
+ 'offRsyncOptions': ''
'offCurlOptions': ''
'log': ''
'offConfigAlways': ''
@@ -144,6 +146,7 @@ offDEFAULTS =
'scpUser': ''
'sshOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3'
'scpOptions': '-C -o StrictHostKeyChecking=no -o ConnectTimeout=3 -p'
+ 'rsyncOptions': '-az -e \'ssh -i _i\''
'store': '~/.git-off/offStore'
'http': 'offNoValue'
'curlOptions': '-o'
@@ -359,6 +362,11 @@ offHelpers =
runtimeConfig.offScpOptions = gitConfig.get 'off.scpoptions'
runtimeConfig.offScpOptions
+ 'offRsyncOptions': ->
+ if runtimeConfig.offRsyncOptions == ''
+ runtimeConfig.offRsyncOptions = gitConfig.get 'off.rsyncoptions'
+ runtimeConfig.offRsyncOptions
+
'offScp': ->
if runtimeConfig.offScp == ''
runtimeConfig.offScp = gitConfig.get 'off.scphost'
@@ -560,6 +568,52 @@ offHelpers =
readStream.pipe(process.stdout)
return
+ # rsync mode
+ else if mode == 'rsync'
+ transport['send'] = (file) ->
+
+ # create file directories in store
+ f_l = file.split '/'
+ offHelpers.mkdirStore f_l[0] + '/' + f_l[1]
+
+ # set pem or not? check rsyncoptions
+ options = offHelpers.offRsyncOptions()
+ if options.indexOf('_i') != -1
+ # there is an identity setting in options
+ # setup ssh/scp private key
+ if offHelpers.offPem() != '' and offHelpers.offPem() != 'offNoValue'
+ options = options.replace '_i', offHelpers.offPem()
+
+ exec 'rsync', [options, offHelpers.objectPath() + '/' + file, offHelpers.offScp() + '/' + file]
+ 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]
+
+ # set pem or not? check rsyncoptions
+ options = offHelpers.offRsyncOptions()
+ if options.indexOf('_i') != -1
+ # there is an identity setting in options
+ # setup ssh/scp private key
+ if offHelpers.offPem() != '' and offHelpers.offPem() != 'offNoValue'
+ options = options.replace '_i', offHelpers.offPem()
+
+ exec 'rsync', [options, offHelpers.offScp() + '/' + file, offHelpers.objectPath() + '/' + file]
+
+ # transform
+ if offHelpers.transform() == 'enable' and offHelpers.transformFrom() != ''
+ transport['transformFrom'](file)
+ if offHelpers.checkIntegrity offHelpers.objectPath() + '/../tmp/' + file
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/../tmp/' + file)
+ readStream.pipe(process.stdout)
+ else
+ if offHelpers.checkIntegrity offHelpers.objectPath() + '/' + file
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file)
+ readStream.pipe(process.stdout)
+ return
+
# scp mode
else if mode == 'scp'
transport['send'] = (file) ->
@@ -791,6 +845,8 @@ offCommands =
setCfg('off.sshoptions', offDEFAULTS.sshOptions)
if offHelpers.offScpOptions() == '' or setCfg != gitConfig.set
setCfg('off.scpoptions', offDEFAULTS.scpOptions)
+ if offHelpers.offRsyncOptions() == '' or setCfg != gitConfig.set
+ setCfg('off.rsyncoptions', offDEFAULTS.rsyncOptions)
if offHelpers.offStore() == '' or setCfg != gitConfig.set
setCfg('off.store', offDEFAULTS.store)
if offHelpers.offHttp() == '' or setCfg != gitConfig.set
@@ -815,7 +871,7 @@ offCommands =
if runtimeConfig.offMode == 'copy'
mkdirParents runtimeConfig.offStore
- if runtimeConfig.offMode == 'scp'
+ if runtimeConfig.offMode == 'scp' or runtimeConfig.offMode == 'rsync'
offHelpers.mkdirStore ''
return
@@ -900,6 +956,15 @@ offCommands =
console.log 'off.scpoptions '.blue.bold + offHelpers.offScpOptions()
return
+ 'rsyncoptions': (setCfg) ->
+ len = process.argv.length
+ rsyncoptions = process.argv[len-1]
+ if rsyncoptions != 'rsyncoptions' and rsyncoptions != 'thisrepo'
+ setCfg('off.rsyncoptions', rsyncoptions)
+ else
+ console.log 'off.rsyncoptions '.blue.bold + offHelpers.offRsyncOptions()
+ return
+
'scpUser': (setCfg) ->
len = process.argv.length
scpUser = process.argv[len-1]
@@ -1199,6 +1264,12 @@ offCommands =
offHelpers.copyTo()
return
+ 'pushTo': ->
+ if offHelpers.offMode() != undefined
+ offHelpers.setTransport offHelpers.offMode()
+ offHelpers.copyTo()
+ return
+
'clearAll': ->
# delete store, cache in current git and log
offCommands.clearStore()
@@ -1215,7 +1286,7 @@ offCommands =
# delete store
if offHelpers.offMode() == 'copy'
rmAll offHelpers.offStore()
- if offHelpers.offMode() == 'scp'
+ if offHelpers.offMode() == 'scp' or offHelpers.offMode() == 'rsync'
offHelpers.rmAllStore ''
return
@@ -1236,6 +1307,7 @@ offCommands =
console.log 'off.pem '.blue.bold + offHelpers.offPem()
console.log 'off.sshoptions '.blue.bold + offHelpers.offSshOptions()
console.log 'off.scpoptions '.blue.bold + offHelpers.offScpOptions()
+ console.log 'off.rsyncoptions '.blue.bold + offHelpers.offRsyncOptions()
console.log 'off.store '.blue.bold + offHelpers.offStore()
console.log 'off.http '.blue.bold + offHelpers.offHttp()
console.log 'off.curloptions '.blue.bold + offHelpers.offCurlOptions()
@@ -1316,7 +1388,7 @@ COMMAND_MAP =
f: ->
thisrepo offCommands['mode']
return
- h: 'git off mode [thisrepo] [copy|scp|http|s3]\n set/show git off mode'
+ h: 'git off mode [thisrepo] [copy|rsync|scp|http|s3]\n set/show git off mode'
'store':
f: ->
@@ -1352,7 +1424,7 @@ COMMAND_MAP =
f: ->
thisrepo offCommands['pem']
return
- 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)"
+ h: "git off pem [thisrepo] [pathToPrivateKey]\n set/show git off pem.\n off.pem is the private key for ssh, rsync and scp\n set 'offNoValue' to set an empty value (useful when there are multiple configs)"
'sshoptions':
f: ->
@@ -1366,6 +1438,12 @@ COMMAND_MAP =
return
h: 'git off scpoptions [thisrepo] [options]\n set/show git off scpoptions'
+ 'rsyncoptions':
+ f: ->
+ thisrepo offCommands['rsyncoptions']
+ return
+ h: 'git off rsyncoptions [thisrepo] [options]\n set/show git off rsyncoptions'
+
'scpuser':
f: ->
thisrepo offCommands['scpUser']
@@ -1436,7 +1514,13 @@ COMMAND_MAP =
f: ->
offCommands.copyTo()
return
- h: 'git off copyTo [copy|scp|s3]\n copy cache to store for specified mode'
+ h: 'git off copyTo [copy|rsync|scp|s3]\n copy cache to store for specified mode'
+
+ 'push':
+ f: ->
+ offCommands.pushTo()
+ return
+ h: 'git off push\n copy cache to store for selected mode'
'clearAll':
f: ->