mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
Parse git status
This commit is contained in:
@@ -1290,6 +1290,10 @@
|
||||
../../src/tools/ecode/notificationcenter.cpp
|
||||
../../src/tools/ecode/notificationcenter.hpp
|
||||
../../src/tools/ecode/pathhelper.hpp
|
||||
../../src/tools/ecode/plugins/git/git.cpp
|
||||
../../src/tools/ecode/plugins/git/git.hpp
|
||||
../../src/tools/ecode/plugins/git/gitplugin.cpp
|
||||
../../src/tools/ecode/plugins/git/gitplugin.hpp
|
||||
../../src/tools/ecode/plugins/linter/linterplugin.cpp
|
||||
../../src/tools/ecode/plugins/linter/linterplugin.hpp
|
||||
../../src/tools/ecode/plugins/lsp/lspclientplugin.cpp
|
||||
@@ -1302,6 +1306,8 @@
|
||||
../../src/tools/ecode/plugins/lsp/lspdocumentclient.cpp
|
||||
../../src/tools/ecode/plugins/lsp/lspdocumentclient.hpp
|
||||
../../src/tools/ecode/plugins/lsp/lspprotocol.hpp
|
||||
../../src/tools/ecode/plugins/plugin.cpp
|
||||
../../src/tools/ecode/plugins/plugin.hpp
|
||||
../../src/tools/ecode/plugins/pluginmanager.cpp
|
||||
../../src/tools/ecode/plugins/pluginmanager.hpp
|
||||
../../src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp
|
||||
|
||||
@@ -42,6 +42,11 @@ void Git::git( const std::string& args, const std::string& projectDir, std::stri
|
||||
p.readAllStdOut( buf );
|
||||
}
|
||||
|
||||
void Git::gitSubmodules( const std::string& args, const std::string& projectDir,
|
||||
std::string& buf ) {
|
||||
git( String::format( "submodule foreach \"git %s\"", args.c_str() ), projectDir, buf );
|
||||
}
|
||||
|
||||
std::string Git::branch( const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
git( "rev-parse --abbrev-ref HEAD", projectDir, buf );
|
||||
@@ -83,11 +88,18 @@ const std::string& Git::getGitFolder() const {
|
||||
return mGitFolder;
|
||||
}
|
||||
|
||||
bool Git::hasSubmodules( const std::string& projectDir ) {
|
||||
return ( !projectDir.empty() && FileSystem::fileExists( projectDir + ".gitmodules" ) ) ||
|
||||
( !mProjectPath.empty() && FileSystem::fileExists( mProjectPath + ".gitmodules" ) );
|
||||
}
|
||||
|
||||
Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir ) {
|
||||
static constexpr auto DIFF_CMD = "diff --numstat";
|
||||
static constexpr auto STATUS_CMD = "-c color.status=never status -b -u -s";
|
||||
Status s;
|
||||
std::string buf;
|
||||
git( "diff --numstat", projectDir, buf );
|
||||
auto parseStatus = [&s, &buf]() {
|
||||
git( DIFF_CMD, projectDir, buf );
|
||||
auto parseNumStat = [&s, &buf]() {
|
||||
auto lastNL = 0;
|
||||
auto nextNL = buf.find_first_of( '\n' );
|
||||
while ( nextNL != std::string_view::npos ) {
|
||||
@@ -111,16 +123,62 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
|
||||
}
|
||||
};
|
||||
|
||||
parseNumStat();
|
||||
|
||||
bool submodules = hasSubmodules( projectDir );
|
||||
|
||||
if ( recurseSubmodules && submodules ) {
|
||||
gitSubmodules( DIFF_CMD, projectDir, buf );
|
||||
parseNumStat();
|
||||
}
|
||||
|
||||
bool modifiedSubmodule = false;
|
||||
auto parseStatus = [&s, &buf, &modifiedSubmodule]() {
|
||||
auto lastNL = 0;
|
||||
auto nextNL = buf.find_first_of( '\n' );
|
||||
while ( nextNL != std::string_view::npos ) {
|
||||
LuaPattern pattern( "\n([%s?][MARTUD?])%s(.*)" );
|
||||
LuaPattern::Range matches[3];
|
||||
if ( pattern.matches( buf.c_str(), lastNL, matches, nextNL ) ) {
|
||||
auto status = buf.substr( matches[1].start, matches[1].end - matches[1].start );
|
||||
String::trimInPlace( status );
|
||||
auto file = buf.substr( matches[2].start, matches[2].end - matches[2].start );
|
||||
FileStatus rstatus = FileStatus::Unidentified;
|
||||
if ( "??" == status )
|
||||
rstatus = FileStatus::Untracked;
|
||||
else if ( "M" == status )
|
||||
rstatus = FileStatus::Modified;
|
||||
else if ( "A" == status )
|
||||
rstatus = FileStatus::Added;
|
||||
else if ( "D" == status )
|
||||
rstatus = FileStatus::Deleted;
|
||||
else if ( "R" == status )
|
||||
rstatus = FileStatus::Renamed;
|
||||
else if ( "T" == status )
|
||||
rstatus = FileStatus::TypeChanged;
|
||||
else if ( "U" == status )
|
||||
rstatus = FileStatus::UpdatedUnmerged;
|
||||
else if ( "m" == status )
|
||||
rstatus = FileStatus::ModifiedSubmodule;
|
||||
|
||||
if ( rstatus != FileStatus::Unidentified ) {
|
||||
if ( rstatus != FileStatus::ModifiedSubmodule )
|
||||
modifiedSubmodule = true;
|
||||
else
|
||||
s.files.insert( { std::move( file ), rstatus } );
|
||||
}
|
||||
}
|
||||
lastNL = nextNL;
|
||||
nextNL = buf.find_first_of( '\n', nextNL + 1 );
|
||||
}
|
||||
};
|
||||
|
||||
git( STATUS_CMD, projectDir, buf );
|
||||
parseStatus();
|
||||
|
||||
if ( recurseSubmodules ) {
|
||||
bool hasSubmodules =
|
||||
( !projectDir.empty() && FileSystem::fileExists( projectDir + ".gitmodules" ) ) ||
|
||||
( !mProjectPath.empty() && FileSystem::fileExists( mProjectPath + ".gitmodules" ) );
|
||||
if ( hasSubmodules ) {
|
||||
git( "submodule foreach \"git diff --numstat\"", projectDir, buf );
|
||||
parseStatus();
|
||||
}
|
||||
if ( modifiedSubmodule && submodules ) {
|
||||
gitSubmodules( STATUS_CMD, projectDir, buf );
|
||||
parseStatus();
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -32,14 +33,27 @@ class Git {
|
||||
}
|
||||
};
|
||||
|
||||
enum FileStatus {
|
||||
Unidentified,
|
||||
Modified = 'M',
|
||||
Added = 'A',
|
||||
Renamed = 'R',
|
||||
TypeChanged = 'T',
|
||||
UpdatedUnmerged = 'U',
|
||||
Deleted = 'D',
|
||||
Untracked = '?',
|
||||
ModifiedSubmodule = 'm',
|
||||
};
|
||||
|
||||
struct Status {
|
||||
std::vector<DiffFile> modified;
|
||||
int totalInserts{ 0 };
|
||||
int totalDeletions{ 0 };
|
||||
std::map<std::string, FileStatus> files;
|
||||
|
||||
bool operator==( const Status& other ) const {
|
||||
return totalInserts == other.totalInserts && totalDeletions == other.totalDeletions &&
|
||||
modified == other.modified;
|
||||
modified == other.modified && files == other.files;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -47,6 +61,8 @@ class Git {
|
||||
|
||||
void git( const std::string& args, const std::string& projectDir, std::string& buf ) const;
|
||||
|
||||
void gitSubmodules( const std::string& args, const std::string& projectDir, std::string& buf );
|
||||
|
||||
Blame blame( const std::string& filepath, std::size_t line ) const;
|
||||
|
||||
std::string branch( const std::string& projectDir = "" );
|
||||
@@ -65,6 +81,8 @@ class Git {
|
||||
std::string mGitPath;
|
||||
std::string mProjectPath;
|
||||
std::string mGitFolder;
|
||||
|
||||
bool hasSubmodules( const std::string& projectDir );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user