@@ -6,6 +6,7 @@ const assert = require('assert');
66const fs = require ( 'fs' ) ;
77const path = require ( 'path' ) ;
88const { pathToFileURL } = require ( 'url' ) ;
9+ const { execSync } = require ( 'child_process' ) ;
910
1011const { validateRmOptionsSync } = require ( 'internal/fs/utils' ) ;
1112
@@ -15,6 +16,15 @@ let count = 0;
1516const nextDirPath = ( name = 'rm' ) =>
1617 path . join ( tmpdir . path , `${ name } -${ count ++ } ` ) ;
1718
19+ const isGitPresent = ( ( ) => {
20+ try { execSync ( 'git --version' ) ; return true ; } catch { return false ; }
21+ } ) ( ) ;
22+
23+ function gitInit ( gitDirectory ) {
24+ fs . mkdirSync ( gitDirectory ) ;
25+ execSync ( 'git init' , { cwd : gitDirectory } ) ;
26+ }
27+
1828function makeNonEmptyDirectory ( depth , files , folders , dirname , createSymLinks ) {
1929 fs . mkdirSync ( dirname , { recursive : true } ) ;
2030 fs . writeFileSync ( path . join ( dirname , 'text.txt' ) , 'hello' , 'utf8' ) ;
@@ -129,6 +139,16 @@ function removeAsync(dir) {
129139 } ) ) ;
130140}
131141
142+ // Removing a .git directory should not throw an EPERM.
143+ // Refs: https://github.com/isaacs/rimraf/issues/21.
144+ if ( isGitPresent ) {
145+ const gitDirectory = nextDirPath ( ) ;
146+ gitInit ( gitDirectory ) ;
147+ fs . rm ( gitDirectory , { recursive : true } , common . mustSucceed ( ( ) => {
148+ assert . strictEqual ( fs . existsSync ( gitDirectory ) , false ) ;
149+ } ) ) ;
150+ }
151+
132152// Test the synchronous version.
133153{
134154 const dir = nextDirPath ( ) ;
@@ -178,6 +198,15 @@ function removeAsync(dir) {
178198 assert . throws ( ( ) => fs . rmSync ( dir ) , { syscall : 'stat' } ) ;
179199}
180200
201+ // Removing a .git directory should not throw an EPERM.
202+ // Refs: https://github.com/isaacs/rimraf/issues/21.
203+ if ( isGitPresent ) {
204+ const gitDirectory = nextDirPath ( ) ;
205+ gitInit ( gitDirectory ) ;
206+ fs . rmSync ( gitDirectory , { recursive : true } ) ;
207+ assert . strictEqual ( fs . existsSync ( gitDirectory ) , false ) ;
208+ }
209+
181210// Test the Promises based version.
182211( async ( ) => {
183212 const dir = nextDirPath ( ) ;
@@ -229,6 +258,17 @@ function removeAsync(dir) {
229258 }
230259} ) ( ) . then ( common . mustCall ( ) ) ;
231260
261+ // Removing a .git directory should not throw an EPERM.
262+ // Refs: https://github.com/isaacs/rimraf/issues/21.
263+ if ( isGitPresent ) {
264+ ( async ( ) => {
265+ const gitDirectory = nextDirPath ( ) ;
266+ gitInit ( gitDirectory ) ;
267+ await fs . promises . rm ( gitDirectory , { recursive : true } ) ;
268+ assert . strictEqual ( fs . existsSync ( gitDirectory ) , false ) ;
269+ } ) ( ) . then ( common . mustCall ( ) ) ;
270+ }
271+
232272// Test input validation.
233273{
234274 const dir = nextDirPath ( ) ;
0 commit comments