Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: Colomban Wendling ban@herbesfolles.org Date: Tue, 26 May 2015 11:59:55 UTC Commit: 6a396b11fd95c90f81552edadfae152be7c35a94 https://github.com/geany/geany-plugins/commit/6a396b11fd95c90f81552edadfae15...
Log Message: ----------- git-changebar: Fix in-repository paths on Windows
Git uses its own path representation for files inside its tree, which follows the UNIX path style (forward slashes). So properly convert internal paths from native to Git paths.
See https://github.com/libgit2/libgit2/issues/3012
Part of Issue #214.
Modified Paths: -------------- git-changebar/src/gcb-plugin.c
Modified: git-changebar/src/gcb-plugin.c 64 lines changed, 59 insertions(+), 5 deletions(-) =================================================================== @@ -290,6 +290,58 @@ monitor_head_ref (git_repository *repo, return monitor; }
+/* checks whether @path points somewhere inside @dir and returns the pointer + * inside @path starting the relative path, or NULL */ +static const gchar * +path_dir_contains (const gchar *dir, + const gchar *path) +{ +#ifdef G_OS_WIN32 + /* FIXME: handle drive letters and such */ +# define NORM_PATH_CH(c) (((c) == '\') ? '/' : (c)) +#else +# define NORM_PATH_CH(c) (c) +#endif + + g_return_val_if_fail (dir != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + while (*dir && NORM_PATH_CH (*dir) == NORM_PATH_CH (*path)) { + dir++, path++; + } + + return *dir ? NULL : path; +} + +/* gets the Git path for @repo pointing to @sys_path, or NULL */ +static gchar * +get_path_in_repository (git_repository *repo, + const gchar *sys_path) +{ + const gchar *workdir = git_repository_workdir (repo); + const gchar *rel_path = path_dir_contains (workdir, sys_path); + +#ifdef G_OS_WIN32 + if (rel_path) { + /* we want an internal Git path, which uses UNIX format */ + gchar *p; + gchar *repo_path = g_strdup (rel_path); + + for (p = repo_path; *p; p++) { + if (*p == '\') { + *p = '/'; + } + } + + return repo_path; + } + + return NULL; +#else + return g_strdup (rel_path); +#endif +} + static gpointer worker_thread (gpointer data) { @@ -303,7 +355,7 @@ worker_thread (gpointer data) const gchar *path = job->path;
if (repo && (job->force || - ! g_str_has_prefix (path, git_repository_workdir (repo)))) { + ! path_dir_contains (path, git_repository_workdir (repo)))) { /* FIXME: this can fail with nested repositories */ git_repository_free (repo); repo = NULL; @@ -330,12 +382,14 @@ worker_thread (gpointer data) } }
+ job->blob = NULL; if (repo) { - const gchar *relpath = path + strlen (git_repository_workdir (repo)); + gchar *relpath = get_path_in_repository (repo, path);
- job->blob = repo_get_file_blob (repo, relpath); - } else { - job->blob = NULL; + if (relpath) { + job->blob = repo_get_file_blob (repo, relpath); + g_free (relpath); + } }
g_idle_add_full (G_PRIORITY_LOW, report_work_in_idle, job, free_job);
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).