@@ -258,3 +258,96 @@ func TestGitVolume_Unsync_RelativeLink(t *testing.T) {
258258 _ , err = os .Lstat (linkPath )
259259 assert .True (t , os .IsNotExist (err ), "Relative link should be correctly identified and removed" )
260260}
261+
262+ func TestGitVolume_Unsync_CopyDirectory (t * testing.T ) {
263+ sourceDir , targetDir , cleanup := setupTestEnv (t )
264+ defer cleanup ()
265+
266+ // Create source directory with files
267+ configDir := filepath .Join (sourceDir , "config" )
268+ require .NoError (t , os .MkdirAll (configDir , 0755 ))
269+ require .NoError (t , os .WriteFile (filepath .Join (configDir , "app.env" ), []byte ("A=1" ), 0644 ))
270+ require .NoError (t , os .WriteFile (filepath .Join (configDir , "db.env" ), []byte ("B=2" ), 0644 ))
271+
272+ volumes := []Volume {
273+ {Source : "config" , Target : "config" , Mode : ModeCopy },
274+ }
275+ gv := createTestGitVolume (sourceDir , targetDir , "" , volumes )
276+
277+ // Sync
278+ require .NoError (t , gv .Sync (SyncOptions {}))
279+
280+ // Verify synced
281+ targetConfig := filepath .Join (targetDir , "config" )
282+ _ , err := os .Stat (filepath .Join (targetConfig , "app.env" ))
283+ require .NoError (t , err , "app.env should exist after sync" )
284+ _ , err = os .Stat (filepath .Join (targetConfig , "db.env" ))
285+ require .NoError (t , err , "db.env should exist after sync" )
286+
287+ // Unsync
288+ require .NoError (t , gv .Unsync (UnsyncOptions {}))
289+
290+ // Verify directory is completely removed
291+ _ , err = os .Stat (targetConfig )
292+ assert .True (t , os .IsNotExist (err ), "config directory should be removed after unsync" )
293+ }
294+
295+ func TestGitVolume_Unsync_CopyDirectory_Modified (t * testing.T ) {
296+ sourceDir , targetDir , cleanup := setupTestEnv (t )
297+ defer cleanup ()
298+
299+ // Create source directory
300+ configDir := filepath .Join (sourceDir , "config" )
301+ require .NoError (t , os .MkdirAll (configDir , 0755 ))
302+ require .NoError (t , os .WriteFile (filepath .Join (configDir , "app.env" ), []byte ("A=1" ), 0644 ))
303+
304+ volumes := []Volume {
305+ {Source : "config" , Target : "config" , Mode : ModeCopy },
306+ }
307+ gv := createTestGitVolume (sourceDir , targetDir , "" , volumes )
308+
309+ // Sync
310+ require .NoError (t , gv .Sync (SyncOptions {}))
311+
312+ // Modify a file inside the copied directory
313+ modifiedPath := filepath .Join (targetDir , "config" , "app.env" )
314+ require .NoError (t , os .WriteFile (modifiedPath , []byte ("MODIFIED" ), 0644 ))
315+
316+ // Unsync
317+ require .NoError (t , gv .Unsync (UnsyncOptions {}))
318+
319+ // Verify directory was preserved (hash mismatch → skip)
320+ _ , err := os .Stat (filepath .Join (targetDir , "config" ))
321+ assert .NoError (t , err , "Modified config directory should NOT be removed" )
322+
323+ data , _ := os .ReadFile (modifiedPath )
324+ assert .Equal (t , "MODIFIED" , string (data ), "Modified file content should be preserved" )
325+ }
326+
327+ func TestGitVolume_Unsync_CopyDirectory_MissingSource (t * testing.T ) {
328+ sourceDir , targetDir , cleanup := setupTestEnv (t )
329+ defer cleanup ()
330+
331+ // Create source directory
332+ configDir := filepath .Join (sourceDir , "config" )
333+ require .NoError (t , os .MkdirAll (configDir , 0755 ))
334+ require .NoError (t , os .WriteFile (filepath .Join (configDir , "app.env" ), []byte ("A=1" ), 0644 ))
335+
336+ volumes := []Volume {
337+ {Source : "config" , Target : "config" , Mode : ModeCopy },
338+ }
339+ gv := createTestGitVolume (sourceDir , targetDir , "" , volumes )
340+
341+ // Sync
342+ require .NoError (t , gv .Sync (SyncOptions {}))
343+
344+ // Delete source directory
345+ require .NoError (t , os .RemoveAll (configDir ))
346+
347+ // Unsync
348+ require .NoError (t , gv .Unsync (UnsyncOptions {}))
349+
350+ // Verify target directory was NOT removed (source missing → safe skip)
351+ _ , err := os .Stat (filepath .Join (targetDir , "config" ))
352+ assert .NoError (t , err , "Config directory should NOT be removed if source is missing" )
353+ }
0 commit comments