Commit c5f3da9692f8de15550fed47e377c586f99f7c5a

Patrick Steinhardt 2016-11-11T14:36:43

repository: use `git_repository_item_path` The recent introduction of the commondir variable of a repository requires callers to distinguish whether their files are part of the dot-git directory or the common directory shared between multpile worktrees. In order to take the burden from callers and unify knowledge on which files reside where, the `git_repository_item_path` function has been introduced which encapsulate this knowledge. Modify most existing callers of `git_repository_path` to use `git_repository_item_path` instead, thus making them implicitly aware of the common directory.

diff --git a/src/attr.c b/src/attr.c
index d43a15f..93dea12 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -292,7 +292,7 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
 	int error = 0;
 	const char *workdir = git_repository_workdir(repo);
 	git_index *idx = NULL;
-	git_buf sys = GIT_BUF_INIT;
+	git_buf path = GIT_BUF_INIT;
 
 	if (attr_session && attr_session->init_setup)
 		return 0;
@@ -304,40 +304,45 @@ static int attr_setup(git_repository *repo, git_attr_session *attr_session)
 	 * definitions will be available for later file parsing
 	 */
 
-	error = system_attr_file(&sys, attr_session);
+	error = system_attr_file(&path, attr_session);
 
 	if (error == 0)
 		error = preload_attr_file(
-			repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
+			repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, path.ptr);
 
 	if (error != GIT_ENOTFOUND)
-		return error;
-
-	git_buf_free(&sys);
+		goto out;
 
 	if ((error = preload_attr_file(
 			repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
 			NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
-		return error;
+		goto out;
+
+	if ((error = git_repository_item_path(&path,
+			repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
+		goto out;
 
 	if ((error = preload_attr_file(
 			repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
-			git_repository_path(repo), GIT_ATTR_FILE_INREPO)) < 0)
-		return error;
+			path.ptr, GIT_ATTR_FILE_INREPO)) < 0)
+		goto out;
 
 	if (workdir != NULL &&
 		(error = preload_attr_file(
 			repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
-		return error;
+		goto out;
 
 	if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
 		(error = preload_attr_file(
 			repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
-		return error;
+		goto out;
 
 	if (attr_session)
 		attr_session->init_setup = 1;
 
+out:
+	git_buf_free(&path);
+
 	return error;
 }
 
@@ -472,7 +477,7 @@ static int collect_attr_files(
 	git_vector *files)
 {
 	int error = 0;
-	git_buf dir = GIT_BUF_INIT;
+	git_buf dir = GIT_BUF_INIT, attrfile = GIT_BUF_INIT;
 	const char *workdir = git_repository_workdir(repo);
 	attr_walk_up_info info = { NULL };
 
@@ -494,9 +499,13 @@ static int collect_attr_files(
 	 * - $GIT_PREFIX/etc/gitattributes
 	 */
 
+	error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO);
+	if (error < 0)
+		goto cleanup;
+
 	error = push_attr_file(
 		repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
-		git_repository_path(repo), GIT_ATTR_FILE_INREPO);
+		attrfile.ptr, GIT_ATTR_FILE_INREPO);
 	if (error < 0)
 		goto cleanup;
 
@@ -538,6 +547,7 @@ static int collect_attr_files(
  cleanup:
 	if (error < 0)
 		release_attr_files(files);
+	git_buf_free(&attrfile);
 	git_buf_free(&dir);
 
 	return error;
diff --git a/src/attr_file.h b/src/attr_file.h
index 388ecf4..a9af240 100644
--- a/src/attr_file.h
+++ b/src/attr_file.h
@@ -15,7 +15,7 @@
 #include "fileops.h"
 
 #define GIT_ATTR_FILE			".gitattributes"
-#define GIT_ATTR_FILE_INREPO	"info/attributes"
+#define GIT_ATTR_FILE_INREPO	"attributes"
 #define GIT_ATTR_FILE_SYSTEM	"gitattributes"
 #define GIT_ATTR_FILE_XDG		"attributes"
 
diff --git a/src/blob.c b/src/blob.c
index cd5df35..19d3039 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -326,8 +326,8 @@ int git_blob_create_fromstream(git_writestream **out, git_repository *repo, cons
 	stream->parent.close = blob_writestream_close;
 	stream->parent.free  = blob_writestream_free;
 
-	if ((error = git_buf_joinpath(&path,
-				      git_repository_path(repo), GIT_OBJECTS_DIR "streamed")) < 0)
+	if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0
+		|| (error = git_buf_joinpath(&path, path.ptr, "streamed")) < 0)
 		goto cleanup;
 
 	if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY,
diff --git a/src/clone.c b/src/clone.c
index 0d4756e..16ddfac 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -513,9 +513,8 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_
 		return error;
 	}
 
-	git_buf_joinpath(&src_odb, git_repository_path(src), GIT_OBJECTS_DIR);
-	git_buf_joinpath(&dst_odb, git_repository_path(repo), GIT_OBJECTS_DIR);
-	if (git_buf_oom(&src_odb) || git_buf_oom(&dst_odb)) {
+	if (git_repository_item_path(&src_odb, src, GIT_REPOSITORY_ITEM_OBJECTS) < 0
+		|| git_repository_item_path(&dst_odb, repo, GIT_REPOSITORY_ITEM_OBJECTS) < 0) {
 		error = -1;
 		goto cleanup;
 	}
diff --git a/src/ignore.c b/src/ignore.c
index cc9e08e..c324d4d 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -277,6 +277,7 @@ int git_ignore__for_path(
 {
 	int error = 0;
 	const char *workdir = git_repository_workdir(repo);
+	git_buf infopath = GIT_BUF_INIT;
 
 	assert(repo && ignores && path);
 
@@ -322,10 +323,14 @@ int git_ignore__for_path(
 			goto cleanup;
 	}
 
+	if ((error = git_repository_item_path(&infopath,
+			repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
+		goto cleanup;
+
 	/* load .git/info/exclude */
 	error = push_ignore_file(
 		ignores, &ignores->ign_global,
-		git_repository_path(repo), GIT_IGNORE_FILE_INREPO);
+		infopath.ptr, GIT_IGNORE_FILE_INREPO);
 	if (error < 0)
 		goto cleanup;
 
@@ -336,6 +341,7 @@ int git_ignore__for_path(
 			git_repository_attr_cache(repo)->cfg_excl_file);
 
 cleanup:
+	git_buf_free(&infopath);
 	if (error < 0)
 		git_ignore__free(ignores);
 
diff --git a/src/ignore.h b/src/ignore.h
index d40bd60..876c8e0 100644
--- a/src/ignore.h
+++ b/src/ignore.h
@@ -12,7 +12,7 @@
 #include "attr_file.h"
 
 #define GIT_IGNORE_FILE			".gitignore"
-#define GIT_IGNORE_FILE_INREPO	"info/exclude"
+#define GIT_IGNORE_FILE_INREPO	"exclude"
 #define GIT_IGNORE_FILE_XDG		"ignore"
 
 /* The git_ignores structure maintains three sets of ignores:
diff --git a/src/repository.c b/src/repository.c
index 14ad7a5..ed70385 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -992,7 +992,8 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
 		git_buf odb_path = GIT_BUF_INIT;
 		git_odb *odb;
 
-		if ((error = git_buf_joinpath(&odb_path, repo->commondir, GIT_OBJECTS_DIR)) < 0)
+		if ((error = git_repository_item_path(&odb_path, repo,
+				GIT_REPOSITORY_ITEM_OBJECTS)) < 0)
 			return error;
 
 		error = git_odb_open(&odb, odb_path.ptr);
diff --git a/src/submodule.c b/src/submodule.c
index 1c17075..3007d25 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -616,8 +616,10 @@ static int submodule_repo_init(
 	 * Old style: sub-repo goes directly into repo/<name>/.git/
 	 */
 	 if (use_gitlink) {
-		error = git_buf_join3(
-			&repodir, '/', git_repository_path(parent_repo), "modules", path);
+		error = git_repository_item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES);
+		if (error < 0)
+			goto cleanup;
+		error = git_buf_joinpath(&repodir, repodir.ptr, path);
 		if (error < 0)
 			goto cleanup;
 
@@ -1084,8 +1086,10 @@ static int submodule_repo_create(
 	 * <repo-dir>/modules/<name>/ with a gitlink in the
 	 * sub-repo workdir directory to that repository.
 	 */
-	error = git_buf_join3(
-		&repodir, '/', git_repository_path(parent_repo), "modules", path);
+	error = git_repository_item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES);
+	if (error < 0)
+		goto cleanup;
+	error = git_buf_joinpath(&repodir, repodir.ptr, path);
 	if (error < 0)
 		goto cleanup;
 
diff --git a/src/transports/local.c b/src/transports/local.c
index 87745ad..e24e998 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -375,7 +375,8 @@ static int local_push(
 		goto on_error;
 	}
 
-	if ((error = git_buf_joinpath(&odb_path, git_repository_path(remote_repo), "objects/pack")) < 0)
+	if ((error = git_repository_item_path(&odb_path, remote_repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0
+		|| (error = git_buf_joinpath(&odb_path, odb_path.ptr, "pack")) < 0)
 		goto on_error;
 
 	error = git_packbuilder_write(push->pb, odb_path.ptr, 0, transfer_to_push_transfer, (void *) cbs);