Avoid cross-directory renames and linking on object creation

Instead of creating new temporary objects in the top-level git object
directory, create them in the same directory they will finally end up in
anyway.  This avoids making the final atomic "rename to stable name"
operation be a cross-directory event, which makes it a lot easier for
various filesystems.

Several filesystems do things like change the inode number when moving
files across directories (or refuse to do it entirely).

In particular, it can also cause problems for NFS implementations that
change the filehandle of a file when it moves to a different directory,
like the old user-space NFS server did, and like the Linux knfsd still
does if you don't export your filesystems with 'no_subtree_check' or if
you export a filesystem that doesn't have stable inode numbers across
renames).

This change also obviously implies creating the object fan-out
subdirectory at tempfile creation time, rather than at the final
move_temp_to_file() time.  Which actually accounts for most of the size
of the patch.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 file changed
tree: 1d3eb8d8bbba8e7ce9a800c4820dee0e4e9e45b4
  1. arm/
  2. compat/
  3. contrib/
  4. Documentation/
  5. git-gui/
  6. gitk-git/
  7. gitweb/
  8. mozilla-sha1/
  9. perl/
  10. ppc/
  11. t/
  12. templates/
  13. xdiff/
  14. .gitattributes
  15. .gitignore
  16. .mailmap
  17. alias.c
  18. alloc.c
  19. archive-tar.c
  20. archive-zip.c
  21. archive.c
  22. archive.h
  23. attr.c
  24. attr.h
  25. base85.c
  26. blob.c
  27. blob.h
  28. branch.c
  29. branch.h
  30. builtin-add.c
  31. builtin-annotate.c
  32. builtin-apply.c
  33. builtin-archive.c
  34. builtin-blame.c
  35. builtin-branch.c
  36. builtin-bundle.c
  37. builtin-cat-file.c
  38. builtin-check-attr.c
  39. builtin-check-ref-format.c
  40. builtin-checkout-index.c
  41. builtin-checkout.c
  42. builtin-clean.c
  43. builtin-clone.c
  44. builtin-commit-tree.c
  45. builtin-commit.c
  46. builtin-config.c
  47. builtin-count-objects.c
  48. builtin-describe.c
  49. builtin-diff-files.c
  50. builtin-diff-index.c
  51. builtin-diff-tree.c
  52. builtin-diff.c
  53. builtin-fast-export.c
  54. builtin-fetch--tool.c
  55. builtin-fetch-pack.c
  56. builtin-fetch.c
  57. builtin-fmt-merge-msg.c
  58. builtin-for-each-ref.c
  59. builtin-fsck.c
  60. builtin-gc.c
  61. builtin-grep.c
  62. builtin-http-fetch.c
  63. builtin-init-db.c
  64. builtin-log.c
  65. builtin-ls-files.c
  66. builtin-ls-remote.c
  67. builtin-ls-tree.c
  68. builtin-mailinfo.c
  69. builtin-mailsplit.c
  70. builtin-merge-base.c
  71. builtin-merge-file.c
  72. builtin-merge-ours.c
  73. builtin-merge-recursive.c
  74. builtin-mv.c
  75. builtin-name-rev.c
  76. builtin-pack-objects.c
  77. builtin-pack-refs.c
  78. builtin-prune-packed.c
  79. builtin-prune.c
  80. builtin-push.c
  81. builtin-read-tree.c
  82. builtin-reflog.c
  83. builtin-remote.c
  84. builtin-rerere.c
  85. builtin-reset.c
  86. builtin-rev-list.c
  87. builtin-rev-parse.c
  88. builtin-revert.c
  89. builtin-rm.c
  90. builtin-send-pack.c
  91. builtin-shortlog.c
  92. builtin-show-branch.c
  93. builtin-show-ref.c
  94. builtin-stripspace.c
  95. builtin-symbolic-ref.c
  96. builtin-tag.c
  97. builtin-tar-tree.c
  98. builtin-unpack-objects.c
  99. builtin-update-index.c
  100. builtin-update-ref.c
  101. builtin-upload-archive.c
  102. builtin-verify-pack.c
  103. builtin-verify-tag.c
  104. builtin-write-tree.c
  105. builtin.h
  106. bundle.c
  107. bundle.h
  108. cache-tree.c
  109. cache-tree.h
  110. cache.h
  111. check-builtins.sh
  112. check-racy.c
  113. color.c
  114. color.h
  115. combine-diff.c
  116. command-list.txt
  117. commit.c
  118. commit.h
  119. config.c
  120. config.mak.in
  121. configure.ac
  122. connect.c
  123. convert.c
  124. copy.c
  125. COPYING
  126. csum-file.c
  127. csum-file.h
  128. ctype.c
  129. daemon.c
  130. date.c
  131. decorate.c
  132. decorate.h
  133. delta.h
  134. diff-delta.c
  135. diff-lib.c
  136. diff-no-index.c
  137. diff.c
  138. diff.h
  139. diffcore-break.c
  140. diffcore-delta.c
  141. diffcore-order.c
  142. diffcore-pickaxe.c
  143. diffcore-rename.c
  144. diffcore.h
  145. dir.c
  146. dir.h
  147. dump-cache-tree.c
  148. entry.c
  149. environment.c
  150. exec_cmd.c
  151. exec_cmd.h
  152. fast-import.c
  153. fetch-pack.h
  154. fixup-builtins
  155. fsck.c
  156. fsck.h
  157. generate-cmdlist.sh
  158. git-add--interactive.perl
  159. git-am.sh
  160. git-archimport.perl
  161. git-bisect.sh
  162. git-compat-util.h
  163. git-cvsexportcommit.perl
  164. git-cvsimport.perl
  165. git-cvsserver.perl
  166. git-filter-branch.sh
  167. git-instaweb.sh
  168. git-lost-found.sh
  169. git-merge-octopus.sh
  170. git-merge-one-file.sh
  171. git-merge-resolve.sh
  172. git-merge-stupid.sh
  173. git-merge.sh
  174. git-mergetool.sh
  175. git-parse-remote.sh
  176. git-pull.sh
  177. git-quiltimport.sh
  178. git-rebase--interactive.sh
  179. git-rebase.sh
  180. git-relink.perl
  181. git-repack.sh
  182. git-request-pull.sh
  183. git-send-email.perl
  184. git-sh-setup.sh
  185. git-stash.sh
  186. git-submodule.sh
  187. git-svn.perl
  188. GIT-VERSION-GEN
  189. git-web--browse.sh
  190. git.c
  191. git.spec.in
  192. graph.c
  193. graph.h
  194. grep.c
  195. grep.h
  196. hash-object.c
  197. hash.c
  198. hash.h
  199. help.c
  200. http-push.c
  201. http-walker.c
  202. http.c
  203. http.h
  204. ident.c
  205. imap-send.c
  206. index-pack.c
  207. INSTALL
  208. interpolate.c
  209. interpolate.h
  210. list-objects.c
  211. list-objects.h
  212. ll-merge.c
  213. ll-merge.h
  214. lockfile.c
  215. log-tree.c
  216. log-tree.h
  217. mailmap.c
  218. mailmap.h
  219. Makefile
  220. match-trees.c
  221. merge-file.c
  222. merge-index.c
  223. merge-recursive.h
  224. merge-tree.c
  225. mktag.c
  226. mktree.c
  227. name-hash.c
  228. object.c
  229. object.h
  230. pack-check.c
  231. pack-redundant.c
  232. pack-revindex.c
  233. pack-revindex.h
  234. pack-write.c
  235. pack.h
  236. pager.c
  237. parse-options.c
  238. parse-options.h
  239. patch-delta.c
  240. patch-id.c
  241. patch-ids.c
  242. patch-ids.h
  243. path-list.c
  244. path-list.h
  245. path.c
  246. pkt-line.c
  247. pkt-line.h
  248. pretty.c
  249. progress.c
  250. progress.h
  251. quote.c
  252. quote.h
  253. reachable.c
  254. reachable.h
  255. read-cache.c
  256. README
  257. receive-pack.c
  258. reflog-walk.c
  259. reflog-walk.h
  260. refs.c
  261. refs.h
  262. remote.c
  263. remote.h
  264. revision.c
  265. revision.h
  266. run-command.c
  267. run-command.h
  268. send-pack.h
  269. server-info.c
  270. setup.c
  271. sha1-lookup.c
  272. sha1-lookup.h
  273. sha1_file.c
  274. sha1_name.c
  275. shallow.c
  276. shell.c
  277. shortlog.h
  278. show-index.c
  279. sideband.c
  280. sideband.h
  281. strbuf.c
  282. strbuf.h
  283. symlinks.c
  284. tag.c
  285. tag.h
  286. tar.h
  287. test-absolute-path.c
  288. test-chmtime.c
  289. test-date.c
  290. test-delta.c
  291. test-genrandom.c
  292. test-match-trees.c
  293. test-parse-options.c
  294. test-sha1.c
  295. test-sha1.sh
  296. thread-utils.c
  297. thread-utils.h
  298. trace.c
  299. transport.c
  300. transport.h
  301. tree-diff.c
  302. tree-walk.c
  303. tree-walk.h
  304. tree.c
  305. tree.h
  306. unpack-file.c
  307. unpack-trees.c
  308. unpack-trees.h
  309. update-server-info.c
  310. upload-pack.c
  311. usage.c
  312. utf8.c
  313. utf8.h
  314. var.c
  315. walker.c
  316. walker.h
  317. write_or_die.c
  318. ws.c
  319. wt-status.c
  320. wt-status.h
  321. xdiff-interface.c
  322. xdiff-interface.h