[PATCH v2] Make git_dir a path relative to work_tree in setup_work_tree()

Subsystems: the rest

DORMANTno replies

4 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH v2] Make git_dir a path relative to work_tree in setup_work_tree()

From: Daniel Barkalow <hidden>
Date: 2016-06-15 22:44:47

Once we find the absolute paths for git_dir and work_tree, we can make
git_dir a relative path since we know pwd will be work_tree. This should
save the kernel some time traversing the path to work_tree all the time
if git_dir is inside work_tree.

Signed-off-by: Daniel Barkalow <redacted>
---
Not only was work_tree potentially NULL, it was also already a copied 
canonical path. So this simpler patch should be better.

 cache.h |    1 +
 path.c  |   17 +++++++++++++++++
 setup.c |    3 ++-
 3 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/cache.h b/cache.h
index eab1a17..3465c94 100644
--- a/cache.h
+++ b/cache.h
@@ -524,6 +524,7 @@ static inline int is_absolute_path(const char *path)
 	return path[0] == '/';
 }
 const char *make_absolute_path(const char *path);
+const char *make_relative_path(const char *abs, const char *base);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index b7c24a2..790d8d4 100644
--- a/path.c
+++ b/path.c
@@ -294,6 +294,23 @@ int adjust_shared_perm(const char *path)
 /* We allow "recursive" symbolic links. Only within reason, though. */
 #define MAXDEPTH 5
 
+const char *make_relative_path(const char *abs, const char *base)
+{
+	static char buf[PATH_MAX + 1];
+	int baselen;
+	if (!base)
+		return abs;
+	baselen = strlen(base);
+	if (prefixcmp(abs, base))
+		return abs;
+	if (abs[baselen] == '/')
+		baselen++;
+	else if (base[baselen - 1] != '/')
+		return abs;
+	strcpy(buf, abs + baselen);
+	return buf;
+}
+
 const char *make_absolute_path(const char *path)
 {
 	static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
diff --git a/setup.c b/setup.c
index d630e37..1643ee4 100644
--- a/setup.c
+++ b/setup.c
@@ -292,7 +292,8 @@ void setup_work_tree(void)
 	work_tree = get_git_work_tree();
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
-		set_git_dir(make_absolute_path(git_dir));
+		set_git_dir(make_relative_path(make_absolute_path(git_dir),
+					       work_tree));
 	if (!work_tree || chdir(work_tree))
 		die("This operation must be run in a work tree");
 	initialized = 1;
-- 
1.5.4.5

Re: [PATCH v2] Make git_dir a path relative to work_tree in setup_work_tree()

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:44:47

Hi,

On Wed, 18 Jun 2008, Daniel Barkalow wrote:
quoted hunk
diff --git a/setup.c b/setup.c
index d630e37..1643ee4 100644
--- a/setup.c
+++ b/setup.c
@@ -292,7 +292,8 @@ void setup_work_tree(void)
 	work_tree = get_git_work_tree();
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
I suspect it needs "work_tree &&" here.
-		set_git_dir(make_absolute_path(git_dir));
+		set_git_dir(make_relative_path(make_absolute_path(git_dir),
+					       work_tree));
 	if (!work_tree || chdir(work_tree))
 		die("This operation must be run in a work tree");
 	initialized = 1;
All in all I am pretty surprised how easy it was.  I tried yesterday, for 
half an hour, to come up with something sensible, and failed.

Thanks,
Dscho

Re: [PATCH v2] Make git_dir a path relative to work_tree in setup_work_tree()

From: Daniel Barkalow <hidden>
Date: 2016-06-15 22:44:47

On Thu, 19 Jun 2008, Johannes Schindelin wrote:
Hi,

On Wed, 18 Jun 2008, Daniel Barkalow wrote:
quoted
diff --git a/setup.c b/setup.c
index d630e37..1643ee4 100644
--- a/setup.c
+++ b/setup.c
@@ -292,7 +292,8 @@ void setup_work_tree(void)
 	work_tree = get_git_work_tree();
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
I suspect it needs "work_tree &&" here.
I'm not clear on the semantics of !get_git_work_tree(); is a non-absolute 
path for git_dir right then?
quoted
-		set_git_dir(make_absolute_path(git_dir));
+		set_git_dir(make_relative_path(make_absolute_path(git_dir),
+					       work_tree));
 	if (!work_tree || chdir(work_tree))
 		die("This operation must be run in a work tree");
 	initialized = 1;
All in all I am pretty surprised how easy it was.  I tried yesterday, for 
half an hour, to come up with something sensible, and failed.
I was sure you'd come up with just this solution, because you'd just 
recently explained that make_absolute_path() means you can find when one 
path is in another path with a simple string compare. And, since we know 
what pwd is going to be...

	-Daniel
*This .sig left intentionally blank*

Re: [PATCH v2] Make git_dir a path relative to work_tree in setup_work_tree()

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:44:47

Hi,

On Thu, 19 Jun 2008, Daniel Barkalow wrote:
On Thu, 19 Jun 2008, Johannes Schindelin wrote:
quoted
On Wed, 18 Jun 2008, Daniel Barkalow wrote:
quoted
diff --git a/setup.c b/setup.c
index d630e37..1643ee4 100644
--- a/setup.c
+++ b/setup.c
@@ -292,7 +292,8 @@ void setup_work_tree(void)
 	work_tree = get_git_work_tree();
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
I suspect it needs "work_tree &&" here.
I'm not clear on the semantics of !get_git_work_tree(); is a non-absolute 
path for git_dir right then?
My reading was: if there is no work_tree, then a relative git_dir is just 
fine, since we are quite unlikely to jump around in the file system.

And your implementation of make_relative_path() is nice enough to a 
(work_tree ==) base == NULL, but would return the absolute path in that 
case.

Haven't had time to test anything, though.

Ciao,
Dscho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help