[PATCH] Improved handling of git syntax names with no git repository

Linus Torvalds torvalds at linux-foundation.org
Fri Mar 14 18:00:13 PDT 2014


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Fri, 14 Mar 2014 17:55:07 -0700
Subject: [PATCH] Improved handling of git syntax names with no git repository

This makes "is_git_repository()" return non-NULL for all file names that
match the git name pattern, even if we don't find an actual git
repository there.  That way, we won't fall back to writing out an XML
file with an odd filename.

If there is no actual git repository, we return a special invalid dummy
pointer, and then the git reading and writing routines will catch it and
return the appropriate error.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

The 'dummy_git_repository' pointer is just so that any caller doesn't need 
to know any internal details about git repositories etc. As far as callers 
are concerned, the pattern is simply to call "is_git_repository()" and if 
non-NULL pass it off to the reading/writing routines.

 dive.h     |  1 +
 load-git.c |  6 +++++-
 save-git.c | 29 ++++++++++++++++++++++++-----
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/dive.h b/dive.h
index c6867fc5d68c..ea7a238a3086 100644
--- a/dive.h
+++ b/dive.h
@@ -689,6 +689,7 @@ extern int export_dives_uddf(const char *filename, const bool selected);
 
 struct git_oid;
 struct git_repository;
+#define dummy_git_repository ((git_repository *) 8ul) /* Random bogus pointer, not NULL */
 extern struct git_repository *is_git_repository(const char *filename, const char **branchp);
 extern int git_save_dives(struct git_repository *, const char *, bool select_only);
 extern int git_load_dives(struct git_repository *, const char *);
diff --git a/load-git.c b/load-git.c
index c861799b469b..4040c16779e1 100644
--- a/load-git.c
+++ b/load-git.c
@@ -1243,7 +1243,11 @@ static int do_git_load(git_repository *repo, const char *branch)
  */
 int git_load_dives(struct git_repository *repo, const char *branch)
 {
-	int ret = do_git_load(repo, branch);
+	int ret;
+
+	if (repo == dummy_git_repository)
+		return report_error("Unable to open git repository at '%s'", branch);
+	ret = do_git_load(repo, branch);
 	git_repository_free(repo);
 	free((void *)branch);
 	finish_active_dive();
diff --git a/save-git.c b/save-git.c
index 745f26b01e36..74eab55bb074 100644
--- a/save-git.c
+++ b/save-git.c
@@ -924,30 +924,45 @@ struct git_repository *is_git_repository(const char *filename, const char **bran
 	if (!flen)
 		return NULL;
 
+	/*
+	 * This is the "point of no return": the name matches
+	 * the git repository name rules, and we will no longer
+	 * return NULL.
+	 *
+	 * We will either return "dummy_git_repository" and the
+	 * branch pointer will have the _whole_ filename in it,
+	 * or we will return a real git repository with the
+	 * branch pointer being filled in with just the branch
+	 * name.
+	 *
+	 * The actual git reading/writing routines can use this
+	 * to generate proper error messages.
+	 */
+	*branchp = filename;
 	loc = malloc(flen+1);
 	if (!loc)
-		return NULL;
+		return dummy_git_repository;
 	memcpy(loc, filename, flen);
 	loc[flen] = 0;
 
 	branch = malloc(blen+1);
 	if (!branch) {
 		free(loc);
-		return NULL;
+		return dummy_git_repository;
 	}
 	memcpy(branch, filename+flen+1, blen);
 	branch[blen] = 0;
 
 	if (stat(loc, &st) < 0 || !S_ISDIR(st.st_mode)) {
 		free(loc);
-		return NULL;
+		return dummy_git_repository;
 	}
 
 	ret = git_repository_open(&repo, loc);
 	free(loc);
 	if (ret < 0) {
 		free(branch);
-		return NULL;
+		return dummy_git_repository;
 	}
 	*branchp = branch;
 	return repo;
@@ -955,7 +970,11 @@ struct git_repository *is_git_repository(const char *filename, const char **bran
 
 int git_save_dives(struct git_repository *repo, const char *branch, bool select_only)
 {
-	int ret = do_git_save(repo, branch, select_only);
+	int ret;
+
+	if (repo == dummy_git_repository)
+		return report_error("Unable to open git repository '%s'", branch);
+	ret = do_git_save(repo, branch, select_only);
 	git_repository_free(repo);
 	free((void *)branch);
 	return ret;
-- 
1.9.0



More information about the subsurface mailing list