github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/cmd/git-dolt/utils/find_git_config_dir.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package utils 16 17 import ( 18 "fmt" 19 "os" 20 "path/filepath" 21 "strings" 22 ) 23 24 // FindGitConfigUnderRoot will recurse upwards from the current working directory 25 // to the system root looking for a directory named .git, returning its path if found, 26 // and an error if not. 27 func FindGitConfigUnderRoot() (string, error) { 28 currentPath, err := os.Getwd() 29 if err != nil { 30 return "", fmt.Errorf("error getting current directory: %v", err) 31 } 32 33 rootPath, err := filepath.Abs("/") 34 if err != nil { 35 return "", fmt.Errorf("error getting root directory: %v", err) 36 } 37 38 return FindGitConfigDir(currentPath, rootPath) 39 } 40 41 // FindGitConfigDir will recurse upwards from currentPath to terminalPath looking for 42 // a directory named .git, returning its path if found, and an error if not. 43 // 44 // Both currentPath and terminalPath are assumed to be absolute paths. An error is returned 45 // if currentPath is not a descendant of terminalPath. 46 func FindGitConfigDir(currentPath, terminalPath string) (string, error) { 47 if !strings.HasPrefix(currentPath, terminalPath) { 48 return "", fmt.Errorf("current path %s is not a descendent of terminal path %s", currentPath, terminalPath) 49 } 50 51 // recursive base case -- currentPath and terminalPath are the same 52 if currentPath == terminalPath { 53 return "", fmt.Errorf("recursed upwards to %s but couldn't find a .git directory", currentPath) 54 } 55 56 // check to see if .git exists in currentPath 57 fileInfo, fileErr := os.Stat(filepath.Join(currentPath, ".git")) 58 59 // .git exists and is a directory -- success! 60 if fileErr == nil && fileInfo.IsDir() { 61 return filepath.Join(currentPath, ".git"), nil 62 } 63 64 // something went wrong looking for .git other than it not existing -- return an error 65 if fileErr != nil && !os.IsNotExist(fileErr) { 66 return "", fmt.Errorf("error looking for the .git directory in %s: %v", currentPath, fileErr) 67 } 68 69 // either .git exists and is not a directory, or .git does not exist: 70 // go up one directory level and make the recursive call 71 parentPath := filepath.Dir(currentPath) 72 if parentPath == "." { 73 return "", fmt.Errorf("ran out of ancestors at %s but couldn't find a .git directory", currentPath) 74 } 75 return FindGitConfigDir(parentPath, terminalPath) 76 }