From 8269ef49fde760d58e5df238346a6575fe406491 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Fri, 4 Nov 2011 17:07:29 -0700 Subject: [PATCH] Don't use git show -c on versions of git earlier than 1.7.2 --- src/cpp/core/StringUtils.cpp | 26 ++++++++++++++ src/cpp/core/include/core/StringUtils.hpp | 2 ++ .../session/modules/SessionSourceControl.cpp | 34 +++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/cpp/core/StringUtils.cpp b/src/cpp/core/StringUtils.cpp index 9f8362eaf1a..8004d4e8d65 100644 --- a/src/cpp/core/StringUtils.cpp +++ b/src/cpp/core/StringUtils.cpp @@ -17,10 +17,13 @@ #include #include +#include #include +#include #include #include +#include #include #ifdef _WIN32 @@ -294,6 +297,29 @@ bool isalnum(wchar_t c) return lookup.at(c); } +bool parseVersion(const std::string& str, uint64_t* pVersion) +{ + uint64_t version = 0; + + std::vector chunks; + boost::algorithm::split(chunks, str, boost::algorithm::is_any_of(".")); + + if (chunks.empty()) + return false; + + for (size_t i = 0; i < chunks.size() && i < 4; i++) + { + uint16_t value = core::safe_convert::stringTo( + chunks[i], std::numeric_limits::max()); + if (value == std::numeric_limits::max()) + return false; + version += static_cast(value) << ((3-i) * 16); + } + if (pVersion) + *pVersion = version; + return true; +} + } // namespace string_utils } // namespace core diff --git a/src/cpp/core/include/core/StringUtils.hpp b/src/cpp/core/include/core/StringUtils.hpp index f3980fa7565..01593eefbc7 100644 --- a/src/cpp/core/include/core/StringUtils.hpp +++ b/src/cpp/core/include/core/StringUtils.hpp @@ -44,6 +44,8 @@ void convertLineEndings(std::string* str, LineEnding type); std::string filterControlChars(const std::string& str); +bool parseVersion(const std::string& str, uint64_t* pVersion); + template T hashStable(const std::string& str) { diff --git a/src/cpp/session/modules/SessionSourceControl.cpp b/src/cpp/session/modules/SessionSourceControl.cpp index 78b5d19c0d1..0247df7b9a8 100644 --- a/src/cpp/session/modules/SessionSourceControl.cpp +++ b/src/cpp/session/modules/SessionSourceControl.cpp @@ -77,6 +77,10 @@ const size_t WARN_SIZE = 200 * 1024; // git bin dir which we detect at startup. note that if the git bin // is already in the path then this will be empty std::string s_gitBinDir; +uint64_t s_gitVersion; +const uint64_t GIT_1_7_2 = ((uint64_t)1 << 48) | + ((uint64_t)7 << 32) | + ((uint64_t)2 << 16); core::system::ProcessOptions procOptions() { @@ -1060,8 +1064,12 @@ class GitVCSImpl : public VCSImpl virtual core::Error show(const std::string& rev, std::string* pOutput) { - return runCommand(git() << "show" << "--pretty=oneline" << "-c" << "-M" << rev, - pOutput, NULL); + ShellCommand cmd = git() << "show" << "--pretty=oneline" << "-M"; + if (s_gitVersion >= GIT_1_7_2) + cmd << "-c"; + cmd << rev; + + return runCommand(cmd, pOutput, NULL); } virtual core::Error hasRemote(bool *pHasRemote) @@ -2498,6 +2506,28 @@ bool tryGit(const FilePath& workingDir) if (error) LOG_ERROR(error); + // Save version + s_gitVersion = GIT_1_7_2; + core::system::ProcessResult result; + error = core::system::runCommand(git() << "--version", + procOptions(), + &result); + if (error) + LOG_ERROR(error); + else + { + if (result.exitStatus == 0) + { + boost::smatch matches; + if (boost::regex_search(result.stdOut, + matches, + boost::regex("\\d+(\\.\\d+)+"))) + { + string_utils::parseVersion(matches[0], &s_gitVersion); + } + } + } + return true; }