summaryrefslogtreecommitdiff
path: root/src/file-manager/fm-icon-container.c
diff options
context:
space:
mode:
authorAnsuz Inspirati <[email protected]>2025-08-25 08:35:41 +1000
committerGitHub <[email protected]>2025-08-24 22:35:41 +0000
commitf093cfa7e4cbb27280576d39d63e5000df9f0d7c (patch)
tree9f5d8e14234c9b596327b60e136099421a2c5f0a /src/file-manager/fm-icon-container.c
parent1cd4e8eeccc7d2424c674a0ebcf646e71b2d2a7b (diff)
downloadcaja-f093cfa7e4cbb27280576d39d63e5000df9f0d7c.tar.bz2
caja-f093cfa7e4cbb27280576d39d63e5000df9f0d7c.tar.xz
New feature - show git branch with icon view text (#1838)
Display the git branch along with directory name in icon view; when the directory is a git repository. Obviously further work will be required to enable/disable as a displayed option, and potentially some level of customisation. This would require open discussion of possibilities. Solutions for co-existence with other displayable parameters also to be community determined. Consideration and feedback appreciated. * Add UI support to enable/disable option Added user interface support for option to enable and disable the display of the git branch name in icon view. * Add internationsation support for the new feature With translations for most of the currently supported languages. * Update caja.pot Build system regenerated .pot file with additional strings from new feature (already in previous commit), new strings already introduced to code-base, along with updated source file line numbers of existing strings. Required for the automated pull mechanism in Transifex - which should complete once merged with master branch.
Diffstat (limited to 'src/file-manager/fm-icon-container.c')
-rw-r--r--src/file-manager/fm-icon-container.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/file-manager/fm-icon-container.c b/src/file-manager/fm-icon-container.c
index c83cf783..8054c2da 100644
--- a/src/file-manager/fm-icon-container.c
+++ b/src/file-manager/fm-icon-container.c
@@ -34,6 +34,7 @@
#include <libcaja-private/caja-thumbnails.h>
#include <libcaja-private/caja-desktop-icon-file.h>
+#include <libcaja-private/caja-icon-private.h>
#include "fm-icon-container.h"
G_DEFINE_TYPE (FMIconContainer, fm_icon_container, CAJA_TYPE_ICON_CONTAINER);
@@ -295,6 +296,67 @@ fm_icon_container_get_icon_text_attribute_names (CajaIconContainer *container,
return attributes;
}
+/**
+ * Parse a .git directory/file to determine repository branch name
+ **/
+static char *
+get_git_branch (const char *git_path) {
+ gchar *head_content = NULL;
+ gchar *branch_name = NULL;
+ gchar *head_path = NULL;
+
+ if (g_file_test (git_path, G_FILE_TEST_IS_REGULAR))
+ {
+ /* It's a file, thus we are probably dealing with a submodule, so read it to resolve the real git dir */
+ gchar *contents = NULL;
+ if (g_file_get_contents (git_path, &contents, NULL, NULL) && contents)
+ {
+ const char *git_dir_prefix = "gitdir: ";
+ if (g_str_has_prefix (contents, git_dir_prefix))
+ {
+ size_t git_dir_prefix_len = strlen (git_dir_prefix);
+ gchar *relative = g_strstrip (contents + git_dir_prefix_len);
+ gchar *base = g_path_get_dirname (git_path);
+ g_free (git_path);
+ git_path = g_build_filename (base, relative, NULL);
+ g_free (base);
+ }
+ g_free (contents);
+ }
+ }
+
+ /* Extract the current git branch name of the repository from file HEAD within .git directory */
+ if (g_file_test (git_path, G_FILE_TEST_IS_DIR))
+ {
+ head_path = g_build_filename (git_path, "HEAD", NULL);
+ if (g_file_get_contents (head_path, &head_content, NULL, NULL))
+ {
+ g_strstrip (head_content);
+ if (g_str_has_prefix (head_content, "ref: "))
+ {
+ gchar **parts = g_strsplit (head_content, "/", -1);
+ if (parts != NULL)
+ {
+ branch_name = g_strdup (parts[g_strv_length(parts) - 1]);
+ g_strchomp (branch_name);
+ g_strfreev (parts);
+ }
+ }
+ else
+ {
+ /* Repository is in a detached HEAD state */
+ branch_name = g_strdup_printf (_("detached: %.7s"), head_content);
+ }
+ }
+ }
+
+ g_free (head_content);
+ g_free (head_path);
+
+ /* branch_name is a newly allocated string, so the caller is responsible for freeing it */
+ return branch_name;
+}
+
/* This callback returns the text, both the editable part, and the
* part below that is not editable.
*/
@@ -398,6 +460,32 @@ fm_icon_container_get_icon_text (CajaIconContainer *container,
if (j == 0)
{
*additional_text = NULL;
+ if (container->details->display_git_branch == CAJA_DISPLAY_GIT_BRANCH_ENABLED)
+ {
+ /* If we have a directory, check if it's a git repository or submodule */
+ GFileType file_type = caja_file_get_file_type (file);
+ if (file_type == G_FILE_TYPE_DIRECTORY)
+ {
+ GFile *location = caja_file_get_location (file);
+ char *path = g_file_get_path (location);
+ if (path != NULL)
+ {
+ char *git_path = g_build_path (G_DIR_SEPARATOR_S, path, ".git", NULL);
+ if (git_path != NULL && G_UNLIKELY(g_file_test (git_path, G_FILE_TEST_EXISTS)))
+ {
+ char *branch = get_git_branch (git_path);
+ if (branch != NULL)
+ {
+ *additional_text = g_strdup_printf ("[%s]", branch);
+ g_free (branch);
+ }
+ }
+ g_free (git_path);
+ g_free (path);
+ }
+ g_object_unref (location);
+ }
+ }
}
else if (j == 1)
{