github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/gitCmd/GitFixNameCase.go (about)

     1  package gitCmd
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/bronze1man/kmg/kmgConsole"
    11  	"github.com/bronze1man/kmg/third/kmgGit"
    12  )
    13  
    14  func init() {
    15  	kmgConsole.AddAction(kmgConsole.Command{
    16  		Name:   "GitFixNameCase",
    17  		Desc:   "fix git name case problem on case insensitive opearate system(windows,osx)",
    18  		Runner: gitFixNameCaseCmd,
    19  	})
    20  }
    21  
    22  func gitFixNameCaseCmd() {
    23  	//检查index里面的文件名大小写和当前的文件名大小写是否一致
    24  	var basePath string
    25  	var err error
    26  	flag.StringVar(&basePath, "p", "", "base path of git directory")
    27  	flag.Parse()
    28  	if basePath == "" {
    29  		basePath, err = os.Getwd()
    30  		kmgConsole.ExitOnErr(err)
    31  	}
    32  	err = GitFixNameCase(basePath)
    33  	kmgConsole.ExitOnErr(err)
    34  }
    35  
    36  func GitFixNameCase(basePath string) (err error) {
    37  	folderFileCache = map[string][]string{}
    38  	repo, err := kmgGit.GetRepositoryFromPath(basePath)
    39  	if err != nil {
    40  		return err
    41  	}
    42  	caseDiffChangeArray := []string{}
    43  	for _, indexPath := range repo.MustGetIndexFileList() {
    44  		//fullPath := filepath.Join(basePath, ie.Path)
    45  		isSameOrNotExist := checkOneFileFoldDiff(basePath, indexPath)
    46  		if isSameOrNotExist {
    47  			continue
    48  		}
    49  		//在index里面修复大小写错误
    50  		caseDiffChangeArray = append(caseDiffChangeArray, indexPath)
    51  	}
    52  
    53  	if len(caseDiffChangeArray) > 0 {
    54  		fmt.Println("file name diff in case:")
    55  		for _, refPath := range caseDiffChangeArray {
    56  			fmt.Println("\t", refPath)
    57  			repo.MustIndexRemoveByPath(refPath)
    58  			//index.RemoveByPath(refPath)
    59  		}
    60  	}
    61  	return nil
    62  }
    63  
    64  type caseDiffChange struct {
    65  	gitPath string
    66  }
    67  
    68  var folderFileCache = map[string][]string{}
    69  
    70  func checkOneFileFoldDiff(basePath string, refPath string) (isSameOrNotExist bool) {
    71  	//此处要检查文件的每一部分的fold都一致
    72  	filePathPartList := strings.Split(refPath, "/")
    73  	for i := range filePathPartList {
    74  		ret := checkOneBasePathFoldDiff(filepath.Join(basePath, strings.Join(filePathPartList[:i+1], "/")))
    75  		if !ret {
    76  			return false
    77  		}
    78  	}
    79  	return true
    80  }
    81  func checkOneBasePathFoldDiff(path string) (isSameOrNotExist bool) {
    82  	fileName := filepath.Base(path)
    83  	dirPath := filepath.Dir(path)
    84  	names, ok := folderFileCache[dirPath]
    85  	if !ok {
    86  		dirFile, err := os.Open(filepath.Dir(path))
    87  		defer dirFile.Close()
    88  		if err != nil {
    89  			if os.IsNotExist(err) {
    90  				return true //dir not exist
    91  			}
    92  			kmgConsole.ExitOnErr(err)
    93  		}
    94  
    95  		names, err = dirFile.Readdirnames(-1)
    96  		kmgConsole.ExitOnErr(err)
    97  		folderFileCache[dirPath] = names
    98  	}
    99  	for _, n := range names {
   100  		if n == fileName {
   101  			return true //case same
   102  		}
   103  		if strings.EqualFold(n, fileName) {
   104  			return false //case not same
   105  		}
   106  	}
   107  	return true // base path not exist
   108  }