Implemented local branch merging during update.

I'm sure I did this before, I must have discarded it by mistake... Also
removed update retry, as there's some permissions issue that occurs with
the repo packfiles whenever it is done.
This commit is contained in:
WrinklyNinja
2014-07-05 15:53:47 +01:00
parent 037b9386ef
commit c910d913d4
2 changed files with 44 additions and 25 deletions
+41 -7
View File
@@ -43,7 +43,7 @@ namespace loot {
struct git_handler {
public:
git_handler() : repo(nullptr), remote(nullptr), cfg(nullptr), obj(nullptr), commit(nullptr), ref(nullptr), sig(nullptr), blob(nullptr) {}
git_handler() : repo(nullptr), remote(nullptr), cfg(nullptr), obj(nullptr), commit(nullptr), ref(nullptr), ref2(nullptr), sig(nullptr), blob(nullptr), merge_head(nullptr) {}
~git_handler() {
git_commit_free(commit);
@@ -52,8 +52,10 @@ namespace loot {
git_remote_free(remote);
git_repository_free(repo);
git_reference_free(ref);
git_reference_free(ref2);
git_signature_free(sig);
git_blob_free(blob);
git_merge_head_free(merge_head);
}
void call(int error_code) {
@@ -81,8 +83,11 @@ namespace loot {
git_object * obj;
git_commit * commit;
git_reference * ref;
git_reference * ref2;
git_signature * sig;
git_blob * blob;
git_merge_head * merge_head;
std::string ui_message;
};
@@ -246,7 +251,7 @@ namespace loot {
}
else {
// Repository exists: check settings are correct, then pull updates.
git.ui_message = "An error occurred while trying to access the local masterlist repository.";
git.ui_message = "An error occurred while trying to access the local masterlist repository. If this error happens again, try deleting the \".git\" folder in \"%LOCALAPPDATA%\\LOOT\\" + game.FolderName() + "\".";
// Open the repository.
BOOST_LOG_TRIVIAL(info) << "Existing repository found, attempting to open it.";
@@ -279,6 +284,7 @@ namespace loot {
BOOST_LOG_TRIVIAL(info) << "Received " << stats->indexed_objects << " of " << stats->total_objects << " objects in " << stats->received_bytes << " bytes.";
// Check that a branch with the correct name exists.
git.ui_message = "An error occurred while trying to access the local masterlist repository. If this error happens again, try deleting the \".git\" folder in \"%LOCALAPPDATA%\\LOOT\\" + game.FolderName() + "\".";
int ret = git_branch_lookup(&git.ref, git.repo, repo_branch.c_str(), GIT_BRANCH_LOCAL);
if (ret == GIT_ENOTFOUND) {
// Branch doesn't exist. Create a new branch using the remote branch's latest commit.
@@ -317,12 +323,40 @@ namespace loot {
if (ret == 0) {
/* The branch did exist, and is now pointed at by HEAD.
Need to merge the remote branch into it.
1. git_merge_head_from_fetchhead to get the remote branch object to merge with.
2. git_merge to merge the remote branch object into HEAD, which is set to be
the desired branch.Docs say a commit may be necessary after this.
Need to merge the remote branch into it. Just do a fast-forward merge because
that's all that should be necessary as the local repo shouldn't get changed by
the user.
*/
BOOST_LOG_TRIVIAL(trace) << "Checking that local and remote branches can be merged by fast-forward.";
git_merge_analysis_t analysis;
git_merge_preference_t pref;
git.call(git_reference_lookup(&git.ref2, git.repo, (string("refs/remotes/origin/") + repo_branch).c_str()));
git.call(git_merge_head_from_ref(&git.merge_head, git.repo, git.ref2));
git.call(git_merge_analysis(&analysis, &pref, git.repo, (const git_merge_head **)&git.merge_head, 1));
if (analysis == GIT_MERGE_ANALYSIS_FASTFORWARD) {
BOOST_LOG_TRIVIAL(trace) << "Local branch can be fast-forwarded to remote branch.";
// The remote branch reference points to a particular commit. We just want to
// update the local branch reference to point to the same commit.
// Get the commit object ID.
const git_oid * commit_id = git_reference_target_peel(git.ref2);
git_reference_free(git.ref2);
git.ref2 = nullptr;
git.call(git_reference_set_target(&git.ref2, git.ref, commit_id, git.sig, "Setting branch reference."));
git_reference_free(git.ref2);
git.ref2 = nullptr;
}
else if (analysis == GIT_MERGE_ANALYSIS_UP_TO_DATE) {
BOOST_LOG_TRIVIAL(trace) << "Local branch is up-to-date with remote branch.";
}
else {
throw error(error::git_error, "Local repository has been edited, an automatic fast-forward merge update is not possible.");
}
}
// Free branch pointer.
+3 -18
View File
@@ -110,24 +110,9 @@ struct masterlist_updater_parser {
if (_doUpdate) {
BOOST_LOG_TRIVIAL(debug) << "Updating masterlist";
try {
try {
pair<string, string> ret = UpdateMasterlist(_game, _errors, _plugins, _messages);
_revision = ret.first;
_date = ret.second;
}
catch (loot::error &e) {
BOOST_LOG_TRIVIAL(error) << "Masterlist update failed. Details: " << e.what();
if (e.code() == loot::error::git_error) {
BOOST_LOG_TRIVIAL(info) << "Masterlist update failure was due to Git error, deleting repository and retrying...";
//Delete .git folder and try again.
fs::remove_all(_game.MasterlistPath().parent_path() / ".git");
pair<string, string> ret = UpdateMasterlist(_game, _errors, _plugins, _messages);
_revision = ret.first;
_date = ret.second;
}
else
throw e;
}
pair<string, string> ret = UpdateMasterlist(_game, _errors, _plugins, _messages);
_revision = ret.first;
_date = ret.second;
} catch (std::exception& e) {
_plugins.clear();
_messages.clear();