diff --git a/.gitignore b/.gitignore index 8ac1898..0e1d97b 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,8 @@ ipch/ *.opensdf *.sdf *.cachefile +*.VC.opendb +*.VC.db # Visual Studio profiler *.psess diff --git a/README.md b/README.md index 514f540..951260a 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Retrieves current status information for the requested "Path". "State" : "", "Branch" : "master", "Upstream": "origin/master", + "UpstreamGone": false, "AheadBy": 0, "BehindBy": 0, "IndexAdded": [], diff --git a/ext/ReadDirectoryChanges/ide/ReadDirectoryChangesLib.vcxproj b/ext/ReadDirectoryChanges/ide/ReadDirectoryChangesLib.vcxproj index a7988c1..67fdec6 100644 --- a/ext/ReadDirectoryChanges/ide/ReadDirectoryChangesLib.vcxproj +++ b/ext/ReadDirectoryChanges/ide/ReadDirectoryChangesLib.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -22,7 +22,7 @@ Unicode Dynamic Static - v120 + v140 StaticLibrary @@ -31,7 +31,7 @@ Unicode Dynamic Static - v120 + v140 diff --git a/src/GitStatusCache/ide/GitStatusCache.vcxproj b/src/GitStatusCache/ide/GitStatusCache.vcxproj index 64cdf9e..de65237 100644 --- a/src/GitStatusCache/ide/GitStatusCache.vcxproj +++ b/src/GitStatusCache/ide/GitStatusCache.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -19,13 +19,13 @@ Application true - v120 + v140 Unicode Application false - v120 + v140 true Unicode diff --git a/src/GitStatusCache/src/Git.cpp b/src/GitStatusCache/src/Git.cpp index d962fe3..d6323c7 100644 --- a/src/GitStatusCache/src/Git.cpp +++ b/src/GitStatusCache/src/Git.cpp @@ -219,6 +219,7 @@ bool Git::GetRefStatus(Git::Status& status, UniqueGitRepository& repository) { status.Branch = std::string(); status.Upstream = std::string(); + status.UpstreamGone = false; status.AheadBy = 0; status.BehindBy = 0; @@ -267,9 +268,40 @@ bool Git::GetRefStatus(Git::Status& status, UniqueGitRepository& repository) result = git_branch_upstream(&upstream.get(), head.get()); if (result == GIT_ENOTFOUND) { - Log("Git.GetRefStatus.NoUpstream", Severity::Spam) - << R"(Branch does not have a remote tracking reference. { "repositoryPath": ")" << status.RepositoryPath - << R"(", "localBranch": ")" << status.Branch << R"(" })"; + auto upstreamBranchName = git_buf{ 0 }; + auto upstreamBranchResult = git_branch_upstream_name( + &upstreamBranchName, + git_reference_owner(head.get()), + git_reference_name(head.get())); + + auto canBuildUpstream = false; + if (upstreamBranchResult == GIT_OK) + { + Log("Git.GetRefStatus.UpstreamGone", Severity::Spam) + << R"(Branch has a configured upstream that is gone. { "repositoryPath": ")" << status.RepositoryPath + << R"(", "localBranch": ")" << status.Branch << R"(" })"; + status.UpstreamGone = true; + canBuildUpstream = upstreamBranchName.ptr != nullptr && upstreamBranchName.size != 0; + } + + if (canBuildUpstream) + { + const auto patternToRemove = std::string("refs/remotes/"); + auto upstreamName = std::string(upstreamBranchName.ptr); + auto patternPosition = upstreamName.find(patternToRemove); + if (patternPosition == 0 && upstreamName.size() > patternToRemove.size()) + { + upstreamName.erase(patternPosition, patternToRemove.size()); + } + status.Upstream = upstreamName; + } + else + { + Log("Git.GetRefStatus.NoUpstream", Severity::Spam) + << R"(Branch does not have a remote tracking reference. { "repositoryPath": ")" << status.RepositoryPath + << R"(", "localBranch": ")" << status.Branch << R"(" })"; + } + return true; } else if (result != GIT_OK) diff --git a/src/GitStatusCache/src/Git.h b/src/GitStatusCache/src/Git.h index 3608212..2341eeb 100644 --- a/src/GitStatusCache/src/Git.h +++ b/src/GitStatusCache/src/Git.h @@ -22,6 +22,7 @@ class Git std::string Branch; std::string Upstream; + bool UpstreamGone = false; int AheadBy = 0; int BehindBy = 0; diff --git a/src/GitStatusCache/src/StatusController.cpp b/src/GitStatusCache/src/StatusController.cpp index 8ad38a2..dd2bfdf 100644 --- a/src/GitStatusCache/src/StatusController.cpp +++ b/src/GitStatusCache/src/StatusController.cpp @@ -31,6 +31,12 @@ StatusController::~StatusController() writer.String(value.c_str()); } +/*static*/ void StatusController::AddBoolToJson(rapidjson::Writer& writer, std::string&& name, bool value) +{ + writer.String(name.c_str()); + writer.Bool(value); +} + /*static*/ void StatusController::AddUintToJson(rapidjson::Writer& writer, std::string&& name, uint32_t value) { writer.String(name.c_str()); @@ -122,6 +128,7 @@ std::string StatusController::GetStatus(const rapidjson::Document& document, con AddStringToJson(writer, "State", statusToReport.State.c_str()); AddStringToJson(writer, "Branch", statusToReport.Branch.c_str()); AddStringToJson(writer, "Upstream", statusToReport.Upstream.c_str()); + AddBoolToJson(writer, "UpstreamGone", statusToReport.UpstreamGone); AddUintToJson(writer, "AheadBy", statusToReport.AheadBy); AddUintToJson(writer, "BehindBy", statusToReport.BehindBy); diff --git a/src/GitStatusCache/src/StatusController.h b/src/GitStatusCache/src/StatusController.h index 7bf2efe..febcde5 100644 --- a/src/GitStatusCache/src/StatusController.h +++ b/src/GitStatusCache/src/StatusController.h @@ -33,6 +33,11 @@ class StatusController : boost::noncopyable */ static void AddStringToJson(rapidjson::Writer& writer, std::string&& name, std::string&& value); + /** + * Adds bool to JSON response. + */ + static void AddBoolToJson(rapidjson::Writer& writer, std::string&& name, bool value); + /** * Adds uint32_t to JSON response. */