Junegunn Choi 5 лет назад
Родитель
Сommit
d16273e072
1 измененных файлов с 62 добавлено и 68 удалено
  1. 62 68
      plug.vim

+ 62 - 68
plug.vim

@@ -120,29 +120,23 @@ function! s:isabsolute(dir) abort
   return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)')
 endfunction
 
-function! s:get_gitdir(dir) abort
-  let gitdir = a:dir . '/.git'
+function! s:git_dir(dir) abort
+  let gitdir = s:trim(a:dir) . '/.git'
   if isdirectory(gitdir)
     return gitdir
   endif
-  try
-    let line = readfile(gitdir)[0]
-    if line =~# '^gitdir: '
-      let gitdir = line[8:]
-      if !s:isabsolute(gitdir)
-        let gitdir = a:dir . '/' . gitdir
-      endif
-      if isdirectory(gitdir)
-        return gitdir
-      endif
-    endif
-  catch
-  endtry
-  return ''
+  if !filereadable(gitdir)
+    return ''
+  endif
+  let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*')
+  if len(gitdir) && !s:isabsolute(gitdir)
+    let gitdir = a:dir . '/' . gitdir
+  endif
+  return isdirectory(gitdir) ? gitdir : ''
 endfunction
 
-function! s:git_get_remote_origin_url(dir) abort
-  let gitdir = s:get_gitdir(a:dir)
+function! s:git_origin_url(dir) abort
+  let gitdir = s:git_dir(a:dir)
   let config = gitdir . '/config'
   if empty(gitdir) || !filereadable(config)
     return ''
@@ -150,44 +144,60 @@ function! s:git_get_remote_origin_url(dir) abort
   return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze')
 endfunction
 
-function! s:git_get_revision(dir) abort
-  let gitdir = s:get_gitdir(a:dir)
-  if gitdir ==# ''
+function! s:git_revision(dir) abort
+  let gitdir = s:git_dir(a:dir)
+  let head = gitdir . '/HEAD'
+  if empty(gitdir) || !filereadable(head)
     return ''
   endif
-  try
-    let line = readfile(gitdir . '/HEAD')[0]
-    if line =~# '^ref: '
-      let ref = line[5:]
-      if filereadable(gitdir . '/' . ref)
-        return readfile(gitdir . '/' . ref)[0]
+
+  let line = get(readfile(head), 0, '')
+  let ref = matchstr(line, '^ref: \zs.*')
+  if empty(ref)
+    return line
+  endif
+
+  if filereadable(gitdir . '/' . ref)
+    return get(readfile(gitdir . '/' . ref), 0, '')
+  endif
+
+  if filereadable(gitdir . '/packed-refs')
+    for line in readfile(gitdir . '/packed-refs')
+      if line =~# ' ' . ref
+        return matchstr(line, '^[0-9a-f]*')
       endif
-      for line in readfile(gitdir . '/packed-refs')
-        if line =~# ' ' . ref
-          return substitute(line, '^\([0-9a-f]*\) ', '\1', '')
-        endif
-      endfor
-    endif
-    return l:line
-  catch
-  endtry
+    endfor
+  endif
+
   return ''
 endfunction
 
-function! s:git_get_branch(dir) abort
-  let gitdir = s:get_gitdir(a:dir)
-  if gitdir ==# ''
+function! s:git_local_branch(dir) abort
+  let gitdir = s:git_dir(a:dir)
+  let head = gitdir . '/HEAD'
+  if empty(gitdir) || !filereadable(head)
     return ''
   endif
-  try
-    let line = readfile(gitdir . '/HEAD')[0]
-    if line =~# '^ref: refs/heads/'
-      return line[16:]
-    endif
-    return 'HEAD'
-  catch
-    return ''
-  endtry
+  let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*')
+  return len(branch) ? branch : 'HEAD'
+endfunction
+
+function! s:git_origin_branch(spec)
+  if len(a:spec.branch)
+    return a:spec.branch
+  endif
+
+  " The file may not be present if this is a local repository
+  let gitdir = s:git_dir(a:spec.dir)
+  let origin_head = gitdir.'/refs/remotes/origin/HEAD'
+  if len(gitdir) && filereadable(origin_head)
+    return matchstr(get(readfile(origin_head), 0, ''),
+                  \ '^ref: refs/remotes/origin/\zs.*')
+  endif
+
+  " The command may not return the name of a branch in detached HEAD state
+  let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir))
+  return v:shell_error ? '' : result[-1]
 endfunction
 
 if s:is_win
@@ -1065,7 +1075,7 @@ endfunction
 
 function! s:checkout(spec)
   let sha = a:spec.commit
-  let output = s:git_get_revision(a:spec.dir)
+  let output = s:git_revision(a:spec.dir)
   if !empty(output) && !s:hash_match(sha, s:lines(output)[0])
     let output = s:system(
           \ 'git fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir)
@@ -2282,26 +2292,10 @@ function! s:system_chomp(...)
   return v:shell_error ? '' : substitute(ret, '\n$', '', '')
 endfunction
 
-function! s:git_origin_branch(spec)
-  if len(a:spec.branch)
-    return a:spec.branch
-  endif
-
-  " The file may not be present if this is a local repository
-  let origin_head = a:spec.dir.'/.git/refs/remotes/origin/HEAD'
-  if filereadable(origin_head)
-    return split(readfile(origin_head)[0], 'refs/remotes/origin/')[-1]
-  endif
-
-  " The command may not return the name of a branch in detached HEAD state
-  let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir))
-  return v:shell_error ? '' : result[-1]
-endfunction
-
 function! s:git_validate(spec, check_branch)
   let err = ''
   if isdirectory(a:spec.dir)
-    let result = [s:git_get_branch(a:spec.dir), s:git_get_remote_origin_url(a:spec.dir)]
+    let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)]
     let remote = result[-1]
     if empty(remote)
       let err = join([remote, 'PlugClean required.'], "\n")
@@ -2310,7 +2304,7 @@ function! s:git_validate(spec, check_branch)
                     \ 'Expected:    '.a:spec.uri,
                     \ 'PlugClean required.'], "\n")
     elseif a:check_branch && has_key(a:spec, 'commit')
-      let sha = s:git_get_revision(a:spec.dir)
+      let sha = s:git_revision(a:spec.dir)
       if empty(sha)
         let err = join(add(result, 'PlugClean required.'), "\n")
       elseif !s:hash_match(sha, a:spec.commit)
@@ -2756,7 +2750,7 @@ function! s:snapshot(force, ...) abort
   let names = sort(keys(filter(copy(g:plugs),
         \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)')))
   for name in reverse(names)
-    let sha = s:git_get_revision(g:plugs[name].dir)
+    let sha = s:git_revision(g:plugs[name].dir)
     if !empty(sha)
       call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha))
       redraw