diff options
-rw-r--r-- | qt-ui/mainwindow.cpp | 2 | ||||
-rw-r--r-- | save-git.c | 48 |
2 files changed, 50 insertions, 0 deletions
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index b66ef997a..8fd51a5b9 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -909,6 +909,7 @@ int MainWindow::file_save_as(void) return -1; } + showError(get_error_string()); set_filename(filename.toUtf8().data(), true); setTitle(MWTF_FILENAME); mark_divelist_changed(false); @@ -938,6 +939,7 @@ int MainWindow::file_save(void) showError(get_error_string()); return -1; } + showError(get_error_string()); mark_divelist_changed(false); addRecentFile(QStringList() << QString(existing_filename)); return 0; diff --git a/save-git.c b/save-git.c index 74eab55bb..1488b43bb 100644 --- a/save-git.c +++ b/save-git.c @@ -776,6 +776,38 @@ static git_object *try_to_find_parent(const char *hex_id, git_repository *repo) return (git_object *)commit; } +static int notify_cb(git_checkout_notify_t why, + const char *path, + const git_diff_file *baseline, + const git_diff_file *target, + const git_diff_file *workdir, + void *payload) +{ + report_error("File '%s' does not match in working tree", path); + return 0; /* Continue with checkout */ +} + +static git_tree *get_git_tree(git_repository *repo, git_object *parent) +{ + git_tree *tree; + if (!parent) + return NULL; + if (git_tree_lookup(&tree, repo, git_commit_tree_id((const git_commit *) parent))) + return NULL; + return tree; +} + +static int update_git_checkout(git_repository *repo, git_object *parent, git_tree *tree) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + + opts.checkout_strategy = GIT_CHECKOUT_SAFE; + opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT | GIT_CHECKOUT_NOTIFY_DIRTY; + opts.notify_cb = notify_cb; + opts.baseline = get_git_tree(repo, parent); + return git_checkout_tree(repo, (git_object *) tree, &opts); +} + /* * libgit2 revision 0.20 and earlier do not have the signature and * message log arguments. @@ -849,6 +881,22 @@ static int create_new_commit(git_repository *repo, const char *branch, git_oid * if (git_branch_create(&ref, repo, branch, commit, 0, author, "Create branch")) return report_error("Failed to create branch '%s'", branch); } + /* + * If it's a checked-out branch, try to also update the working + * tree and index. If that fails (dirty working tree or whatever), + * this is not technically a save error (we did save things in + * the object database), but it can cause extreme confusion, so + * warn about it. + */ + if (git_branch_is_head(ref) && !git_repository_is_bare(repo)) { + if (update_git_checkout(repo, parent, tree)) { + const git_error *err = giterr_last(); + const char *errstr = err ? err->message : strerror(errno); + report_error("Git branch '%s' is checked out, but worktree is dirty (%s)", + branch, errstr); + } + } + if (git_reference_set_target(&ref, ref, &commit_id, author, "Subsurface save event")) return report_error("Failed to update branch '%s'", branch); set_git_id(&commit_id); |