/* * This turns a remote repository into a local one if possible. * * The recognized formats are * git://host/repo[branch] * ssh://host/repo[branch] * http://host/repo[branch] * https://host/repo[branch] * file://repo[branch] */ static struct git_repository *is_remote_git_repository(char *remote, const char *branch) { char c, *localdir; const char *p = remote; while ((c = *p++) >= 'a' && c <= 'z') /* nothing */; if (c != ':') return NULL; if (*p++ != '/' || *p++ != '/') return NULL; /* Special-case "file://", since it's already local */ if (!strncmp(remote, "file://", 7)) remote += 7; /* * Ok, we found "[a-z]*://", we've simplified the * local repo case (because libgit2 is insanely slow * for that), and we think we have a real "remote * git" format. * * We now create the SHA1 hash of the whole thing, * including the branch name. That will be our unique * unique local repository name. * * NOTE! We will create a local repository per branch, * because * * (a) libgit2 remote tracking branch support seems to * be a bit lacking * (b) we'll actually check the branch out so that we * can do merges etc too. * * so even if you have a single remote git repo with * multiple branches for different people, the local * caches will sadly force that to split into multiple * individual repositories. */ /* * next we need to make sure that any encoded username * has been extracted from an https:// based URL */ if (!strncmp(remote, "https://", 8)) { char *at = strchr(remote, '@'); if (at) { /* was this the @ that denotes an account? that means it was before the * first '/' after the https:// - so let's find a '/' after that and compare */ char *slash = strchr(remote + 8, '/'); if (slash && slash > at) { /* grab the part between "https://" and "@" as encoded email address * (that's our username) and move the rest of the URL forward, remembering * to copy the closing NUL as well */ prefs.cloud_storage_email_encoded = strndup(remote + 8, at - remote - 8); memmove(remote + 8, at + 1, strlen(at + 1) + 1); } } } localdir = get_local_dir(remote, branch); if (!localdir) return NULL; return get_remote_repo(localdir, remote, branch); }
/* * This turns a remote repository into a local one if possible. * * The recognized formats are * git://host/repo[branch] * ssh://host/repo[branch] * http://host/repo[branch] * https://host/repo[branch] * file://repo[branch] */ static struct git_repository *is_remote_git_repository(char *remote, const char *branch) { char c, *localdir; char *p = remote; while ((c = *p++) >= 'a' && c <= 'z') /* nothing */; if (c != ':') return NULL; if (*p++ != '/' || *p++ != '/') return NULL; /* * Ok, we found "[a-z]*://" and we think we have a real * "remote git" format. The "file://" case was handled * in the calling function. * * We now create the SHA1 hash of the whole thing, * including the branch name. That will be our unique * unique local repository name. * * NOTE! We will create a local repository per branch, * because * * (a) libgit2 remote tracking branch support seems to * be a bit lacking * (b) we'll actually check the branch out so that we * can do merges etc too. * * so even if you have a single remote git repo with * multiple branches for different people, the local * caches will sadly force that to split into multiple * individual repositories. */ /* * next we need to make sure that any encoded username * has been extracted from the URL */ char *at = strchr(remote, '@'); if (at) { /* was this the @ that denotes an account? that means it was before the * first '/' after the protocol:// - so let's find a '/' after that and compare */ char *slash = strchr(p, '/'); if (slash && slash > at) { /* grab the part between "protocol://" and "@" as encoded email address * (that's our username) and move the rest of the URL forward, remembering * to copy the closing NUL as well */ prefs.cloud_storage_email_encoded = strndup(p, at - p); memmove(p, at + 1, strlen(at + 1) + 1); } } localdir = get_local_dir(remote, branch); if (!localdir) return NULL; /* remember if the current git storage we are working on is our cloud storage * this is used to create more user friendly error message and warnings */ is_subsurface_cloud = strstr(remote, prefs.cloud_git_url) != NULL; return get_remote_repo(localdir, remote, branch); }