mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-01 18:50:16 +03:00
More fixes in the new git commands.
This commit is contained in:
@@ -225,31 +225,27 @@ Git::CountResult Git::branchHistoryPosition( const std::string& localBranch,
|
||||
const std::string& remoteBranch,
|
||||
const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
int retCode = git( String::format( "rev-list --count %s..%s", localBranch, remoteBranch ),
|
||||
projectDir, buf );
|
||||
int retCode =
|
||||
git( String::format( "rev-list --left-right --count %s...%s", localBranch, remoteBranch ),
|
||||
projectDir, buf );
|
||||
Git::CountResult res;
|
||||
res.returnCode = retCode;
|
||||
if ( res.success() ) {
|
||||
uint64_t count = 0;
|
||||
if ( String::fromString( count, buf ) )
|
||||
res.behind = count;
|
||||
String::trimInPlace( buf );
|
||||
auto results = String::split( buf, '\t' );
|
||||
if ( results.size() == 2 ) {
|
||||
int64_t behind = 0;
|
||||
int64_t ahead = 0;
|
||||
if ( String::fromString( ahead, results[0] ) &&
|
||||
String::fromString( behind, results[1] ) ) {
|
||||
res.ahead = ahead;
|
||||
res.behind = behind;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res.result = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
retCode = git( String::format( "rev-list --count %s..%s", remoteBranch, localBranch ),
|
||||
projectDir, buf );
|
||||
res.returnCode = retCode;
|
||||
|
||||
if ( res.success() ) {
|
||||
uint64_t count = 0;
|
||||
if ( String::fromString( count, buf ) )
|
||||
res.ahead = count;
|
||||
} else {
|
||||
res.result = buf;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -277,12 +273,28 @@ std::vector<Git::Branch> Git::getAllBranches( const std::string& projectDir ) {
|
||||
projectDir );
|
||||
}
|
||||
|
||||
static Git::Branch parseLocalBranch( const std::string_view& raw ) {
|
||||
Git::Branch Git::parseLocalBranch( const std::string_view& raw,
|
||||
const std::unordered_map<std::string, std::string>& headOrigins,
|
||||
const std::string& projectDir ) {
|
||||
static constexpr size_t len = std::string_view{ "refs/heads/"sv }.size();
|
||||
if ( len < raw.size() )
|
||||
return Git::Branch{ std::string{ raw.substr( len ) }, std::string{}, Git::RefType::Head,
|
||||
std::string{} };
|
||||
return {};
|
||||
if ( len >= raw.size() )
|
||||
return {};
|
||||
|
||||
std::string name( std::string{ raw.substr( len ) } );
|
||||
auto found = headOrigins.find( name );
|
||||
std::string remote;
|
||||
int64_t ahead = 0;
|
||||
int64_t behind = 0;
|
||||
if ( found != headOrigins.end() ) {
|
||||
remote = found->second;
|
||||
auto res = branchHistoryPosition( name, remote );
|
||||
if ( res.success() ) {
|
||||
ahead = res.ahead;
|
||||
behind = res.behind;
|
||||
}
|
||||
}
|
||||
return Git::Branch{
|
||||
std::move( name ), std::move( remote ), Git::RefType::Head, std::string{}, ahead, behind };
|
||||
}
|
||||
|
||||
static Git::Branch parseRemoteBranch( const std::string_view& raw ) {
|
||||
@@ -313,10 +325,12 @@ std::vector<Git::Branch> Git::getAllBranchesAndTags( RefType ref, const std::str
|
||||
|
||||
branches.reserve( countLines( buf ) );
|
||||
|
||||
readAllLines( buf, [&branches, ref]( const std::string_view& line ) {
|
||||
auto headOrigins = getHeadOrigins( projectDir );
|
||||
|
||||
readAllLines( buf, [&branches, ref, &headOrigins, this]( const std::string_view& line ) {
|
||||
auto branch = String::trim( String::trim( line, '\n' ), '\'' );
|
||||
if ( ( ref & Head ) && String::startsWith( branch, "refs/heads/" ) ) {
|
||||
branches.emplace_back( parseLocalBranch( branch ) );
|
||||
branches.emplace_back( parseLocalBranch( branch, headOrigins ) );
|
||||
} else if ( ( ref & Remote ) && String::startsWith( branch, "refs/remotes/" ) ) {
|
||||
branches.emplace_back( parseRemoteBranch( branch ) );
|
||||
} else if ( ( ref & Tag ) && String::startsWith( branch, "refs/tags/" ) ) {
|
||||
@@ -354,6 +368,26 @@ std::vector<std::string> Git::getSubModules( const std::string& projectDir ) {
|
||||
return mSubModules;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> Git::getHeadOrigins( const std::string& projectDir ) {
|
||||
std::unordered_map<std::string, std::string> ret;
|
||||
std::string buf;
|
||||
int retCode = git( "for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads",
|
||||
projectDir, buf );
|
||||
Result res;
|
||||
res.returnCode = retCode;
|
||||
if ( res.fail() )
|
||||
return ret;
|
||||
|
||||
readAllLines( buf, [&ret]( const std::string_view& line ) {
|
||||
auto split = String::split( String::trim( line, '\'' ), '\t' );
|
||||
if ( split.size() != 2 )
|
||||
return;
|
||||
ret[std::string{ split[0] }] = std::string{ split[1] };
|
||||
} );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Git::hasSubmodules( const std::string& projectDir ) {
|
||||
return ( !projectDir.empty() && FileSystem::fileExists( projectDir + ".gitmodules" ) ) ||
|
||||
( !mProjectPath.empty() && FileSystem::fileExists( mProjectPath + ".gitmodules" ) );
|
||||
@@ -459,7 +493,7 @@ Git::Status Git::status( bool recurseSubmodules, const std::string& projectDir )
|
||||
if ( statusStr.size() < 2 )
|
||||
return;
|
||||
|
||||
Uint16 status = xy( statusStr[0], statusStr[1] );
|
||||
Uint16 status = git_xy( statusStr[0], statusStr[1] );
|
||||
GitStatus gitStatus = GitStatus::NotSet;
|
||||
GitStatusChar gitStatusChar = GitStatusChar::Unknown;
|
||||
GitStatusType gitStatusType = GitStatusType::Untracked;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
namespace ecode {
|
||||
|
||||
#define git_xy( x, y ) ( ( (uint16_t)x ) << 8 | y )
|
||||
|
||||
class Git {
|
||||
public:
|
||||
struct Blame {
|
||||
@@ -72,37 +74,29 @@ class Git {
|
||||
Ignored,
|
||||
};
|
||||
|
||||
static constexpr uint16_t xy( char x, char y ) { return ( (uint16_t)x ) << 8 | y; }
|
||||
|
||||
static constexpr uint16_t x( uint16_t val ) { return ( val >> 8 ) & 0xFF; }
|
||||
|
||||
static constexpr uint16_t y( uint16_t val ) { return val & 0xFF; }
|
||||
|
||||
static constexpr auto ANY = 0;
|
||||
|
||||
#define _xy( x, y ) ( ( (uint16_t)x ) << 8 | y )
|
||||
|
||||
enum StatusXY : uint16_t {
|
||||
A = _xy( ' ', 'A' ), // modified, added not updated
|
||||
M = _xy( ' ', 'M' ), // modified, modified not updated
|
||||
D = _xy( ' ', 'D' ), // modified, deleted not updated
|
||||
m = _xy( ' ', 'm' ), // modified, modified submodule not updated
|
||||
DD = _xy( 'D', 'D' ), // unmerged, both deleted
|
||||
AU = _xy( 'A', 'U' ), // unmerged, added by us
|
||||
UD = _xy( 'U', 'D' ), // unmerged, deleted by them
|
||||
UA = _xy( 'U', 'A' ), // unmerged, added by them
|
||||
DU = _xy( 'D', 'U' ), // unmerged, deleted by us
|
||||
AA = _xy( 'A', 'A' ), // unmerged, both added
|
||||
UU = _xy( 'U', 'U' ), // unmerged, both modified
|
||||
QQ = _xy( '?', '?' ), // untracked
|
||||
II = _xy( '!', '!' ), // ignored
|
||||
SM = _xy( 'M', ANY ), // staged modified
|
||||
ST = _xy( 'T', ANY ), // staged type changed
|
||||
SA = _xy( 'A', ANY ), // staged added
|
||||
SD = _xy( 'D', ANY ), // staged deleted
|
||||
SR = _xy( 'R', ANY ), // staged renamed
|
||||
SC = _xy( 'C', ANY ), // staged copied
|
||||
SMM = _xy( 'm', ANY ), // staged modified submodule
|
||||
A = git_xy( ' ', 'A' ), // modified, added not updated
|
||||
M = git_xy( ' ', 'M' ), // modified, modified not updated
|
||||
D = git_xy( ' ', 'D' ), // modified, deleted not updated
|
||||
m = git_xy( ' ', 'm' ), // modified, modified submodule not updated
|
||||
DD = git_xy( 'D', 'D' ), // unmerged, both deleted
|
||||
AU = git_xy( 'A', 'U' ), // unmerged, added by us
|
||||
UD = git_xy( 'U', 'D' ), // unmerged, deleted by them
|
||||
UA = git_xy( 'U', 'A' ), // unmerged, added by them
|
||||
DU = git_xy( 'D', 'U' ), // unmerged, deleted by us
|
||||
AA = git_xy( 'A', 'A' ), // unmerged, both added
|
||||
UU = git_xy( 'U', 'U' ), // unmerged, both modified
|
||||
QQ = git_xy( '?', '?' ), // untracked
|
||||
II = git_xy( '!', '!' ), // ignored
|
||||
SM = git_xy( 'M', ANY ), // staged modified
|
||||
ST = git_xy( 'T', ANY ), // staged type changed
|
||||
SA = git_xy( 'A', ANY ), // staged added
|
||||
SD = git_xy( 'D', ANY ), // staged deleted
|
||||
SR = git_xy( 'R', ANY ), // staged renamed
|
||||
SC = git_xy( 'C', ANY ), // staged copied
|
||||
SMM = git_xy( 'm', ANY ), // staged modified submodule
|
||||
};
|
||||
|
||||
struct DiffFile {
|
||||
@@ -186,6 +180,9 @@ class Git {
|
||||
RefType type = All;
|
||||
/** last commit on this branch, may be empty **/
|
||||
std::string lastCommit;
|
||||
/** if it's HEAD how much ahead and behind the current local branch is against remote */
|
||||
int64_t ahead{ 0 };
|
||||
int64_t behind{ 0 };
|
||||
|
||||
const char* typeStr() const { return refTypeToString( type ); }
|
||||
};
|
||||
@@ -256,6 +253,9 @@ class Git {
|
||||
|
||||
std::vector<std::string> getSubModules( const std::string& projectDir = "" );
|
||||
|
||||
std::unordered_map<std::string, std::string>
|
||||
getHeadOrigins( const std::string& projectDir = "" );
|
||||
|
||||
protected:
|
||||
std::string mGitPath;
|
||||
std::string mProjectPath;
|
||||
@@ -267,6 +267,10 @@ class Git {
|
||||
bool hasSubmodules( const std::string& projectDir );
|
||||
|
||||
std::string inSubModule( const std::string& file, const std::string& projectDir );
|
||||
|
||||
Git::Branch parseLocalBranch( const std::string_view& raw,
|
||||
const std::unordered_map<std::string, std::string>& headOrigins,
|
||||
const std::string& projectDir = "" );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user