Skip to content

Commit

Permalink
Moved tag detection to separate method
Browse files Browse the repository at this point in the history
  • Loading branch information
tfpf committed Oct 29, 2024
1 parent 9e84074 commit 4fcd5a7
Showing 1 changed file with 40 additions and 18 deletions.
58 changes: 40 additions & 18 deletions custom-prompt/custom-prompt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class GitRepository
std::filesystem::path gitdir;
C::git_reference* ref;
C::git_oid const* oid;
std::string description;
std::string description, tag;
bool bare, detached;
std::string state;
bool dirty, staged, untracked;
Expand All @@ -192,11 +192,12 @@ class GitRepository

private:
void establish_description(void);
void establish_tag(void);
void establish_state(void);
void establish_dirty_staged_untracked(void);
// These are static methods because otherwise, their signatures do not
// match the required signatures for use as callback functions.
static int update_description(char const* name, C::git_oid* oid, void* self_);
static int update_tag(char const* name, C::git_oid* oid, void* self_);
static int update_dirty_staged_untracked(char const* path, unsigned status_flags, void* self_);
};

Expand All @@ -217,6 +218,7 @@ GitRepository::GitRepository(void) :
}
this->gitdir = C::git_repository_path(this->repo);
this->establish_description();
this->establish_tag();
this->bare = C::git_repository_is_bare(this->repo);
this->detached = C::git_repository_head_detached(this->repo);
this->establish_state();
Expand All @@ -226,32 +228,35 @@ GitRepository::GitRepository(void) :
/******************************************************************************
* Obtain a human-readable description of the working tree of the current Git
* repository. This shall be the name of the current branch if it is available.
* Otherwise, it shall be the hash of the most recent commit (and possibly its
* tag).
* Otherwise, it shall be the hash of the most recent commit.
*****************************************************************************/
void GitRepository::establish_description(void)
{
if (C::git_repository_head(&this->ref, this->repo) == 0)
{
// According to the documentation, this retrieves the OID only if the
// reference is direct. However, I observed that it does so even if the
// reference is symbolic (i.e. we are on a branch). There is no harm in
// leaving it here because if it fails, it will just return a null
// pointer.
this->oid = C::git_reference_target(this->ref);

char const* branch_name;
if (C::git_branch_name(&branch_name, this->ref) == 0)
{
this->description = branch_name;
return;
};

// If not on a branch, use the commit hash and the tag, if there is
// one. Unannotated tags cannot be looked up, so the only way to check
// is to iterate over all tags.
this->oid = C::git_reference_target(this->ref);
// We are not on a branch. The reference must be direct. Use the commit
// hash.
this->description = C::git_oid_tostr_s(this->oid);
this->description.erase(7);
C::git_tag_foreach(this->repo, this->update_description, this);
return;
}

// If we are here, we must be on a branch with no commits. Obtain the
// required information manually.
// We must be on a branch with no commits. Obtain the required information
// manually.
std::ifstream head_file(this->gitdir / "HEAD");
if (!head_file.good())
{
Expand All @@ -264,6 +269,19 @@ void GitRepository::establish_description(void)
}
}

/******************************************************************************
* Obtain the tag of the working tree of the current Git repository (if there
* is one).
*****************************************************************************/
void GitRepository::establish_tag(void)
{
if (this->oid == nullptr)
{
return;
}
C::git_tag_foreach(this->repo, this->update_tag, this);
}

/******************************************************************************
* Obtain the state of the working tree of the current Git repository. This
* shall be the name of the operation currently in progress (if any).
Expand Down Expand Up @@ -307,28 +325,28 @@ void GitRepository::establish_dirty_staged_untracked(void)

/******************************************************************************
* Check whether the given tag matches the reference of the given
* `GitRepository` instance. If it does, update the description of the latter
* with the tag name.
* `GitRepository` instance. If it does, update the corresponding member of the
* latter.
*
* @param name Tag name.
* @param oid Tag object ID.
* @param self_ `GitRepository` instance whose description should be updated.
*
* @return 1 if the tag matches the reference, 0 otherwise.
*****************************************************************************/
int GitRepository::update_description(char const* name, C::git_oid* oid, void* self_)
int GitRepository::update_tag(char const* name, C::git_oid* oid, void* self_)
{
GitRepository* self = static_cast<GitRepository*>(self_);
if (C::git_oid_cmp(oid, self->oid) != 0)
{
return 0;
}
std::string tag_name = name;
if (tag_name.rfind("refs/tags/", 0) == 0)
std::string tag = name;
if (tag.rfind("refs/tags/", 0) == 0)
{
tag_name = tag_name.substr(10);
tag = tag.substr(10);
}
self->description += " 󰓼 " + tag_name;
self->tag = tag;
// Found a match. Stop iterating.
return 1;
}
Expand Down Expand Up @@ -396,6 +414,10 @@ std::string GitRepository::get_information(void)
{
information_stream << D_GREEN << this->description << RESET;
}
if (!this->tag.empty())
{
information_stream << " 󰓼 " << this->tag;
}
if (this->dirty || this->staged || this->untracked)
{
information_stream << ' ';
Expand Down

0 comments on commit 4fcd5a7

Please sign in to comment.