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(-)
@@ -524,6 +524,7 @@ static inline int is_absolute_path(const char *path)returnpath[0]=='/';}constchar*make_absolute_path(constchar*path);+constchar*make_relative_path(constchar*abs,constchar*base);/* Read and unpack a sha1 file into memory, write memory to a sha1 file */externintsha1_object_info(constunsignedchar*,unsignedlong*);
@@ -294,6 +294,23 @@ int adjust_shared_perm(const char *path)/* We allow "recursive" symbolic links. Only within reason, though. */#define MAXDEPTH 5+constchar*make_relative_path(constchar*abs,constchar*base)+{+staticcharbuf[PATH_MAX+1];+intbaselen;+if(!base)+returnabs;+baselen=strlen(base);+if(prefixcmp(abs,base))+returnabs;+if(abs[baselen]=='/')+baselen++;+elseif(base[baselen-1]!='/')+returnabs;+strcpy(buf,abs+baselen);+returnbuf;+}+constchar*make_absolute_path(constchar*path){staticcharbufs[2][PATH_MAX+1],*buf=bufs[0],*next_buf=bufs[1];
@@ -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;
- 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
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*
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