diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim index 0f54775..b009105 100644 --- a/autoload/magit/git.vim +++ b/autoload/magit/git.vim @@ -19,39 +19,65 @@ function! magit#git#get_status() return file_list endfunction -" s:magit_top_dir: top directory of git tree -" it is evaluated only once -" FIXME: it won't work when playing with multiple git directories wihtin one -" vim session -let s:magit_top_dir='' -" magit#git#top_dir: return the absolute path of current git worktree -" return top directory -function! magit#git#top_dir() - if ( s:magit_top_dir == '' ) - let s:magit_top_dir=magit#utils#strip( - \ system(s:git_cmd . " rev-parse --show-toplevel")) . "/" +" magit#git#is_work_tree: this function check that path passed as parameter is +" inside a git work tree +" param[in] path: path to check +" return: top work tree path if in a work tree, empty string otherwise +function! magit#git#is_work_tree(path) + let dir = getcwd() + try + call magit#utils#lcd(a:path) + let top_dir=magit#utils#strip( + \ system(s:git_cmd . " rev-parse --show-toplevel")) . "/" + if ( v:shell_error != 0 ) + return '' + endif + return top_dir + finally + call magit#utils#lcd(dir) + endtry +endfunction + +" magit#git#set_top_dir: this function set b:magit_top_dir and b:magit_git_dir +" according to a path +" param[in] path: path to set. This path must be in a git repository work tree +function! magit#git#set_top_dir(path) + let dir = getcwd() + try + call magit#utils#lcd(a:path) + let top_dir=magit#utils#strip( + \ system(s:git_cmd . " rev-parse --show-toplevel")) . "/" + if ( v:shell_error != 0 ) + throw "magit: git-show-toplevel error: " . top_dir + endif + let git_dir=magit#utils#strip(system(s:git_cmd . " rev-parse --git-dir")) . "/" if ( v:shell_error != 0 ) - echoerr "Git error: " . s:magit_top_dir + throw "magit: git-git-dir error: " . git_dir endif + let b:magit_top_dir=top_dir + let b:magit_git_dir=git_dir + finally + call magit#utils#lcd(dir) + endtry +endfunction + +" magit#git#top_dir: return the absolute path of current git worktree for the +" current magit buffer +" return top directory +function! magit#git#top_dir() + if ( !exists("b:magit_top_dir") ) + throw 'top_dir_not_set' endif - return s:magit_top_dir + return b:magit_top_dir endfunction -" s:magit_git_dir: git directory -" it is evaluated only once -" FIXME: it won't work when playing with multiple git directories wihtin one -" vim session -let s:magit_git_dir='' " magit#git#git_dir: return the absolute path of current git worktree " return git directory function! magit#git#git_dir() - if ( s:magit_git_dir == '' ) - let s:magit_git_dir=magit#utils#strip(system(s:git_cmd . " rev-parse --git-dir")) . "/" - if ( v:shell_error != 0 ) - echoerr "Git error: " . s:magit_git_dir - endif + if ( !exists("b:magit_git_dir") ) + throw 'git_dir_not_set' endif - return s:magit_git_dir + return b:magit_git_dir endfunction " magit#git#git_diff: helper function to get diff of a file diff --git a/autoload/magit/sign.vim b/autoload/magit/sign.vim index 7a53390..097e0c8 100644 --- a/autoload/magit/sign.vim +++ b/autoload/magit/sign.vim @@ -12,8 +12,6 @@ let s:dummy_sign_id = s:first_sign_id - 1 " Remove-all-signs optimisation requires Vim 7.3.596+. let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596")) -let s:bufnr = bufnr(g:magit_buffer_name) - function! magit#sign#remove_all(...) if ( a:0 == 1 ) let pattern = a:1 diff --git a/plugin/magit.vim b/plugin/magit.vim index 4383f00..3de06e9 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -15,9 +15,6 @@ let g:loaded_magit = 1 " syntax files execute 'source ' . resolve(expand(':p:h')) . '/../common/magit_common.vim' -" g:magit_buffer_name: vim buffer name for vimagit -let g:magit_buffer_name = "magit-playground" - let s:state = deepcopy(magit#state#state) " these mappings are broadly applied, for all vim buffers @@ -125,8 +122,9 @@ function! s:mg_get_info() silent put ='' let branch=magit#utils#system("git rev-parse --abbrev-ref HEAD") let commit=magit#utils#system("git show -s --oneline") - silent put ='Current branch: ' . branch - silent put ='Last commit: ' . commit + silent put ='Current repository: ' . magit#git#top_dir() + silent put ='Current branch: ' . branch + silent put ='Last commit: ' . commit silent put ='' endfunction @@ -522,8 +520,9 @@ let s:mg_display_functions = { " 4. fills with unstage stuff " 5. restore window state function! magit#update_buffer() - if ( @% != g:magit_buffer_name ) - echoerr "Not in magit buffer " . g:magit_buffer_name . " but in " . @% + let buffer_name=bufname("%") + if ( buffer_name !~ 'magit://.*' ) + echoerr "Not in magit buffer but in " . buffer_name return endif " FIXME: find a way to save folding state. According to help, this won't @@ -578,24 +577,57 @@ endfunction " 'h': horizontal split " 'c': current buffer (should be used when opening vim in vimagit mode function! magit#show_magit(display, ...) - if ( magit#utils#strip(system("git rev-parse --is-inside-work-tree")) != 'true' ) - echoerr "Magit must be started from a git repository" - return + if ( &filetype == 'netrw' ) + let cur_file_path = b:netrw_curdir + else + let cur_file = expand("%:p") + let cur_file_path = isdirectory(cur_file) ? cur_file : fnamemodify(cur_file, ":h") + endif + + let git_dir='' + let try_paths = [ cur_file_path, getcwd() ] + for path in try_paths + let git_dir=magit#git#is_work_tree(path) + if ( git_dir != '' ) + break + endif + endfor + + if ( git_dir == '' ) + echohl ErrorMsg + echom "magit can not find any git repository" + echom "make sure that current opened file or vim current directory points to a git repository" + echom "search paths:" + for path in try_paths + echom path + endfor + echohl None + throw 'magit_not_in_git_repo' endif + + let buffer_name='magit://' . git_dir + if ( a:display == 'v' ) - vnew + silent execute "vnew " . buffer_name elseif ( a:display == 'h' ) - new + silent execute "new " . buffer_name elseif ( a:display == 'c' ) - if ( bufname("%") == "" ) - keepalt enew - else - enew + if ( !bufexists(buffer_name) ) + if ( bufname("%") == "" ) + keepalt enew + else + enew + endif + execute "file " . buffer_name endif else throw 'parameter_error' endif + silent execute "buffer " . buffer_name + + call magit#git#set_top_dir(git_dir) + let b:magit_default_show_all_files = g:magit_default_show_all_files let b:magit_default_fold_level = g:magit_default_fold_level let b:magit_warning_max_lines_answered = 0 @@ -616,13 +648,7 @@ function! magit#show_magit(display, ...) setlocal filetype=magit "setlocal readonly - try - silent execute "buffer " . g:magit_buffer_name - catch /^Vim\%((\a\+)\)\=:E94/ - silent execute "keepalt file " . g:magit_buffer_name - endtry - - call magit#utils#setbufnr(bufnr(g:magit_buffer_name)) + call magit#utils#setbufnr(bufnr(buffer_name)) call magit#sign#init() execute "nnoremap " . g:magit_stage_file_mapping . " :call magit#stage_file()"