diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85181bc8..ee55ff2d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -222,6 +222,7 @@ set (LOOT_HEADERS "${CMAKE_SOURCE_DIR}/src/backend/app/loot_paths.h"
"${CMAKE_SOURCE_DIR}/include/loot/error.h"
"${CMAKE_SOURCE_DIR}/include/loot/error_categories.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/cyclic_interaction_error.h"
+ "${CMAKE_SOURCE_DIR}/include/loot/exception/git_state_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/game_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/language_code.h"
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
@@ -282,6 +283,7 @@ set (LOOT_API_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
"${CMAKE_SOURCE_DIR}/include/loot/error.h"
"${CMAKE_SOURCE_DIR}/include/loot/error_categories.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/cyclic_interaction_error.h"
+ "${CMAKE_SOURCE_DIR}/include/loot/exception/git_state_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/game_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/language_code.h"
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
diff --git a/docs/api/reference.rst b/docs/api/reference.rst
index afedbb8b..e7a7ecfd 100644
--- a/docs/api/reference.rst
+++ b/docs/api/reference.rst
@@ -46,6 +46,9 @@ Classes
.. doxygenclass:: loot::CyclicInteractionError
:members:
+.. doxygenclass:: loot::GitStateError
+ :members:
+
.. doxygenclass:: loot::Error
:members:
diff --git a/include/loot/api.h b/include/loot/api.h
index 5a81c2ae..23594fa7 100644
--- a/include/loot/api.h
+++ b/include/loot/api.h
@@ -33,6 +33,7 @@
#include "loot/error.h"
#include "loot/error_categories.h"
#include "loot/exception/cyclic_interaction_error.h"
+#include "loot/exception/git_state_error.h"
#include "loot/game_type.h"
#include "loot/loot_version.h"
diff --git a/include/loot/error.h b/include/loot/error.h
index c6135131..497dd270 100644
--- a/include/loot/error.h
+++ b/include/loot/error.h
@@ -59,11 +59,6 @@ public:
path_not_found = 9,
/** None of LOOT's supported games could be detected. */
no_game_detected = 10,
- /**
- * An error was encountered while trying to create or interact with a Git
- * repository.
- */
- git_error = 12,
};
/**
diff --git a/include/loot/exception/git_state_error.h b/include/loot/exception/git_state_error.h
new file mode 100644
index 00000000..b269e67f
--- /dev/null
+++ b/include/loot/exception/git_state_error.h
@@ -0,0 +1,41 @@
+/* LOOT
+
+ A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
+ Fallout: New Vegas.
+
+ Copyright (C) 2012-2016 WrinklyNinja
+
+ This file is part of LOOT.
+
+ LOOT is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ LOOT is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LOOT. If not, see
+ .
+ */
+
+#ifndef LOOT_EXCEPTION_GIT_STATE_ERROR
+#define LOOT_EXCEPTION_GIT_STATE_ERROR
+
+#include
+
+namespace loot {
+/**
+ * @brief An exception class thrown if an error occurs when performing
+ * an operation on a Git repository due to invalid state.
+ */
+class GitStateError : public std::logic_error {
+public:
+ using std::logic_error::logic_error;
+};
+}
+
+#endif
diff --git a/src/backend/helpers/git_helper.cpp b/src/backend/helpers/git_helper.cpp
index 71f55bc5..e68f5e73 100644
--- a/src/backend/helpers/git_helper.cpp
+++ b/src/backend/helpers/git_helper.cpp
@@ -30,6 +30,7 @@
#include "loot/error.h"
#include "loot/error_categories.h"
+#include "loot/exception/git_state_error.h"
using boost::locale::translate;
using std::string;
@@ -141,7 +142,7 @@ int GitHelper::DiffFileCallback(const git_diff_delta *delta, float progress, voi
// Clones a repository and opens it.
void GitHelper::Clone(const boost::filesystem::path& path, const std::string& url) {
if (data_.repo != nullptr)
- throw Error(Error::Code::git_error, "Cannot clone repository that has already been opened.");
+ throw GitStateError("Cannot clone repository that has already been opened.");
SetErrorMessage(translate("An error occurred while trying to clone the remote masterlist repository."));
// Clone the remote repository.
@@ -189,7 +190,7 @@ void GitHelper::Clone(const boost::filesystem::path& path, const std::string& ur
void GitHelper::Fetch(const std::string& remote) {
if (data_.repo == nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch updates for repository that has not been opened.");
+ throw GitStateError("Cannot fetch updates for repository that has not been opened.");
BOOST_LOG_TRIVIAL(trace) << "Fetching updates from remote.";
SetErrorMessage(translate("An error occurred while trying to update the masterlist. This could be due to a server-side error. Try again in a few minutes."));
@@ -211,13 +212,13 @@ void GitHelper::Fetch(const std::string& remote) {
void GitHelper::CheckoutNewBranch(const std::string& remote, const std::string& branch) {
if (data_.repo == nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch updates for repository that has not been opened.");
+ throw GitStateError("Cannot fetch updates for repository that has not been opened.");
else if (data_.commit != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, commit memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, commit memory already allocated.");
else if (data_.object != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, object memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, object memory already allocated.");
else if (data_.reference != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, reference memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, reference memory already allocated.");
BOOST_LOG_TRIVIAL(trace) << "Looking up commit referred to by the remote branch \"" << branch << "\".";
Call(git_revparse_single(&data_.object, data_.repo, (remote + "/" + branch).c_str()));
@@ -252,9 +253,9 @@ void GitHelper::CheckoutNewBranch(const std::string& remote, const std::string&
void GitHelper::CheckoutRevision(const std::string& revision) {
if (data_.repo == nullptr)
- throw Error(Error::Code::git_error, "Cannot checkout revision for repository that has not been opened.");
+ throw GitStateError("Cannot checkout revision for repository that has not been opened.");
else if (data_.object != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, object memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, object memory already allocated.");
// Get an object ID for 'HEAD^'.
Call(git_revparse_single(&data_.object, data_.repo, revision.c_str()));
@@ -273,13 +274,13 @@ void GitHelper::CheckoutRevision(const std::string& revision) {
std::string GitHelper::GetHeadShortId() {
if (data_.repo == nullptr)
- throw Error(Error::Code::git_error, "Cannot checkout revision for repository that has not been opened.");
+ throw GitStateError("Cannot checkout revision for repository that has not been opened.");
else if (data_.object != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, object memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, object memory already allocated.");
else if (data_.reference != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, reference memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, reference memory already allocated.");
else if (data_.buffer.ptr != nullptr)
- throw Error(Error::Code::git_error, "Cannot fetch repository updates, buffer memory already allocated.");
+ throw GitStateError("Cannot fetch repository updates, buffer memory already allocated.");
BOOST_LOG_TRIVIAL(trace) << "Getting the Git object for HEAD.";
Call(git_repository_head(&data_.reference, data_.repo));