diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2015-09-23 05:14:46 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-09-23 05:14:46 -0700 |
commit | f622516dd07a0afbad698f68305561789d4a40c4 (patch) | |
tree | 7d036fd0b64dead9c39f7407893250647281e215 | |
parent | aeedc2a619564a957c8fca000a7fa0148e3d78b1 (diff) | |
download | subsurface-f622516dd07a0afbad698f68305561789d4a40c4.tar.gz |
Cloud storage: more user friendly handling of local cache corruption
When dealing with cloud storage most of the time the user will not be
familiar with git. So if the local cache is corrupted don't leave them to
clean up the mess. Instead just move things out of the way (just in case
they know how to extract data from the damaged local repository) and ask
them to restart the operation which should give them a fresh copy of their
data from the remote server (minus any local changes that hadn't been
synced to the server before things went bad).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | git-access.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/git-access.c b/git-access.c index cd371cf9b..aa7d38776 100644 --- a/git-access.c +++ b/git-access.c @@ -115,6 +115,12 @@ char *get_local_dir(const char *remote, const char *branch) hash[4], hash[5], hash[6], hash[7]); } +static char *move_local_cache(const char *remote, const char *branch) +{ + char *old_path = get_local_dir(remote, branch); + return move_away(old_path); +} + static int check_clean(const char *path, unsigned int status, void *payload) { status &= ~GIT_STATUS_CURRENT | GIT_STATUS_IGNORED; @@ -371,7 +377,19 @@ write_error: return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: writing the data failed (%s)"), giterr_last()->message); } -static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt) +// if accessing the local cache of Subsurface cloud storage fails, we simplify things +// for the user and simply move the cache away (in case they want to try and extract data) +// and ask them to retry the operation (which will then refresh the data from the cloud server) +static int cleanup_local_cache(const char *remote_url, const char *branch) +{ + char *backup_path = move_local_cache(remote_url, branch); + report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data")); + report_error(translate("gettextFromC", "Moved cache data to %s. Please try the operation again."), backup_path); + free(backup_path); + return -1; +} +static int try_to_update(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, + const char *remote_url, const char *branch, enum remote_transport rt) { git_oid base; const git_oid *local_id, *remote_id; @@ -431,11 +449,13 @@ static int try_to_update(git_repository *repo, git_remote *origin, git_reference return try_to_git_merge(repo, local, remote, &base, local_id, remote_id); cloud_data_error: - return report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data")); - + // since we are working with Subsurface cloud storage we want to make the user interaction + // as painless as possible. So if something went wrong with the local cache, tell the user + // about it an move it away + return cleanup_local_cache(remote_url, branch); } -static int check_remote_status(git_repository *repo, git_remote *origin, const char *branch, enum remote_transport rt) +static int check_remote_status(git_repository *repo, git_remote *origin, const char *remote, const char *branch, enum remote_transport rt) { int error = 0; @@ -446,7 +466,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c if (git_branch_lookup(&local_ref, repo, branch, GIT_BRANCH_LOCAL)) { if (is_subsurface_cloud) - report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data")); + return cleanup_local_cache(remote, branch); else return report_error("Git cache branch %s no longer exists", branch); } @@ -468,7 +488,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c error = git_remote_push(origin, &refspec, NULL); #endif } else { - error = try_to_update(repo, origin, local_ref, remote_ref, rt); + error = try_to_update(repo, origin, local_ref, remote_ref, remote, branch, rt); git_reference_free(remote_ref); } git_reference_free(local_ref); @@ -529,7 +549,7 @@ int sync_with_remote(git_repository *repo, const char *remote, const char *branc report_error("Unable to fetch remote '%s'", remote); error = 0; } else { - error = check_remote_status(repo, origin, branch, rt); + error = check_remote_status(repo, origin, remote, branch, rt); } git_remote_free(origin); return error; @@ -546,7 +566,7 @@ static git_repository *update_local_repo(const char *localdir, const char *remot error = git_repository_open(&repo, localdir); if (error) { if (is_subsurface_cloud) - report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data")); + (void)cleanup_local_cache(remote, branch); else report_error("Unable to open git cache repository at %s: %s", localdir, giterr_last()->message); return NULL; @@ -679,7 +699,7 @@ static struct git_repository *get_remote_repo(const char *localdir, const char * if (!stat(localdir, &st)) { if (!S_ISDIR(st.st_mode)) { if (is_subsurface_cloud) - report_error(translate("gettextFromC", "Problems with local cache of Subsurface cloud data")); + (void)cleanup_local_cache(remote, branch); else report_error("local git cache at '%s' is corrupt"); return NULL; |