diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim
index 9c95a29cc35d99fb5efd0fc48f2ebacc8ece7390..1163014d2d69bf0eb6deb45a9b326e6fda63ce93 100644
--- a/autoload/magit/state.vim
+++ b/autoload/magit/state.vim
@@ -88,53 +88,59 @@ endfunction
 " param[in] status: one character status code of the file (AMDRCU?)
 " param[in] filename: filename
 function! magit#state#add_file(mode, status, filename) dict
-	let dev_null = ( a:status == '?' ) ? " /dev/null " : " "
-	let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " "
-	let diff_cmd="git diff --no-ext-diff " . staged_flag .
-				\ "--no-color --patch -- " . dev_null . " "
-				\ .  magit#utils#add_quotes(a:filename)
-	let diff_list=magit#utils#systemlist(diff_cmd)
-	if ( empty(diff_list) )
-		echoerr "diff command \"" . diff_cmd . "\" returned nothing"
-	endif
-	let diff_dict_file = self.get_file(a:mode, a:filename, 1)
-	let diff_dict_file.exists = 1
-	let diff_dict_file.status = a:status
-	if ( a:status == '?' && getftype(a:filename) == 'link' )
-		let diff_dict_file.symlink = resolve(a:filename)
-		call add(diff_dict_file.diff.header, 'no header')
-		let diff_dict_file.diff.hunks[0].header = 'New symbolic link file'
-	elseif ( a:status == '?' && getfsize(a:filename) == 0 )
-		let diff_dict_file.empty = 1
-		call add(diff_dict_file.diff.header, 'no header')
-		let diff_dict_file.diff.hunks[0].header = 'New empty file'
-	elseif ( match(system("file --mime " .
-				\ magit#utils#add_quotes(a:filename)),
-				\ a:filename . ".*charset=binary") != -1 )
-		let diff_dict_file.binary = 1
-		call add(diff_dict_file.diff.header, 'no header')
-		let diff_dict_file.diff.hunks[0].header = 'Binary file'
-	else
-		let line = 0
-		" match(
-		while ( line < len(diff_list) && diff_list[line] !~ "^@.*" )
-			call add(diff_dict_file.diff.header, diff_list[line])
-			let line += 1
-		endwhile
-
-		let hunk = diff_dict_file.diff.hunks[0]
-		let hunk.header = diff_list[line]
-
-		for diff_line in diff_list[line+1 : -1]
-			if ( diff_line =~ "^@.*" )
-				let hunk = deepcopy(s:hunk_template)
-				call add(diff_dict_file.diff.hunks, hunk)
-				let hunk.header = diff_line
-				continue
-			endif
-			call add(hunk.lines, diff_line)
-		endfor
-	endif
+	let dir = getcwd()
+	try
+		call magit#utils#lcd(magit#utils#top_dir())
+		let dev_null = ( a:status == '?' ) ? " /dev/null " : " "
+		let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " "
+		let diff_cmd="git diff --no-ext-diff " . staged_flag .
+					\ "--no-color --patch -- " . dev_null . " "
+					\ .  magit#utils#add_quotes(a:filename)
+		let diff_list=magit#utils#systemlist(diff_cmd)
+		if ( empty(diff_list) )
+			echoerr "diff command \"" . diff_cmd . "\" returned nothing"
+		endif
+		let diff_dict_file = self.get_file(a:mode, a:filename, 1)
+		let diff_dict_file.exists = 1
+		let diff_dict_file.status = a:status
+		if ( a:status == '?' && getftype(a:filename) == 'link' )
+			let diff_dict_file.symlink = resolve(a:filename)
+			call add(diff_dict_file.diff.header, 'no header')
+			let diff_dict_file.diff.hunks[0].header = 'New symbolic link file'
+		elseif ( a:status == '?' && getfsize(a:filename) == 0 )
+			let diff_dict_file.empty = 1
+			call add(diff_dict_file.diff.header, 'no header')
+			let diff_dict_file.diff.hunks[0].header = 'New empty file'
+		elseif ( match(system("file --mime " .
+					\ magit#utils#add_quotes(a:filename)),
+					\ a:filename . ".*charset=binary") != -1 )
+			let diff_dict_file.binary = 1
+			call add(diff_dict_file.diff.header, 'no header')
+			let diff_dict_file.diff.hunks[0].header = 'Binary file'
+		else
+			let line = 0
+			" match(
+			while ( line < len(diff_list) && diff_list[line] !~ "^@.*" )
+				call add(diff_dict_file.diff.header, diff_list[line])
+				let line += 1
+			endwhile
+
+			let hunk = diff_dict_file.diff.hunks[0]
+			let hunk.header = diff_list[line]
+
+			for diff_line in diff_list[line+1 : -1]
+				if ( diff_line =~ "^@.*" )
+					let hunk = deepcopy(s:hunk_template)
+					call add(diff_dict_file.diff.hunks, hunk)
+					let hunk.header = diff_line
+					continue
+				endif
+				call add(hunk.lines, diff_line)
+			endfor
+		endif
+	finally
+		call magit#utils#lcd(dir)
+	endtry
 endfunction
 
 " magit#state#update: update self.dict
diff --git a/autoload/magit/utils.vim b/autoload/magit/utils.vim
index 6b8ca64f6d186c6fbb44c9096b74cb063f0349da..1cc472bad2408029bf22250a0f3c5100d1417e7e 100644
--- a/autoload/magit/utils.vim
+++ b/autoload/magit/utils.vim
@@ -36,6 +36,10 @@ endfunction
 " s:magit_cd_cmd: plugin variable to choose lcd/cd command, 'lcd' if exists,
 " 'cd' otherwise
 let s:magit_cd_cmd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
+" magit#utils#lcd: helper function to lcd. use cd if lcd doesn't exists
+function! magit#utils#lcd(dir)
+	execute s:magit_cd_cmd . a:dir
+endfunction
 
 " magit#utils#system: wrapper for system, which only takes String as input in vim,
 " although it can take String or List input in neovim.