summaryrefslogtreecommitdiff
path: root/t/t3600-rm.sh
AgeCommit message (Collapse)AuthorFilesLines
2014-03-31tests: don't rely on strerror text when testing rmdir failureLibravatar Charles Bailey1-2/+1
AIX doesn't make a distiction between EEXIST and ENOTEMPTY; relying on the strerror string for the rmdir failure is fragile. Just test that the start of the string matches the Git controlled "failed to rmdir..." error. The exact text of the OS generated error string isn't important to the test. Signed-off-by: Charles Bailey <cbailey32@bloomberg.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-07rm: better document side effects when removing a submoduleLibravatar Jens Lehmann1-0/+16
The "Submodules" section of the "git rm" documentation mentions what will happen when a submodule with a gitfile gets removed with newer git. But it doesn't talk about what happens when the user changes between commits before and after the removal, which does not remove the submodule from the work tree like using the rm command did the first time. Explain what happens and what the user has to do manually to fix that in the new BUGS section. Also document this behavior in a new test. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-30Merge branch 'sg/t3600-nul-sha1-fix'Libravatar Junio C Hamano1-7/+4
* sg/t3600-nul-sha1-fix: t3600: fix broken "choking git rm" test
2013-10-16t3600: fix broken "choking git rm" testLibravatar SZEDER Gábor1-7/+4
The test 'choking "git rm" should not let it die with cruft' is supposed to check 'git rm's behavior when interrupted by provoking a SIGPIPE while 'git rm' is busily deleting files from a specially crafted index. This test is silently broken for the following reasons: - The test crafts a special index by feeding a large number of index entries with null shas to 'git update-index --index-info'. It was OK back then when this test was introduced in commit 0693f9ddad (Make sure lockfiles are unlocked when dying on SIGPIPE, 2008-12-18), but since commit 4337b5856f (do not write null sha1s to on-disk index, 2012-07-28) null shas are not allowed in the on-disk index causing 'git update-index' to error out. - The barfing 'git update-index --index-info' should fail the test, but it remains unnoticed because of the severely broken && chain: the test's result depends solely on whether there is a stale lock file left behind, but after 'git update-index' errors out 'git rm' won't be executed at all. To fix this test feed only non-null shas to 'git update-index' and restore the && chain (partly by adding a missing && and by using the test_when_finished helper instead of manual cleanup). Signed-off-by: SZEDER Gábor <szeder@ira.uka.de> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-08-06rm: delete .gitmodules entry of submodules removed from the work treeLibravatar Jens Lehmann1-6/+92
Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-12rm: introduce advice.rmHints to shorten messagesLibravatar Mathieu Lienard--Mayor1-0/+29
Introduce advice.rmHints to choose whether to display advice or not when git rm fails. Defaults to true, in order to preserve current behavior. As an example, the message: error: 'foo.txt' has changes staged in the index (use --cached to keep the file, or -f to force removal) would look like, with advice.rmHints=false: error: 'foo.txt' has changes staged in the index Signed-off-by: Mathieu Lienard--Mayor <Mathieu.Lienard--Mayor@ensimag.imag.fr> Signed-off-by: Jorge Juan Garcia Garcia <Jorge-Juan.Garcia-Garcia@ensimag.imag.fr> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-12rm: better error message on failure for multiple filesLibravatar Mathieu Lienard--Mayor1-0/+67
When 'git rm' fails, it now displays a single message with the list of files involved, instead of displaying a list of messages with one file each. As an example, the old message: error: 'foo.txt' has changes staged in the index (use --cached to keep the file, or -f to force removal) error: 'bar.txt' has changes staged in the index (use --cached to keep the file, or -f to force removal) would now be displayed as: error: the following files have changes staged in the index: foo.txt bar.txt (use --cached to keep the file, or -f to force removal) Signed-off-by: Mathieu Lienard--Mayor <Mathieu.Lienard--Mayor@ensimag.imag.fr> Signed-off-by: Jorge Juan Garcia Garcia <Jorge-Juan.Garcia-Garcia@ensimag.imag.fr> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-04t3600: document failure of rm across symbolic linksLibravatar Jeff King1-0/+28
If we have a symlink "d" that points to a directory, we should not be able to remove "d/f". In the normal case, where "d/f" does not exist in the index, we already disallow this, as we only remove things that git knows about in the index. So for something like: ln -s /outside/repo foo git add foo git rm foo/bar we will properly produce an error (as there is no index entry for foo/bar). However, if there is an index entry for the path (e.g., because the movement is due to working tree changes that have not yet been reflected in the index), we will happily delete it, even though the path we delete from the filesystem is not the same as the path in the index. This patch documents that failure with a test. While this is a bug, it should not be possible to cause serious data loss with it. For any path that does not have an index entry, we will complain and bail. For a path which does have an index entry, we will do the usual up-to-date content check. So even if the deleted path in the filesystem is not the same as the one we are removing from the index, we do know that they at least have the same content, and that the content is included in HEAD. That means the worst case is not the accidental loss of content, but rather confusion by the user when a copy of a file another part of the tree is removed. Which makes this bug a minor and hard-to-trigger annoyance rather than a data-loss bug (and hence the fix can be saved for a rainy day when somebody feels like working on it). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-04t3600: test behavior of reverse-d/f conflictLibravatar Jeff King1-0/+12
The previous commit taught "rm" that it is safe to consider "d/f" removed when "d" has become a non-directory. This patch adds a test for the opposite: a file "d" that becomes a directory. In this case, "git rm" does need to complain, because we should not be removing arbitrary content under "d". Git already behaves correctly, but let's make sure that remains the case by protecting the behavior with a test. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-04rm: do not complain about d/f conflicts during deletionLibravatar Jeff King1-0/+25
If we used to have an index entry "d/f", but "d" has been replaced by a non-directory entry, the user may still want to run "git rm" to delete the stale index entry. They could use "git rm --cached" to just touch the index, but "git rm" should also work: we explicitly try to handle the case that the file has already been removed from the working tree. However, because unlinking "d/f" in this case will not yield ENOENT, but rather ENOTDIR, we do not notice that the file is already gone. Instead, we report it as an error. The simple solution is to treat ENOTDIR in this case exactly like ENOENT; all we want to know is whether the file is already gone, and if a leading path is no longer a directory, then by definition the sub-path is gone. Reported-by: jpinheiro <7jpinheiro@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-19t3600: Avoid "cp -a", which is a GNUismLibravatar Junio C Hamano1-3/+3
With d4a7ffa (tests: "cp -a" is a GNUism, 2012-10-08), we got rid of most of them, but the ones in a topic that was still in flight were missed. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-11-23Teach rm to remove submodules when given with a trailing '/'Libravatar Jens Lehmann1-0/+17
Doing a "git rm submod/" on a submodule results in an error: fatal: pathspec 'submod/' did not match any files This is really inconvenient as e.g. using TAB completion in a shell on a submodule automatically adds the trailing '/' when it completes the path of the submodule directory. The user has then to remove the '/' herself to make a "git rm" succeed. Doing a "git rm -r somedir/" is working fine, so there is no reason why that shouldn't work for submodules too. Teach git rm to not error out when a '/' is appended to the path of a submodule. Achieve this by chopping off trailing slashes from the path names given if they represent directories. Add tests to make sure that logic only applies to directories and not to files. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-09-29submodule: teach rm to remove submodules unless they contain a git directoryLibravatar Jens Lehmann1-0/+343
Currently using "git rm" on a submodule - populated or not - fails with this error: fatal: git rm: '<submodule path>': Is a directory This made sense in the past as there was no way to remove a submodule without possibly removing unpushed parts of the submodule's history contained in its .git directory too, so erroring out here protected the user from possible loss of data. But submodules cloned with a recent git version do not contain the .git directory anymore, they use a gitfile to point to their git directory which is safely stored inside the superproject's .git directory. The work tree of these submodules can safely be removed without losing history, so let's teach git to do so. Using rm on an unpopulated submodule now removes the empty directory from the work tree and the gitlink from the index. If the submodule's directory is missing from the work tree, it will still be removed from the index. Using rm on a populated submodule using a gitfile will apply the usual checks for work tree modification adapted to submodules (unless forced). For a submodule that means that the HEAD is the same as recorded in the index, no tracked files are modified and no untracked files that aren't ignored are present in the submodules work tree (ignored files are deemed expendable and won't stop a submodule's work tree from being removed). That logic has to be applied in all nested submodules too. Using rm on a submodule which has its .git directory inside the work trees top level directory will just error out like it did before to protect the repository, even when forced. In the future git could either provide a message informing the user to convert the submodule to use a gitfile or even attempt to do the conversion itself, but that is not part of this change. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-06Merge branch 'jc/fix-diff-files-unmerged'Libravatar Junio C Hamano1-2/+1
* jc/fix-diff-files-unmerged: diff-files: show unmerged entries correctly diff: remove often unused parameters from diff_unmerge() diff.c: return filepair from diff_unmerge() test: use $_z40 from test-lib
2011-04-23test: use $_z40 from test-libLibravatar Junio C Hamano1-2/+1
There is no need to duplicate the definition of $_z40 and $_x40 that test-lib.sh supplies the test scripts. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-12-14t3600-rm.sh: Don't pass a non-existent prereq to test #15Libravatar Ramsay Jones1-1/+1
Commit c91cfd19 (tests: A SANITY test prereq for testing if we're root, 2010-08-06) introduced a SANITY prerequisite which had very similar semantics to RO_DIR. That commit removed the code to set RO_DIR, but forgot to replace RO_DIR with SANITY in test #15. In order not to skip test 15 unnecessarily, since RO_DIR will never be set, we pass the SANITY prerequisite instead. Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-08-18tests: A SANITY test prereq for testing if we're rootLibravatar Ævar Arnfjörð Bjarmason1-16/+0
Some tests depend on not being able to write to files after chmod -w. This doesn't work when running the tests as root. Change test-lib.sh to test if this works, and if so it sets a new SANITY test prerequisite. The tests that use this previously failed when run under root. There was already a test for this in t3600-rm.sh, added by Junio C Hamano in 2283645 in 2006. That check now uses the new SANITY prerequisite. Some of this was resurrected from the "Tests in Cygwin" thread in May 2009: http://thread.gmane.org/gmane.comp.version-control.git/116729/focus=118385 Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-25tests: Skip tests in a way that makes sense under TAPLibravatar Ævar Arnfjörð Bjarmason1-1/+1
SKIP messages are now part of the TAP plan. A TAP harness now knows why a particular test was skipped and can report that information. The non-TAP harness built into Git's test-lib did nothing special with these messages, and is unaffected by these changes. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-02-18rm: fix bug in recursive subdirectory removalLibravatar Jeff King1-0/+8
If we remove a path in a/deep/subdirectory, we should try to remove as many trailing components as possible (i.e., subdirectory, then deep, then a). However, the test for the return value of rmdir was reversed, so we only ever deleted at most one level. The fix is in remove_path, so "apply" and "merge-recursive" also are fixed. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-22t3600: Use test prerequisite tagsLibravatar Johannes Sixt1-28/+30
There are two prerequisites: - The filesystem supports names with tabs or new-lines. - Files cannot be removed if their containing directory is read-only. Previously, whether these preconditions are satisified was tested inside test_expect_success. We move these tests outside because, strictly speaking, they are not part of the tests. Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2009-03-19Call 'say' outside test_expect_successLibravatar Johannes Sixt1-1/+2
There were some uses of 'say' inside test_expect_success. But if the tests were not run in verbose mode, this message went to /dev/null. Pull them out of test_expect_success. Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2009-03-19test suite: Use 'say' to say something instead of 'test_expect_success'Libravatar Johannes Sixt1-1/+1
Some tests report that some tests will be skipped. They used 'test_expect_success' with a trivially successful test. Nowadays we have the helper function 'say' for this purpose. In on case, 'say_color skip' is replaced by 'say' because the former is not intended as a public API. Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2008-12-21Make sure lockfiles are unlocked when dying on SIGPIPELibravatar Junio C Hamano1-0/+17
We cleaned up lockfiles upon receiving the usual suspects HUP, TERM, QUIT but a wicked user could kill us of asphyxiation by piping our output to a pipe that does not read. Protect ourselves by catching SIGPIPE and clean up the lockfiles as well in such a case. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-28git add --intent-to-add: fix removal of cached emptinessLibravatar Junio C Hamano1-2/+2
This uses the extended index flag mechanism introduced earlier to mark the entries added to the index via "git add -N" with CE_INTENT_TO_ADD. The logic to detect an "intent to add" entry for the purpose of allowing "git rm --cached $path" is tightened to check not just for a staged empty blob, but with the CE_INTENT_TO_ADD bit. This protects an empty blob that was explicitly added and then modified in the work tree from being dropped with this sequence: $ >empty $ git add empty $ echo "non empty" >empty $ git rm --cached empty Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-22rm: loosen safety valve for empty filesLibravatar Jeff King1-0/+13
If a file is different between the working tree copy, the index, and the HEAD, then we do not allow it to be deleted without --force. However, this is overly tight in the face of "git add --intent-to-add": $ git add --intent-to-add file $ : oops, I don't actually want to stage that yet $ git rm --cached file error: 'empty' has staged content different from both the file and the HEAD (use -f to force removal) $ git rm -f --cached file Unfortunately, there is currently no way to distinguish between an empty file that has been added and an "intent to add" file. The ideal behavior would be to disallow the former while allowing the latter. This patch loosens the safety valve to allow the deletion only if we are deleting the cached entry and the cached content is empty. This covers the intent-to-add situation, and assumes there is little harm in not protecting users who have legitimately added an empty file. In many cases, the file will still be empty, in which case the safety valve does not trigger anyway (since the content remains untouched in the working tree). Otherwise, we do remove the fact that no content was staged, but given that the content is by definition empty, it is not terribly difficult for a user to recreate it. However, we still document the desired behavior in the form of two tests. One checks the correct removal of an intent-to-add file. The other checks that we still disallow removal of empty files, but is marked as expect_failure to indicate this compromise. If the intent-to-add feature is ever extended to differentiate between normal empty files and intent-to-add files, then the safety valve can be re-tightened. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-08git rm: refresh index before up-to-date checkLibravatar Johannes Schindelin1-8/+17
Since "git rm" is supposed to be porcelain, we should convince it to be user friendly by refreshing the index itself. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2008-09-03tests: use "git xyzzy" form (t3600 - t6999)Libravatar Nanako Shiraishi1-2/+2
Converts tests between t3600-t6300. Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-19Merge branch 'maint'Libravatar Junio C Hamano1-0/+12
* maint: GIT 1.5.6.4 builtin-rm: fix index lock file path http-fetch: do not SEGV after fetching a bad pack idx file rev-list: honor --quiet option api-run-command.txt: typofix
2008-07-19builtin-rm: fix index lock file pathLibravatar Olivier Marin1-0/+12
When hold_locked_index() is called with a relative git_dir and you are outside the work tree, the lock file become relative to the current directory. So when later setup_work_tree() change the current directory it breaks lock file path and commit_locked_index() fails. This patch move index locking code after setup_work_tree() call to make lock file relative to the working tree as it should be and add a test case. Noticed by Nick Andrew. Signed-off-by: Olivier Marin <dkr@freesurf.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-07-13t/: Use "test_must_fail git" instead of "! git"Libravatar Stephan Beyer1-13/+13
This patch changes every occurrence of "! git" -- with the meaning that a git call has to gracefully fail -- into "test_must_fail git". This is useful to - make sure the test does not fail because of a signal, e.g. SIGSEGV, and - advertise the use of "test_must_fail" for new tests. Signed-off-by: Stephan Beyer <s-beyer@gmx.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-01Sane use of test_expect_failureLibravatar Junio C Hamano1-8/+9
Originally, test_expect_failure was designed to be the opposite of test_expect_success, but this was a bad decision. Most tests run a series of commands that leads to the single command that needs to be tested, like this: test_expect_{success,failure} 'test title' ' setup1 && setup2 && setup3 && what is to be tested ' And expecting a failure exit from the whole sequence misses the point of writing tests. Your setup$N that are supposed to succeed may have failed without even reaching what you are trying to test. The only valid use of test_expect_failure is to check a trivial single command that is expected to fail, which is a minority in tests of Porcelain-ish commands. This large-ish patch rewrites all uses of test_expect_failure to use test_expect_success and rewrites the condition of what is tested, like this: test_expect_success 'test title' ' setup1 && setup2 && setup3 && ! this command should fail ' test_expect_failure is redefined to serve as a reminder that that test *should* succeed but due to a known breakage in git it currently does not pass. So if git-foo command should create a file 'bar' but you discovered a bug that it doesn't, you can write a test like this: test_expect_failure 'git-foo should create bar' ' rm -f bar && git foo && test -f bar ' This construct acts similar to test_expect_success, but instead of reporting "ok/FAIL" like test_expect_success does, the outcome is reported as "FIXED/still broken". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-05t/t{3600,3800,5401}: do not use egrep when grep would doLibravatar Junio C Hamano1-1/+1
There is nothing _wrong_ with egrep per se, but this way we would have less dependency on external tools. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-13More permissive "git-rm --cached" behavior without -f.Libravatar Matthieu Moy1-0/+34
In the previous behavior, "git-rm --cached" (without -f) had the same restriction as "git-rm". This forced the user to use the -f flag in situations which weren't actually dangerous, like: $ git add foo # oops, I didn't want this $ git rm --cached foo # back to initial situation Previously, the index had to match the file *and* the HEAD. With --cached, the index must now match the file *or* the HEAD. The behavior without --cached is unchanged, but provides better error messages. Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-02Rewrite "git-frotz" to "git frotz"Libravatar Junio C Hamano1-24/+24
This uses the remove-dashes target to replace "git-frotz" to "git frotz". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-04-17Add --ignore-unmatch option to exit with zero status when no files are removed.Libravatar Steven Grimm1-0/+4
Signed-off-by: Steven Grimm <koreth@midwinter.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-16Add --quiet option to suppress output of "rm" commands for removed files.Libravatar Steven Grimm1-0/+24
Signed-off-by: Steven Grimm <koreth@midwinter.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-12-25t3600: update the test for updated git rmLibravatar Junio C Hamano1-4/+74
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-05-29Remove unnecessary output from t3600-rm.Libravatar Shawn Pearce1-19/+23
Moved the setup commands into test_expect_success blocks so their output is hidden unless -v is used. This makes the test suite look a little cleaner when the rm test-file setup step fails (and was expected to fail for most cases). Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-13t3600-rm: skip failed-remove test when we cannot make an unremovable file.Libravatar Junio C Hamano1-3/+15
When running t3600-rm test under fakeroot (or as root), we cannot make a file unremovable with "chmod a-w .". Detect this case early and skip that test. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-03-03workaround fat/ntfs deficiencies for t3600-rm.sh (git-rm)Libravatar Alex Riesen1-6/+17
Signed-off-by: Alex Riesen <ariesen@harmanbecker.com> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-22git-rm: Fix to properly handle files with spaces, tabs, newlines, etc.Libravatar Carl Worth1-17/+35
New tests are added to the git-rm test case to cover this as well. Signed-off-by: Carl Worth <cworth@cworth.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-02-22Add new git-rm command with documentationLibravatar Carl Worth1-0/+42
This adds a git-rm command which provides convenience similar to git-add, (and a bit more since it takes care of the rm as well if given -f). Like git-add, git-rm expands the given path names through git-ls-files. This means it only acts on files listed in the index. And it does act recursively on directories by default, (no -r needed as in the case of rm itself). When it recurses, it does not remove empty directories that are left behind. Signed-off-by: Junio C Hamano <junkio@cox.net>