@@ -453,6 +453,36 @@ func (v *RepoWorkSpace) UpdateProjectList(submodulesOK bool) ([]string, error) {
453453 return remains , nil
454454}
455455
456+ // ShortGitObjectsDir is relative path of shared objects gitdir
457+ func (v * RepoWorkSpace ) ShortGitObjectsDir (name string ) string {
458+ if name == "" {
459+ return ""
460+ }
461+ if v .IsMirror () {
462+ return name + ".git"
463+ }
464+ return filepath .Join (
465+ config .DotRepo ,
466+ config .ProjectObjects ,
467+ name + ".git" ,
468+ )
469+ }
470+
471+ // ShortGitDir is relative path of gitdir
472+ func (v * RepoWorkSpace ) ShortGitDir (pathName string ) string {
473+ if pathName == "" {
474+ return ""
475+ }
476+ if v .IsMirror () {
477+ return ""
478+ }
479+ return filepath .Join (
480+ config .DotRepo ,
481+ config .Projects ,
482+ pathName + ".git" ,
483+ )
484+ }
485+
456486func (v * RepoWorkSpace ) removeObsoletePaths (oldPaths , newPaths []string ) ([]string , error ) {
457487 var (
458488 remains []string = []string {}
@@ -462,37 +492,62 @@ func (v *RepoWorkSpace) removeObsoletePaths(oldPaths, newPaths []string) ([]stri
462492
463493 obsoletePaths := findObsoletePaths (oldPaths , newPaths )
464494
465- for _ , p := range obsoletePaths {
466- workdir := filepath .Clean (filepath .Join (v .RootDir , p ))
467- gitdir := filepath .Join (workdir , ".git" )
495+ for _ , obsoletePath := range obsoletePaths {
496+ var workdirAbs , gitdir , gitdirAbs string
497+
498+ p := filepath .Clean (obsoletePath )
499+ if p == "" || p == "." || p == ".." ||
500+ strings .HasPrefix (p , "./" ) || strings .HasPrefix (p , "../" ) {
501+ errMsgs = append (errMsgs , fmt .Sprintf ("bad project path '%s', ignored" , obsoletePath ))
502+ continue
503+ }
504+ workdirAbs = filepath .Clean (filepath .Join (v .RootDir , p ))
505+ gitdir = v .ShortGitDir (p )
506+ if gitdir != "" {
507+ gitdirAbs = filepath .Clean (filepath .Join (v .RootDir , gitdir ))
508+ }
468509 /*
469510 workRepoPath := filepath.Clean(filepath.Join(v.RootDir,
470511 config.DotRepo,
471512 config.Projects,
472513 p+".git"))
473514 */
474515
475- // Obsolete path does not exist, ignore it.
476- if _ , err := os .Stat (workdir ); err != nil {
516+ if ! strings .HasPrefix (workdirAbs , v .RootDir ) {
517+ // Ignore bad path, and do not update remains.
518+ errMsgs = append (errMsgs ,
519+ fmt .Sprintf ("project '%s', which beyond repo root '%s', ignored" ,
520+ p , v .RootDir ))
521+ continue
522+ }
523+ if strings .TrimPrefix (workdirAbs , v .RootDir ) == "" {
477524 continue
478525 }
479526
480- if ! strings .HasPrefix (workdir , v .RootDir ) {
481- // Ignore bad path, and do not update remains.
482- errMsgs = append (errMsgs ,
483- fmt .Sprintf ("cannot delete project path '%s', which beyond repo root '%s'" ,
484- workdir , v .RootDir ))
527+ // Obsolete path does not exist, ignore it.
528+ if ! path .Exist (workdirAbs ) {
529+ // Remove gitdirAbs if exists
530+ if gitdirAbs != "" && path .Exist (gitdirAbs ) {
531+ err = os .RemoveAll (gitdirAbs )
532+ if err != nil {
533+ remains = append (remains , p )
534+ errMsgs = append (errMsgs , fmt .Sprintf ("fail to remove '%s': %s" , gitdir , err ))
535+ } else {
536+ v .removeEmptyDirs (gitdirAbs )
537+ }
538+ }
485539 continue
486540 }
487541
488- if _ , err := os .Stat (gitdir ); err != nil {
542+ // workdirAbs is not a git workdir
543+ if ! path .Exist (filepath .Join (workdirAbs , ".git" )) {
489544 remains = append (remains , p )
490545 errMsgs = append (errMsgs ,
491- fmt .Sprintf ("cannot find gitdir '%s' when removing obsolete path " , gitdir ))
546+ fmt .Sprintf ("obsolete path '%s' does not seem like a git worktree " , p ))
492547 continue
493548 }
494549
495- if ok , _ := project .IsClean (workdir ); ! ok {
550+ if ok , _ := project .IsClean (workdirAbs ); ! ok {
496551 remains = append (remains , p )
497552 errMsgs = append (errMsgs ,
498553 fmt .Sprintf (`cannot remove project "%s": uncommitted changes are present.
@@ -513,32 +568,14 @@ Please commit changes, upload then run sync again`,
513568 continue
514569
515570 /*
516- // Remove gitdir first
517- err = os.RemoveAll(gitdir)
518- if err != nil {
519- return fmt.Errorf("fail to remove '%s': %s",
520- gitdir,
521- err)
522- }
523-
524571 // Remove worktree, except recursive git repositories
525572 ignoreRepos := findGitWorktree(workdir)
526573 err = removeWorktree(workdir, ignoreRepos)
527574 if err != nil {
528- return fmt.Errorf("fail to remove '%s': %s", workdir, err)
529- }
530- v.removeEmptyDirs(workdir)
531-
532- // Remove project repository
533- if _, err = os.Stat(workRepoPath); err != nil {
534- if !strings.HasPrefix(workRepoPath, v.RootDir) {
535- return fmt.Errorf("cannot delete project repo '%s', which beyond repo root '%s'", workRepoPath, v.RootDir)
536- }
537- err = os.RemoveAll(workRepoPath)
538- if err != nil {
539- return err
540- }
541- v.removeEmptyDirs(workRepoPath)
575+ remains = append(remains, p)
576+ errMsgs = append(errMsgs, fmt.Sprintf("fail to remove '%s': %s", workdir, err))
577+ } else {
578+ v.removeEmptyDirs(workdir)
542579 }
543580 */
544581 }
0 commit comments