Add builtin "git rm" command

This changes semantics very subtly, because it adds a new atomicity
guarantee.

In particular, if you "git rm" several files, it will now do all or
nothing. The old shell-script really looped over the removed files one by
one, and would basically randomly fail in the middle if "-f" was used and
one of the files didn't exist in the working directory.

This C builtin one will not re-write the index after each remove, but
instead remove all files at once. However, that means that if "-f" is used
(to also force removal of the file from the working directory), and some
files have already been removed from the workspace, it won't stop in the
middle in some half-way state like the old one did.

So what happens is that if the _first_ file fails to be removed with "-f",
we abort the whole "git rm". But once we've started removing, we don't
leave anything half done. If some of the other files don't exist, we'll
just ignore errors of removal from the working tree.

This is only an issue with "-f", of course.

I think the new behaviour is strictly an improvement, but perhaps more
importantly, it is _different_. As a special case, the semantics are
identical for the single-file case (which is the only one our test-suite
seems to test).

The other question is what to do with leading directories. The old "git
rm" script didn't do anything, which is somewhat inconsistent. This one
will actually clean up directories that have become empty as a result of
removing the last file, but maybe we want to have a flag to decide the
behaviour?

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
5 files changed
tree: 86607447958a0f032a4a26a37effbda03b4d6d8a
  1. arm/
  2. compat/
  3. contrib/
  4. Documentation/
  5. mozilla-sha1/
  6. ppc/
  7. t/
  8. templates/
  9. xdiff/
  10. .gitignore
  11. apply.c
  12. base85.c
  13. blame.c
  14. blob.c
  15. blob.h
  16. builtin-add.c
  17. builtin-count.c
  18. builtin-diff.c
  19. builtin-grep.c
  20. builtin-help.c
  21. builtin-log.c
  22. builtin-push.c
  23. builtin-rm.c
  24. builtin.h
  25. cache.h
  26. cat-file.c
  27. check-ref-format.c
  28. checkout-index.c
  29. clone-pack.c
  30. combine-diff.c
  31. commit-tree.c
  32. commit.c
  33. commit.h
  34. config.c
  35. connect.c
  36. convert-objects.c
  37. copy.c
  38. COPYING
  39. csum-file.c
  40. csum-file.h
  41. ctype.c
  42. daemon.c
  43. date.c
  44. delta.h
  45. describe.c
  46. diff-delta.c
  47. diff-files.c
  48. diff-index.c
  49. diff-lib.c
  50. diff-stages.c
  51. diff-tree.c
  52. diff.c
  53. diff.h
  54. diffcore-break.c
  55. diffcore-delta.c
  56. diffcore-order.c
  57. diffcore-pickaxe.c
  58. diffcore-rename.c
  59. diffcore.h
  60. dir.c
  61. dir.h
  62. entry.c
  63. environment.c
  64. exec_cmd.c
  65. exec_cmd.h
  66. fetch-clone.c
  67. fetch-pack.c
  68. fetch.c
  69. fetch.h
  70. fsck-objects.c
  71. generate-cmdlist.sh
  72. get-tar-commit-id.c
  73. git-am.sh
  74. git-annotate.perl
  75. git-applymbox.sh
  76. git-applypatch.sh
  77. git-archimport.perl
  78. git-bisect.sh
  79. git-branch.sh
  80. git-checkout.sh
  81. git-cherry.sh
  82. git-clean.sh
  83. git-clone.sh
  84. git-commit.sh
  85. git-compat-util.h
  86. git-cvsexportcommit.perl
  87. git-cvsimport.perl
  88. git-cvsserver.perl
  89. git-fetch.sh
  90. git-fmt-merge-msg.perl
  91. git-format-patch.sh
  92. git-lost-found.sh
  93. git-ls-remote.sh
  94. git-merge-octopus.sh
  95. git-merge-one-file.sh
  96. git-merge-ours.sh
  97. git-merge-recursive.py
  98. git-merge-resolve.sh
  99. git-merge-stupid.sh
  100. git-merge.sh
  101. git-mv.perl
  102. git-parse-remote.sh
  103. git-prune.sh
  104. git-pull.sh
  105. git-push.sh
  106. git-rebase.sh
  107. git-relink.perl
  108. git-repack.sh
  109. git-request-pull.sh
  110. git-rerere.perl
  111. git-reset.sh
  112. git-resolve.sh
  113. git-revert.sh
  114. git-send-email.perl
  115. git-sh-setup.sh
  116. git-shortlog.perl
  117. git-svnimport.perl
  118. git-tag.sh
  119. git-verify-tag.sh
  120. GIT-VERSION-GEN
  121. git.c
  122. git.spec.in
  123. gitk
  124. gitMergeCommon.py
  125. hash-object.c
  126. http-fetch.c
  127. http-push.c
  128. http.c
  129. http.h
  130. ident.c
  131. imap-send.c
  132. index-pack.c
  133. index.c
  134. init-db.c
  135. INSTALL
  136. local-fetch.c
  137. log-tree.c
  138. log-tree.h
  139. ls-files.c
  140. ls-tree.c
  141. mailinfo.c
  142. mailsplit.c
  143. Makefile
  144. merge-base.c
  145. merge-index.c
  146. merge-tree.c
  147. mktag.c
  148. mktree.c
  149. name-rev.c
  150. object.c
  151. object.h
  152. pack-check.c
  153. pack-objects.c
  154. pack-redundant.c
  155. pack.h
  156. pager.c
  157. patch-delta.c
  158. patch-id.c
  159. path.c
  160. peek-remote.c
  161. pkt-line.c
  162. pkt-line.h
  163. prune-packed.c
  164. quote.c
  165. quote.h
  166. read-cache.c
  167. read-tree.c
  168. README
  169. receive-pack.c
  170. refs.c
  171. refs.h
  172. repo-config.c
  173. rev-list.c
  174. rev-parse.c
  175. revision.c
  176. revision.h
  177. rsh.c
  178. rsh.h
  179. run-command.c
  180. run-command.h
  181. send-pack.c
  182. server-info.c
  183. setup.c
  184. sha1_file.c
  185. sha1_name.c
  186. shell.c
  187. show-branch.c
  188. show-index.c
  189. ssh-fetch.c
  190. ssh-pull.c
  191. ssh-push.c
  192. ssh-upload.c
  193. strbuf.c
  194. strbuf.h
  195. stripspace.c
  196. symbolic-ref.c
  197. tag.c
  198. tag.h
  199. tar-tree.c
  200. tar.h
  201. test-date.c
  202. test-delta.c
  203. tree-diff.c
  204. tree-walk.c
  205. tree-walk.h
  206. tree.c
  207. tree.h
  208. unpack-file.c
  209. unpack-objects.c
  210. update-index.c
  211. update-ref.c
  212. update-server-info.c
  213. upload-pack.c
  214. usage.c
  215. var.c
  216. verify-pack.c
  217. write-tree.c
  218. xdiff-interface.c
  219. xdiff-interface.h