I have always been frustrated by trying git on afs.
The other day I finally decided to look into why.
Looks like two reasons caused my frustrations.
1) git presumes that link() works fine across subdirs; in afs land, hardlinks do not succeed ever
2) git presumes that DTYPE(de) != DT_DIR .. means the dirent is not a dir this is not true for afs
I have been using this to sync several git trees, including linux-2.6 for the past week without issues writing to a local afs server.
What do you guys think?
diff --git a/dir.c b/dir.c index eb6c3ab..a3e53a5 100644 --- a/dir.c +++ b/dir.c @@ -487,9 +487,19 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co && in_pathspec(fullname, baselen + len, simplify)) dir_add_ignored(dir, fullname, baselen + len); if (exclude != dir->show_ignored) { - if (!dir->show_ignored || DTYPE(de) != DT_DIR) { + if (!dir->show_ignored) continue; } + if (DTYPE(de) == DT_UNKNOWN) { + struct stat st; + if (lstat(fullname, &st)) + continue; + if (!S_ISDIR(st.st_mode)) + continue; + } else { + if (DTYPE(de) != DT_DIR) + continue; + } } switch (DTYPE(de)) { diff --git a/sha1_file.c b/sha1_file.c index 83a06a7..1b93322 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1961,7 +1961,7 @@ static int link_temp_to_file(const char *tmpfile, const char *filename) int ret; char *dir; - if (!link(tmpfile, filename)) + if (!rename(tmpfile, filename)) return 0; /* @@ -1980,7 +1980,7 @@ static int link_temp_to_file(const char *tmpfile, const char *filename) return -2; } *dir = '/'; - if (!link(tmpfile, filename)) + if (!rename(tmpfile, filename)) return 0; ret = errno; }
--
Todd Fries .. todd@fries.net
_____________________________________________
| \ 1.636.410.0632 (voice)
| Free Daemon Consulting, LLC \ 1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com \ 1.866.792.3418 (FAX)
| "..in support of free software solutions." \ 250797 (FWD)
| \
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
37E7 D3EB 74D0 8D66 A68D B866 0326 204E 3F42 004A
http://todd.fries.net/pgp.txt