diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim
index 0f547751acba687b58b3a5a6d41575eab1dd554c..b009105d86deec52a3ae4b2d167e869bc1ce5267 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 7a53390921aafefac34b623b5efda53116173d5c..097e0c89dd02200136cec510f402eba03d96b9f5 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 4383f004ff114ffb0df9e2947234eed2d5184067..3de06e9227e2bc6583fc4476fa8621a6d34bc4ba 100644
--- a/plugin/magit.vim
+++ b/plugin/magit.vim
@@ -15,9 +15,6 @@ let g:loaded_magit = 1
 " syntax files
 execute 'source ' . resolve(expand('<sfile>: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 <buffer> <silent> " . g:magit_stage_file_mapping .   " :call magit#stage_file()<cr>"