diff --git a/.travis.yml b/.travis.yml
index 184293b1fbb495f71c8632042bc148ca45d81a35..0288e9bc419ea355d0c29b145d470923a433f10c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@ branches:
   only:
     - master
     - next
-    - dev
+    - /^dev\/.*$/
 
 os:
   - linux
@@ -62,7 +62,7 @@ install:
 
 before_script:
   - git clone https://github.com/jreybert/djooks
-  - git clone https://github.com/junegunn/vader.vim
+  - git clone https://github.com/jreybert/vader.vim
 
 script:
   - ./test/run.sh . vader.vim djooks $VIM_VERSION
diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim
index 0389b90ce4ac29cee3ff38353050c185c59a503d..66b0181184750946b51c50e8d6a08b459be6b56f 100644
--- a/autoload/magit/git.vim
+++ b/autoload/magit/git.vim
@@ -1,3 +1,5 @@
+let s:git_cmd="GIT_CONFIG=/dev/null GIT_CONFIG_NOSYSTEM=1 XDG_CONFIG_HOME=/ git"
+
 " magit#git#get_status: this function returns the git status output formated
 " into a List of Dict as
 " [ {staged', 'unstaged', 'filename'}, ... ]
@@ -8,7 +10,7 @@ function! magit#git#get_status()
 	" we can't use git status -z here, because system doesn't make the
 	" difference between NUL and NL. -status z terminate entries with NUL,
 	" instead of NF
-	let status_list=magit#utils#systemlist("git status --porcelain")
+	let status_list=magit#utils#systemlist(s:git_cmd . " status --porcelain")
 	for file_status_line in status_list
 		let line_match = matchlist(file_status_line, '\(.\)\(.\) \%(.\{-\} -> \)\?"\?\(.\{-\}\)"\?$')
 		let filename = line_match[3]
@@ -17,3 +19,126 @@ 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")) . "/"
+		if ( v:shell_error != 0 )
+			echoerr "Git error: " . s:magit_top_dir
+		endif
+	endif
+	return s: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
+	endif
+	return s:magit_git_dir
+endfunction
+
+" magit#git#git_add: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_add(filename)
+	let git_cmd=s:git_cmd . " add --no-ignore-removal -- " . a:filename
+	silent let git_result=magit#utils#system(git_cmd)
+	if ( v:shell_error != 0 )
+		echoerr "Git error: " . git_result
+		echoerr "Git cmd: " . git_cmd
+	endif
+endfunction
+
+" magit#git#git_checkout: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_checkout(filename)
+	let git_cmd=s:git_cmd . " checkout -- " . a:filename
+	silent let git_result=magit#utils#system(git_cmd)
+	if ( v:shell_error != 0 )
+		echoerr "Git error: " . git_result
+		echoerr "Git cmd: " . git_cmd
+	endif
+endfunction
+
+" magit#git#git_reset: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_reset(filename)
+	let git_cmd=s:git_cmd . " reset HEAD -- " . a:filename
+	silent let git_result=magit#utils#system(git_cmd)
+	if ( v:shell_error != 0 )
+		echoerr "Git error: " . git_result
+		echoerr "Git cmd: " . git_cmd
+	endif
+endfunction
+
+" magit#git#git_apply: helper function to stage a selection
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] selection: the text to stage. It must be a patch, i.e. a diff 
+" header plus one or more hunks
+" return: no
+function! magit#git#git_apply(header, selection)
+	let selection = magit#utils#flatten(a:header + a:selection)
+	if ( selection[-1] !~ '^$' )
+		let selection += [ '' ]
+	endif
+	let git_cmd=s:git_cmd . " apply --recount --no-index --cached -"
+	silent let git_result=magit#utils#system(git_cmd, selection)
+	if ( v:shell_error != 0 )
+		echoerr "Git error: " . git_result
+		echoerr "Git cmd: " . git_cmd
+		echoerr "Tried to aply this"
+		echoerr string(selection)
+	endif
+endfunction
+
+" magit#git#git_unapply: helper function to unstage a selection
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] selection: the text to stage. It must be a patch, i.e. a diff 
+" header plus one or more hunks
+" return: no
+function! magit#git#git_unapply(header, selection, mode)
+	let cached_flag=''
+	if ( a:mode == 'staged' )
+		let cached_flag=' --cached '
+	endif
+	let selection = magit#utils#flatten(a:header + a:selection)
+	if ( selection[-1] !~ '^$' )
+		let selection += [ '' ]
+	endif
+	silent let git_result=magit#utils#system(
+		\ s:git_cmd . " apply --recount --no-index " . cached_flag . " --reverse - ",
+		\ selection)
+	if ( v:shell_error != 0 )
+		echoerr "Git error: " . git_result
+		echoerr "Tried to unaply this"
+		echoerr string(selection)
+	endif
+endfunction
+
+function! magit#git#submodule_status()
+	return system(s:git_cmd . " submodule status")
+endfunction
diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim
index 8781329aabf213a4ed22bb3af94f414e288ee73b..032416eacd461d1ef8b82abd57206c605157e2a8 100644
--- a/autoload/magit/state.vim
+++ b/autoload/magit/state.vim
@@ -1,23 +1,31 @@
+" magit#state#is_file_visible: file getter function
+" return if file is visible
 function! magit#state#is_file_visible() dict
 	return self.visible
 endfunction
 
+" magit#state#set_file_visible: file setter function
+" param[in] val: visible state to set to file
 function! magit#state#set_file_visible(val) dict
 	let self.visible = a:val
 endfunction
 
+" magit#state#toggle_file_visible: file setter function, toggle file visible
+" state
 function! magit#state#toggle_file_visible() dict
 	let self.visible = ( self.visible == 0 ) ? 1 : 0
 endfunction
 
+" magit#state#is_file_dir: file getter function
+" return 1 if current file is a directory, 0 otherwise
 function! magit#state#is_file_dir() dict
 	return self.dir != 0
 endfunction
 
-function! magit#state#get_files(mode) dict
-	return self.dict[a:mode]
-endfunction
-
+" magit#state#must_be_added: file helper function
+" there are some conditions where files must be widely added (git add), not
+" 'diff applied' (git apply)
+" return 1 if file must 
 function! magit#state#must_be_added() dict
 	return ( self.empty == 1 ||
 		\ self.symlink != '' ||
@@ -208,7 +216,7 @@ function! magit#state#update() dict
 
 	let dir = getcwd()
 	try
-		call magit#utils#lcd(magit#utils#top_dir())
+		call magit#utils#lcd(magit#git#top_dir())
 		call magit#utils#refresh_submodule_list()
 		for [mode, diff_dict_mode] in items(self.dict)
 			let status_list = magit#git#get_status()
@@ -236,6 +244,9 @@ function! magit#state#update() dict
 	endfor
 endfunction
 
+" magit#state#set_files_visible: global dict setter function
+" update all files visible state
+" param[in] is_visible: boolean value to set to files
 function! magit#state#set_files_visible(is_visible) dict
 	for diff_dict_mode in values(self.dict)
 		for file in values(diff_dict_mode)
@@ -244,6 +255,14 @@ function! magit#state#set_files_visible(is_visible) dict
 	endfor
 endfunction
 
+" magit#state#get_files: global dict getter function
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return all files belonging to mode
+function! magit#state#get_files(mode) dict
+	return self.dict[a:mode]
+endfunction
+
+
 " dict: structure containing all diffs
 " It is formatted as follow
 " {
diff --git a/autoload/magit/utils.vim b/autoload/magit/utils.vim
index a8ec6ef98c193a39b65a8dd00fa09139b5953066..6be7df154753667583c371fe83f5179291682185 100644
--- a/autoload/magit/utils.vim
+++ b/autoload/magit/utils.vim
@@ -1,43 +1,9 @@
-" 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#utils#top_dir: return the absolute path of current git worktree
-" return top directory
-function! magit#utils#top_dir()
-	if ( s:magit_top_dir == '' )
-		let s:magit_top_dir=magit#utils#strip(
-			\ system("git rev-parse --show-toplevel")) . "/"
-		if ( v:shell_error != 0 )
-			echoerr "Git error: " . s:magit_top_dir
-		endif
-	endif
-	return s: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#utils#git_dir: return the absolute path of current git worktree
-" return git directory
-function! magit#utils#git_dir()
-	if ( s:magit_git_dir == '' )
-		let s:magit_git_dir=magit#utils#strip(system("git rev-parse --git-dir")) . "/"
-		if ( v:shell_error != 0 )
-			echoerr "Git error: " . s:magit_git_dir
-		endif
-	endif
-	return s:magit_git_dir
-endfunction
 
 " s:magit#utils#is_binary: check if file is a binary file
 " param[in] filename: the file path. it must quoted if it contains spaces
 function! magit#utils#is_binary(filename)
 	return ( match(system("file --mime " . a:filename ),
-				\ a:filename . ".*charset=binary") != -1 )
+				\ ".*charset=binary") != -1 )
 endfunction
 
 " magit#utils#ls_all: list all files (including hidden ones) in a given path
@@ -51,7 +17,7 @@ let s:submodule_list = []
 " magit#utils#refresh_submodule_list: this function refresh the List s:submodule_list
 " magit#utils#is_submodule() is using s:submodule_list
 function! magit#utils#refresh_submodule_list()
-	let s:submodule_list = map(split(system("git submodule status"), "\n"), 'split(v:val)[1]')
+	let s:submodule_list = map(split(magit#git#submodule_status(), "\n"), 'split(v:val)[1]')
 endfunction
 
 " magit#utils#is_submodule search if dirname is in s:submodule_list 
@@ -78,7 +44,7 @@ endfunction
 function! magit#utils#system(...)
 	let dir = getcwd()
 	try
-		execute s:magit_cd_cmd . magit#utils#top_dir()
+		execute s:magit_cd_cmd . magit#git#top_dir()
 		" List as system() input is since v7.4.247, it is safe to check
 		" systemlist, which is sine v7.4.248
 		if exists('*systemlist')
@@ -111,7 +77,7 @@ endfunction
 function! magit#utils#systemlist(...)
 	let dir = getcwd()
 	try
-		execute s:magit_cd_cmd . magit#utils#top_dir()
+		execute s:magit_cd_cmd . magit#git#top_dir()
 		" systemlist since v7.4.248
 		if exists('*systemlist')
 			return call('systemlist', a:000)
diff --git a/plugin/magit.vim b/plugin/magit.vim
index 4f951cb29c90b6d3e158363baf8cc1ff71e9b7d8..86078177b83b6ed03d983a2e1ba751a413aa58f8 100644
--- a/plugin/magit.vim
+++ b/plugin/magit.vim
@@ -20,49 +20,35 @@ let g:magit_buffer_name = "magit-playground"
 
 let s:state = deepcopy(magit#state#state)
 
-" s:set: helper function to set user definable variable
-" param[in] var: variable to set
-" param[in] default: default value if not already set by the user
-" return: no
-function! s:set(var, default)
-	if !exists(a:var)
-		if type(a:default)
-			execute 'let' a:var '=' string(a:default)
-		else
-			execute 'let' a:var '=' a:default
-		endif
-	endif
-endfunction
-
 " these mappings are broadly applied, for all vim buffers
-call s:set('g:magit_show_magit_mapping',        '<leader>M' )
+let g:magit_show_magit_mapping     = get(g:, 'magit_show_magit_mapping',        '<leader>M' )
 
 " these mapping are applied locally, for magit buffer only
-call s:set('g:magit_stage_file_mapping',        'F' )
-call s:set('g:magit_stage_hunk_mapping',        'S' )
-call s:set('g:magit_stage_line_mapping',        'L' )
-call s:set('g:magit_mark_line_mapping',         'M' )
-call s:set('g:magit_discard_hunk_mapping',      'DDD' )
-call s:set('g:magit_commit_mapping_command',    'w<cr>' )
-call s:set('g:magit_commit_mapping',            'CC' )
-call s:set('g:magit_commit_amend_mapping',      'CA' )
-call s:set('g:magit_commit_fixup_mapping',      'CF' )
-call s:set('g:magit_reload_mapping',            'R' )
-call s:set('g:magit_ignore_mapping',            'I' )
-call s:set('g:magit_close_mapping',             'q' )
-call s:set('g:magit_toggle_help_mapping',       'h' )
-
-call s:set('g:magit_folding_toggle_mapping',    [ '<CR>' ])
-call s:set('g:magit_folding_open_mapping',      [ 'zo', 'zO' ])
-call s:set('g:magit_folding_close_mapping',     [ 'zc', 'zC' ])
+let g:magit_stage_file_mapping     = get(g:, 'magit_stage_file_mapping',        'F' )
+let g:magit_stage_hunk_mapping     = get(g:, 'magit_stage_hunk_mapping',        'S' )
+let g:magit_stage_line_mapping     = get(g:, 'magit_stage_line_mapping',        'L' )
+let g:magit_mark_line_mapping      = get(g:, 'magit_mark_line_mapping',         'M' )
+let g:magit_discard_hunk_mapping   = get(g:, 'magit_discard_hunk_mapping',      'DDD' )
+let g:magit_commit_mapping_command = get(g:, 'magit_commit_mapping_command',    'w<cr>' )
+let g:magit_commit_mapping         = get(g:, 'magit_commit_mapping',            'CC' )
+let g:magit_commit_amend_mapping   = get(g:, 'magit_commit_amend_mapping',      'CA' )
+let g:magit_commit_fixup_mapping   = get(g:, 'magit_commit_fixup_mapping',      'CF' )
+let g:magit_reload_mapping         = get(g:, 'magit_reload_mapping',            'R' )
+let g:magit_ignore_mapping         = get(g:, 'magit_ignore_mapping',            'I' )
+let g:magit_close_mapping          = get(g:, 'magit_close_mapping',             'q' )
+let g:magit_toggle_help_mapping    = get(g:, 'magit_toggle_help_mapping',       'h' )
+
+let g:magit_folding_toggle_mapping = get(g:, 'magit_folding_toggle_mapping',    [ '<CR>' ])
+let g:magit_folding_open_mapping   = get(g:, 'magit_folding_open_mapping',      [ 'zo', 'zO' ])
+let g:magit_folding_close_mapping  = get(g:, 'magit_folding_close_mapping',     [ 'zc', 'zC' ])
 
 " user options
-call s:set('g:magit_enabled',                   1)
-call s:set('g:magit_show_help',                 1)
-call s:set('g:magit_default_show_all_files',    0)
-call s:set('g:magit_default_fold_level',        1)
+let g:magit_enabled                = get(g:, 'magit_enabled',                   1)
+let g:magit_show_help              = get(g:, 'magit_show_help',                 1)
+let g:magit_default_show_all_files = get(g:, 'magit_default_show_all_files',    0)
+let g:magit_default_fold_level     = get(g:, 'magit_default_fold_level',        1)
 
-call s:set('g:magit_warning_max_lines',         10000)
+let g:magit_warning_max_lines      = get(g:, 'magit_warning_max_lines',         10000)
 
 execute "nnoremap <silent> " . g:magit_show_magit_mapping . " :call magit#show_magit('v')<cr>"
 " }}}
@@ -144,6 +130,13 @@ function! s:mg_get_info()
 	silent put =''
 endfunction
 
+" s:mg_display_files: display in current buffer files, filtered by some
+" parameters
+" param[in] mode: files mode, can be 'staged' or 'unstaged'
+" param[in] curdir: directory containing files (only needed for untracked
+" directory)
+" param[in] depth: current directory depth (only needed for untracked
+" directory)
 function! s:mg_display_files(mode, curdir, depth)
 
 	" FIXME: ouch, must store subdirs in more efficient way
@@ -247,7 +240,7 @@ function! s:mg_get_commit_section()
 	silent put =magit#utils#underline(g:magit_sections.commit_start)
 	silent put =''
 
-	let git_dir=magit#utils#git_dir()
+	let git_dir=magit#git#git_dir()
 	" refresh the COMMIT_EDITMSG file
 	if ( s:magit_commit_mode == 'CC' )
 		silent! call magit#utils#system("GIT_EDITOR=/bin/false git commit -e 2> /dev/null")
@@ -288,20 +281,14 @@ endfunction
 " inferior to upper_limit line, block is discarded
 " return: [startline, endline]
 function! s:mg_search_block(start_pattern, end_pattern, upper_limit_pattern)
-	let l:winview = winsaveview()
 
 	let upper_limit=0
 	if ( a:upper_limit_pattern != "" )
 		let upper_limit=search(a:upper_limit_pattern, "cbnW")
 	endif
 
-	let start=search(a:start_pattern[0], "cbW")
-	if ( start == 0 )
-		call winrestview(l:winview)
-		throw "out_of_block"
-	endif
-	if ( start < upper_limit )
-		call winrestview(l:winview)
+	let start=search(a:start_pattern[0], "cbnW")
+	if ( start == 0 || start < upper_limit )
 		throw "out_of_block"
 	endif
 	let start+=a:start_pattern[1]
@@ -316,12 +303,9 @@ function! s:mg_search_block(start_pattern, end_pattern, upper_limit_pattern)
 		endif
 	endfor
 	if ( end == 0 )
-		call winrestview(l:winview)
 		throw "out_of_block"
 	endif
 
-	call winrestview(l:winview)
-
 	return [start,end]
 endfunction
 
@@ -396,52 +380,6 @@ function! s:mg_select_hunk_block()
 				\ g:magit_file_re)
 endfunction
 
-" s:mg_git_apply: helper function to stage a selection
-" nota: when git fail (due to misformated patch for example), an error
-" message is raised.
-" param[in] selection: the text to stage. It must be a patch, i.e. a diff 
-" header plus one or more hunks
-" return: no
-function! s:mg_git_apply(header, selection)
-	let selection = magit#utils#flatten(a:header + a:selection)
-	if ( selection[-1] !~ '^$' )
-		let selection += [ '' ]
-	endif
-	let git_cmd="git apply --recount --no-index --cached -"
-	silent let git_result=magit#utils#system(git_cmd, selection)
-	if ( v:shell_error != 0 )
-		echoerr "Git error: " . git_result
-		echoerr "Git cmd: " . git_cmd
-		echoerr "Tried to aply this"
-		echoerr string(selection)
-	endif
-endfunction
-
-" s:mg_git_unapply: helper function to unstage a selection
-" nota: when git fail (due to misformated patch for example), an error
-" message is raised.
-" param[in] selection: the text to stage. It must be a patch, i.e. a diff 
-" header plus one or more hunks
-" return: no
-function! s:mg_git_unapply(header, selection, mode)
-	let cached_flag=''
-	if ( a:mode == 'staged' )
-		let cached_flag=' --cached '
-	endif
-	let selection = magit#utils#flatten(a:header + a:selection)
-	if ( selection[-1] !~ '^$' )
-		let selection += [ '' ]
-	endif
-	silent let git_result=magit#utils#system(
-		\ "git apply --recount --no-index " . cached_flag . " --reverse - ",
-		\ selection)
-	if ( v:shell_error != 0 )
-		echoerr "Git error: " . git_result
-		echoerr "Tried to unaply this"
-		echoerr string(selection)
-	endif
-endfunction
-
 " s:mg_create_diff_from_select: craft the diff to apply from a selection
 " in a chunk
 " remarks: it works with full lines, and can not span over multiple chunks
@@ -708,7 +646,7 @@ function! magit#show_magit(display, ...)
 	execute "normal! gg"
 endfunction
 
-function! s:mg_select_closed_file()
+function! s:mg_stage_closed_file(discard)
 	if ( getline(".") =~ g:magit_file_re )
 		let list = matchlist(getline("."), g:magit_file_re)
 		let filename = list[2]
@@ -717,8 +655,26 @@ function! s:mg_select_closed_file()
 		let file = s:state.get_file(section, filename)
 		if ( file.is_visible() == 0 ||
 			\ file.is_dir() == 1 )
-			let selection = s:state.get_file(section, filename).get_flat_hunks()
-			return selection
+			if ( a:discard == 0 )
+				if ( section == 'unstaged' )
+					call magit#git#git_add(magit#utils#add_quotes(filename))
+				elseif ( section == 'staged' )
+					call magit#git#git_reset(magit#utils#add_quotes(filename))
+				else
+					echoerr "Must be in \"" .
+								\ g:magit_sections.staged . "\" or \"" .
+								\ g:magit_sections.unstaged . "\" section"
+				endif
+			else
+				if ( section == 'unstaged' )
+					call magit#git#git_checkout(magit#utils#add_quotes(filename))
+				else
+					echoerr "Must be in \"" .
+								\ g:magit_sections.unstaged . "\" section"
+				endif
+			endif
+			call magit#update_buffer()
+			return
 		endif
 	endif
 	throw "out_of_block"
@@ -739,32 +695,30 @@ function! magit#stage_block(selection, discard) abort
 	if ( a:discard == 0 )
 		if ( section == 'unstaged' )
 			if ( file.must_be_added() )
-				call magit#utils#system('git add ' .
-					\ magit#utils#add_quotes(filename))
+				call magit#git#git_add(magit#utils#add_quotes(filename))
 			else
-				call <SID>mg_git_apply(header, a:selection)
+				call magit#git#git_apply(header, a:selection)
 			endif
 		elseif ( section == 'staged' )
 			if ( file.must_be_added() )
-				call magit#utils#system('git reset ' .
-					\ magit#utils#add_quotes(filename))
+				call magit#git#git_reset(magit#utils#add_quotes(filename))
 			else
-				call <SID>mg_git_unapply(header, a:selection, 'staged')
+				call magit#git#git_unapply(header, a:selection, 'staged')
 			endif
 		else
-			echoerr "Must be in \"" . 
-						\ g:magit_sections.staged . "\" or \"" . 
+			echoerr "Must be in \"" .
+						\ g:magit_sections.staged . "\" or \"" .
 						\ g:magit_sections.unstaged . "\" section"
 		endif
 	else
 		if ( section == 'unstaged' )
 			if ( file.must_be_added() )
-				call delete(filename)
+				call magit#git#git_checkout(magit#utils#add_quotes(filename))
 			else
-				call <SID>mg_git_unapply(header, a:selection, 'unstaged')
+				call magit#git#git_unapply(header, a:selection, 'unstaged')
 			endif
 		else
-			echoerr "Must be in \"" . 
+			echoerr "Must be in \"" .
 						\ g:magit_sections.unstaged . "\" section"
 		endif
 	endif
@@ -779,7 +733,8 @@ endfunction
 " return: no
 function! magit#stage_file()
 	try
-		let selection = <SID>mg_select_closed_file()
+		call <SID>mg_stage_closed_file(0)
+		return
 	catch 'out_of_block'
 		let [start, end] = <SID>mg_select_file_block()
 		let selection = getline(start, end)
@@ -797,7 +752,8 @@ endfunction
 " return: no
 function! magit#stage_hunk(discard)
 	try
-		let selection = <SID>mg_select_closed_file()
+		call <SID>mg_stage_closed_file(a:discard)
+		return
 	catch 'out_of_block'
 		try
 			let [start,end] = <SID>mg_select_hunk_block()
@@ -844,7 +800,7 @@ endfunction
 " FIXME: git diff adds some strange characters to end of line
 function! magit#ignore_file() abort
 	let ignore_file=<SID>mg_get_filename()
-	call magit#utils#append_file(magit#utils#top_dir() . ".gitignore",
+	call magit#utils#append_file(magit#git#top_dir() . ".gitignore",
 			\ [ ignore_file ] )
 	call magit#update_buffer()
 endfunction
diff --git a/test/addFile/addFile_modnano_png_commit.expect b/test/addFile/addFile_modnano_png_commit.expect
new file mode 100644
index 0000000000000000000000000000000000000000..44cda0fc19fbfc097363559bf34f44af95860811
--- /dev/null
+++ b/test/addFile/addFile_modnano_png_commit.expect
@@ -0,0 +1,10 @@
+Add bootstrap fileAdd bootstrap file
+
+Some description text
+On multiple lines
+
+With blanks
+
+
+diff --git modnano.png modnano.png
+Binary files modnano.png and modnano.png differ
diff --git a/test/addFile/addFile_modnano_png_file_diff.expect b/test/addFile/addFile_modnano_png_file_diff.expect
new file mode 100644
index 0000000000000000000000000000000000000000..f92b3349379d99e69fe45958a0e77d88c7d4c077
--- /dev/null
+++ b/test/addFile/addFile_modnano_png_file_diff.expect
@@ -0,0 +1,2 @@
+diff --git modnano.png modnano.png
+Binary files modnano.png and modnano.png differ
diff --git a/test/addFile/addFile_modnano_png_unstaged_status.expect b/test/addFile/addFile_modnano_png_unstaged_status.expect
new file mode 100644
index 0000000000000000000000000000000000000000..c93827b0dfd894c7e097de6f92df2af230b42542
--- /dev/null
+++ b/test/addFile/addFile_modnano_png_unstaged_status.expect
@@ -0,0 +1 @@
+ M modnano.png
diff --git a/test/addFile/addFile_nanopdf_png_commit.expect b/test/addFile/addFile_nanopdf_png_commit.expect
new file mode 100644
index 0000000000000000000000000000000000000000..a79399b606d538ab7d6703a00d10341a66a8e89a
--- /dev/null
+++ b/test/addFile/addFile_nanopdf_png_commit.expect
@@ -0,0 +1,11 @@
+Add bootstrap fileAdd bootstrap file
+
+Some description text
+On multiple lines
+
+With blanks
+
+
+diff --git nanopdf.png nanopdf.png
+new file mode 100644
+Binary files /dev/null and nanopdf.png differ
diff --git a/test/addFile/addFile_nanopdf_png_file_diff.expect b/test/addFile/addFile_nanopdf_png_file_diff.expect
new file mode 100644
index 0000000000000000000000000000000000000000..b9902b200a52f209e7ea3b9eaa3724f685ee1230
--- /dev/null
+++ b/test/addFile/addFile_nanopdf_png_file_diff.expect
@@ -0,0 +1,3 @@
+diff --git nanopdf.png nanopdf.png
+new file mode 100644
+Binary files /dev/null and nanopdf.png differ
diff --git a/test/addFile/addFile_nanopdf_png_unstaged_status.expect b/test/addFile/addFile_nanopdf_png_unstaged_status.expect
new file mode 100644
index 0000000000000000000000000000000000000000..b8ee5f543dfaffebd3c8d2786a2daaa50cc539bc
--- /dev/null
+++ b/test/addFile/addFile_nanopdf_png_unstaged_status.expect
@@ -0,0 +1 @@
+?? nanopdf.png
diff --git a/test/run.sh b/test/run.sh
index ded972c6f4a11f0fdbfcd1817ecdca813cedd125..8a4e37488bb8f494bb6873c8744dfa89a8744ce7 100755
--- a/test/run.sh
+++ b/test/run.sh
@@ -26,7 +26,7 @@ fi
 pushd $TEST_PATH
 git config --local user.email 'tester@vimagit.org'
 git config --local user.name 'vimagit tester'
-export TEST_HEAD_SHA1='origin/vimagit_test-1.4'
+export TEST_HEAD_SHA1='origin/vimagit_test-1.4.1'
 git submodule update
 git show $TEST_HEAD_SHA1 --stat
 git reset $TEST_HEAD_SHA1~1 && git status --porcelain && git reset --hard $TEST_HEAD_SHA1
@@ -76,6 +76,7 @@ for script in ${!test_scripts[@]}; do
 				set rtp-=~/.vim/after
 				set rtp+=$VIMAGIT_PATH
 				set rtp+=$VADER_PATH
+				let g:vader_show_version=0
 				filetype plugin indent on
 				syntax enable
 EOF) -c "Vader! $VIMAGIT_PATH/test/$script 2> >(sed -n '/^Starting Vader/,$p')"
diff --git a/test/test.config b/test/test.config
index e1376821a90654cb75c91fca55aaca5cb6b9392f..3b5b21a7878adb11dbd4f7f3122e57cec8d7018d 100644
--- a/test/test.config
+++ b/test/test.config
@@ -1,6 +1,6 @@
 declare -a test_paths=(./ ./books/templates/)
 declare -A test_scripts=(
-            [addFile.vader]='bootstrap;books/models.py;bootstrap.lnk;empty_file;bootstrap\ with\ spaces;bootstrap\ with\ spaces.lnk;empty_file\ with\ spaces'
+            [addFile.vader]='bootstrap;books/models.py;bootstrap.lnk;empty_file;bootstrap\ with\ spaces;bootstrap\ with\ spaces.lnk;empty_file\ with\ spaces;nanopdf.png;modnano.png'
             [addHunk.vader]='bootstrap;books/models.py'
             [addSelect.vader]='books/models.py'
             [renameFile.vader]='manage.py|manage\ with\ spaces.py;djooks/settings\ with\ spaces.py|djooks/settings_without_spaces.py'