Skip to content

Commit

Permalink
feat: add update mode to speed up update
Browse files Browse the repository at this point in the history
Update can be slow, especially when the repository has a lot of (recursive)
submodules. To speed up update, submodules status can be lighter.

By setting update mode to normal, git status performs the default behavior.
By setting update mode to fast, git status will use the option
`--ignore-submodules=dirty`. This option will only search for commit changes
in the submodules. All modified and untracked changes will be ignored.

It is possible to control this option by two ways:
 - globally, by setting the vim option `g:magit_update_mode`
 - at repository level, by setting the git option:
   `git config vimagit.update-mode fast`
 - for the record, it is also possible to set the option globally with git:
   `git config --global vimagit.update-mode fast`

g:magit_update_mode
 * Can be set to 'normal' and 'fast'.
 * Default value is 'normal'.
  • Loading branch information
jerome-reybert-tiempo committed Jan 4, 2024
1 parent 308650d commit 08060ff
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 11 deletions.
19 changes: 11 additions & 8 deletions autoload/magit/git.vim
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@ endfunction
" magit#git#get_status: this function returns the git status output formated
" into a List of Dict as
" [ {staged', 'unstaged', 'filename'}, ... ]
function! magit#git#get_status()
function! magit#git#get_status(update_mode)
let file_list = []

" systemlist v7.4.248 problem again
" 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#sys#systemlist(g:magit_git_cmd . " status --porcelain")
if a:update_mode == 'fast'
let ignore_flag = 'dirty'
else
let ignore_flag = 'none'
endif
let status_list=magit#sys#systemlist(g:magit_git_cmd . " status --porcelain --ignore-submodules=" . ignore_flag)
for file_status_line in status_list
let line_match = matchlist(file_status_line, '\(.\)\(.\) \%(.\{-\} -> \)\?"\?\(.\{-\}\)"\?$')
let filename = line_match[3]
Expand Down Expand Up @@ -153,10 +158,8 @@ endfunction
" untracked content
" param[in] submodule: submodule path
" param[in] check_level: can be modified or untracked
function! magit#git#sub_check(submodule, check_level)
let ignore_flag = ( a:check_level == 'modified' ) ?
\ '--ignore-submodules=untracked' : ''
let git_cmd=g:magit_git_cmd . " status --porcelain " . ignore_flag . " " . a:submodule
function! magit#git#sub_check(submodule, ignore_flag)
let git_cmd=g:magit_git_cmd . " status --porcelain --ignore-submodules=" . a:ignore_flag . " " . a:submodule
return ( !empty(magit#sys#systemlist(git_cmd)) )
endfunction

Expand All @@ -172,10 +175,10 @@ function! magit#git#git_sub_summary(filename, mode)
silent let diff_list=magit#sys#systemlist(git_cmd)
if ( empty(diff_list) )
if ( a:mode == 'unstaged' )
if ( magit#git#sub_check(a:filename, 'modified') )
if ( magit#git#sub_check(a:filename, 'untracked') )
return "modified content"
endif
if ( magit#git#sub_check(a:filename, 'untracked') )
if ( magit#git#sub_check(a:filename, 'none') )
return "untracked content"
endif
endif
Expand Down
2 changes: 1 addition & 1 deletion autoload/magit/state.vim
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ function! magit#state#update() dict
try
call magit#utils#chdir(magit#git#top_dir())
call magit#utils#refresh_submodule_list()
let status_list = magit#git#get_status()
let status_list = magit#git#get_status(b:magit_update_mode)
for [mode, diff_dict_mode] in items(self.dict)
for file_status in status_list
let status=file_status[mode]
Expand Down
1 change: 1 addition & 0 deletions common/magit_common.vim
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let g:magit_section_info = {
\ 'cur_upstream': 'Upstream:',
\ 'cur_push': 'Push:',
\ 'commit_mode': 'Commit mode:',
\ 'update_mode': 'Update mode:',
\ }

let g:magit_git_status_code = {
Expand Down
23 changes: 23 additions & 0 deletions doc/vimagit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,24 @@ section only.

------------------------------------------------------------------------------

UPDATE MODE *vimagit-update-mode*

Update can be slow, especially when the repository has a lot of (recursive)
submodules. To speed up update, submodules status can be lighter.

By setting update mode to normal, git status performs the default behavior.
By setting update mode to fast, git status will use the option
`--ignore-submodules=dirty`. This option will only search for commit changes
in the submodules. All modified and untracked changes will be ignored.

It is possible to control this option by two ways:
- globally, by setting the vim option `g:magit_update_mode`
- at repository level, by setting the git option:
`git config vimagit.update-mode fast`
- for the record, it is also possible to set the option globally with git:
`git config --global vimagit.update-mode fast`

------------------------------------------------------------------------------

AUTOCMD *vimagit-autocmd*

Expand Down Expand Up @@ -517,6 +535,11 @@ empty).
Default value is 0.
let g:magit_auto_close=[01]

*vimagit-g:magit_update_mode*
See |vimagit-update-mode|.
Can be set to 'normal' and 'fast'.
Default value is 'normal'.

===============================================================================
6. FAQ *vimagit-FAQ*

48 changes: 46 additions & 2 deletions plugin/magit.vim
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ let g:magit_default_sections = get(g:, 'magit_default_sections',
let g:magit_discard_untracked_do_delete = get(g:, 'magit_discard_untracked_do_delete', 0)

let g:magit_refresh_gutter = get(g:, 'magit_refresh_gutter' , 1)

let g:magit_update_mode = get(g:, 'magit_update_mode', 'normal')
let g:magit_update_modes = ['normal', 'fast']

" Should deprecate the following
let g:magit_refresh_gitgutter = get(g:, 'magit_refresh_gitgutter', 0)

Expand Down Expand Up @@ -95,7 +99,12 @@ function! s:mg_get_info()
let upstream_msg=s:mg_cut_str(magit#git#get_commit_subject(upstream_br), limit)
let push_msg=s:mg_cut_str(magit#git#get_commit_subject(push_br), limit)

let head_line=magit#utils#strip(printf("%-*s %-*s %s",
let update_msg = ""
if b:magit_last_update_time > 1.0 && b:magit_update_mode_undefined == 1
\ && b:magit_update_mode != 'fast'
let update_msg = "update is slow, consider fast update `:help vimagit-update-mode`"
endif
let head_line=magit#utils#strip(printf("%-*s %-*s %s",
\ align_w, g:magit_section_info.cur_head,
\ max_br_w, head_br, head_msg))
let upstream_line=magit#utils#strip(printf("%-*s %-*s %s",
Expand All @@ -104,7 +113,9 @@ function! s:mg_get_info()
let push_line=magit#utils#strip(printf("%-*s %-*s %s",
\ align_w, g:magit_section_info.cur_push,
\ max_br_w, push_br, push_msg))

let update_line=magit#utils#strip(printf("%-*s %-*s %s",
\ align_w, g:magit_section_info.update_mode,
\ max_br_w, b:magit_update_mode, update_msg))

silent put =g:magit_sections.info
silent put =magit#utils#underline(g:magit_sections.info)
Expand All @@ -113,6 +124,7 @@ function! s:mg_get_info()
silent put =head_line
silent put =upstream_line
silent put =push_line
silent put =update_line

if ( b:magit_current_commit_mode != '' )
let commit_mode_line=printf("%-*s %s",
Expand Down Expand Up @@ -615,7 +627,15 @@ function! magit#update_buffer(...)
let prev_filename = (pos > 0) ? filenames[pos-1] : ''
endif

if has('reltime')
let start_time = reltime()
endif
call b:state.update()
if has('reltime')
let b:magit_last_update_time = reltimefloat(start_time)
else
let b:magit_last_update_time = 0
endif

if ( g:magit_auto_close == 1 &&
\ b:magit_just_commited == 1 &&
Expand Down Expand Up @@ -866,6 +886,30 @@ function! magit#show_magit(display, ...)
return
endif

if index(g:magit_update_modes, g:magit_update_mode) == -1
echohl WarningMsg
echom "g:magit_update_mode='" . g:magit_update_mode . "' must be one of the following: " . join(g:magit_update_modes, ',')
echom "Reset to normal"
echohl None
let g:magit_update_mode = 'normal'
endif

let update_mode = magit#git#get_config('vimagit.update-mode', 'undefined')
if update_mode == 'undefined'
let b:magit_update_mode_undefined = 1
let b:magit_update_mode = g:magit_update_mode
else
let b:magit_update_mode_undefined = 0
if index(g:magit_update_modes, update_mode) == -1
echohl WarningMsg
echom "vimagit.update-mode='" . update_mode . "' (gitconfig) must be one of the following: " . join(g:magit_update_modes, ',')
echom "Reset to g:magit_update_mode"
echohl None
let update_mode = g:magit_update_mode
endif
let b:magit_update_mode = update_mode
endif

let b:state = deepcopy(g:magit#state#state)
call magit#utils#setbufnr(bufnr(buffer_name))
call magit#sign#init()
Expand Down
2 changes: 2 additions & 0 deletions syntax/magit.vim
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ execute 'syn match gitInfoRepo "\%(' . g:magit_section_info.cur_repo . '\)\@<=
execute 'syn match gitInfoHead "\%(' . g:magit_section_info.cur_head . '\s*\)\@<=\S\+" oneline'
execute 'syn match gitInfoUpstream "\%(' . g:magit_section_info.cur_upstream . '\s*\)\@<=\S\+" oneline'
execute 'syn match gitInfoPush "\%(' . g:magit_section_info.cur_push . '\s*\)\@<=\S\+" oneline'
execute 'syn match gitUpdateMode "\%(' . g:magit_section_info.update_mode . '\s*\)\@<=\S\+" oneline'
execute 'syn match gitCommitMode "\%(' . g:magit_section_info.commit_mode . '\)\@<=.*$" oneline'
"execute 'syn match gitInfoCommit "\%(' . g:magit_section_info.cur_commit . '\)\@<=.*$" contains=infoSha1 oneline'
"syntax match infoSha1 containedin=gitInfoCommit "\x\{7,}"
Expand All @@ -47,6 +48,7 @@ highlight default link gitInfoRepo Directory
highlight default link gitInfoHead Identifier
highlight default link gitInfoUpstream Identifier
highlight default link gitInfoPush Identifier
highlight default link gitUpdateMode Identifier
highlight default link gitCommitMode Special
highlight default link infoSha1 Identifier

Expand Down

0 comments on commit 08060ff

Please sign in to comment.