utils 0.0.55 → 0.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/utils/config/vim/doc/fugitive.txt +257 -0
- data/lib/utils/config/vim/plugin/fugitive.vim +422 -84
- data/lib/utils/config/vimrc +28 -16
- data/lib/utils/version.rb +1 -1
- data/utils.gemspec +3 -3
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.56
|
@@ -0,0 +1,257 @@
|
|
1
|
+
*fugitive.txt* A Git wrapper so awesome, it should be illegal
|
2
|
+
|
3
|
+
Author: Tim Pope <vimNOSPAM@tpope.org> *fugitive-author*
|
4
|
+
License: Same terms as Vim itself (see |license|)
|
5
|
+
|
6
|
+
This plugin is only available if 'compatible' is not set.
|
7
|
+
|
8
|
+
INTRODUCTION *fugitive*
|
9
|
+
|
10
|
+
Install in ~/.vim, or in ~\vimfiles if you're on Windows and feeling lucky.
|
11
|
+
Vim 7.2 is recommended as it ships with syntax highlighting for many Git file
|
12
|
+
types.
|
13
|
+
|
14
|
+
If you're in a hurry to get started, here are some things to try:
|
15
|
+
|
16
|
+
In any file in your repository, run |:Gedit| HEAD. Press <CR> to jump to the
|
17
|
+
current branch. Press <CR> again to jump to the top most commit. Keep using
|
18
|
+
<CR> to explore parent commits, trees, and blobs. Use C in a tree or blob to
|
19
|
+
get back to the commit.
|
20
|
+
|
21
|
+
Edit a file in the work tree and make some changes. Use |:Gdiff| to open up
|
22
|
+
the indexed version. Use |do| and |dp| on various hunks to bring the files in
|
23
|
+
sync, or use |:Gread| to pull in all changes. Write the indexed version to
|
24
|
+
stage the file.
|
25
|
+
|
26
|
+
Run |:Gstatus| to check your repository's status. Use "-" to stage and reset
|
27
|
+
files and "p" to add/reset --patch them. Invoke |:Gcommit| to commit your
|
28
|
+
changes.
|
29
|
+
|
30
|
+
Run |:Gblame| in a work tree file to see a blame in a vertical split. Press
|
31
|
+
<CR> on any line to reopen and reblame that file as it stood in that commit.
|
32
|
+
Press o or O on any line to inspect that commit in a split or a tab.
|
33
|
+
|
34
|
+
Run |:Ggrep| to search the work tree or history. Run |:Gmove| to rename a
|
35
|
+
file. Run |:Gremove| to delete a file.
|
36
|
+
|
37
|
+
COMMANDS *fugitive-commands*
|
38
|
+
|
39
|
+
These commands are local to the buffers in which they work (generally, buffers
|
40
|
+
that are part of Git repositories).
|
41
|
+
|
42
|
+
*fugitive-:Git*
|
43
|
+
:Git [args] Run an arbitrary git command. Similar to :!git [args]
|
44
|
+
but chdir to the repository tree first.
|
45
|
+
|
46
|
+
*fugitive-:Gcd*
|
47
|
+
:Gcd [directory] |:cd| relative to the repository.
|
48
|
+
|
49
|
+
*fugitive-:Glcd*
|
50
|
+
:Glcd [directory] |:lcd| relative to the repository.
|
51
|
+
|
52
|
+
*fugitive-:Gstatus*
|
53
|
+
:Gstatus Bring up the output of git-status in the preview
|
54
|
+
window. In addition to standard motions, you can
|
55
|
+
use <C-N> and <C-P> to jump from filename to
|
56
|
+
filename. Press C to invoke |:Gcommit|. Press D to
|
57
|
+
|:Gdiff| the file on the cursor line, or ds to
|
58
|
+
|:Gsdiff|. Press - to stage or unstage the file on
|
59
|
+
the cursor line. Press p to do so on a per hunk basis
|
60
|
+
(--patch). All of D, -, and p have a different,
|
61
|
+
sensible (and hopefully intuitive) behavior when
|
62
|
+
invoked on a heading rather than a file name.
|
63
|
+
|
64
|
+
*fugitive-:Gcommit*
|
65
|
+
:Gcommit [args] A wrapper around git-commit. If there is nothing
|
66
|
+
to commit, |:Gstatus| is called instead. Unless the
|
67
|
+
arguments given would skip the invocation of an editor
|
68
|
+
(e.g., -m), a split window will be used to obtain a
|
69
|
+
commit message. Write and close that window (:wq or
|
70
|
+
|:Gwrite|) to finish the commit. Unlike when running
|
71
|
+
the actual git-commit command, it is possible (but
|
72
|
+
unadvisable) to muck with the index with commands like
|
73
|
+
git-add and git-reset while a commit message is
|
74
|
+
pending.
|
75
|
+
|
76
|
+
*fugitive-:Ggrep*
|
77
|
+
:Ggrep [args] |:grep| with git-grep as 'grepprg'.
|
78
|
+
|
79
|
+
*fugitive-:Glog*
|
80
|
+
:Glog [args] Load all previous revisions of the current file into
|
81
|
+
the quickfix list. Additional git-log arguments can
|
82
|
+
be given (for example, --reverse). If "--" appears as
|
83
|
+
an argument, no file specific filtering is done, and
|
84
|
+
commits are loaded into the quickfix list.
|
85
|
+
|
86
|
+
*fugitive-:Gedit* *fugitive-:Ge*
|
87
|
+
:Gedit [revision] |:edit| a |fugitive-revision|.
|
88
|
+
|
89
|
+
*fugitive-:Gsplit*
|
90
|
+
:Gsplit [revision] |:split| a |fugitive-revision|.
|
91
|
+
|
92
|
+
*fugitive-:Gvsplit*
|
93
|
+
:Gvsplit [revision] |:vsplit| a |fugitive-revision|.
|
94
|
+
|
95
|
+
*fugitive-:Gtabedit*
|
96
|
+
:Gtabedit [revision] |:tabedit| a |fugitive-revision|
|
97
|
+
|
98
|
+
*fugitive-:Gpedit*
|
99
|
+
:Gpedit [revision] |:pedit| a |fugitive-revision|
|
100
|
+
|
101
|
+
*fugitive-:Gread*
|
102
|
+
:Gread [revision] Empty the buffer and |:read| a |fugitive-revision|.
|
103
|
+
When the argument is omitted, this is similar to
|
104
|
+
git-checkout on a work tree file or git-add on a stage
|
105
|
+
file, but without writing anything to disk.
|
106
|
+
|
107
|
+
:{range}Gread [revision]
|
108
|
+
|:read| in a |fugitive-revision| after {range}.
|
109
|
+
|
110
|
+
*fugitive-:Gwrite*
|
111
|
+
:Gwrite Write to the current file's path and stage the results.
|
112
|
+
When run in a work tree file, it is effectively git
|
113
|
+
add. Elsewhere, it is effectively git-checkout. A
|
114
|
+
great deal of effort is expended to behave sensibly
|
115
|
+
when the work tree or index version of the file is
|
116
|
+
open in another buffer.
|
117
|
+
|
118
|
+
:Gwrite {path} You can give |:Gwrite| an explicit path of where in
|
119
|
+
the work tree to write. You can also give a path like
|
120
|
+
:0:foo.txt or even :0 to write to just that stage in
|
121
|
+
the index.
|
122
|
+
|
123
|
+
*fugitive-:Gwq*
|
124
|
+
:Gwq [path] Like |:Gwrite| followed by |:quit| if the write
|
125
|
+
succeeded.
|
126
|
+
|
127
|
+
:Gwq! [path] Like |:Gwrite|! followed by |:quit|! if the write
|
128
|
+
succeeded.
|
129
|
+
|
130
|
+
*fugitive-:Gdiff*
|
131
|
+
:Gdiff [revision] Perform a |vimdiff| against the current file in the
|
132
|
+
given revision. With no argument, the version in the
|
133
|
+
index is used (which means a three-way diff during a
|
134
|
+
merge conflict, making it a git-mergetool
|
135
|
+
alternative). The newer of the two files is placed
|
136
|
+
to the right. Use |do| and |dp| and write to the
|
137
|
+
index file to simulate "git add --patch".
|
138
|
+
|
139
|
+
*fugitive-:Gsdiff*
|
140
|
+
:Gsdiff [revision] Like |:Gdiff|, but split horizontally.
|
141
|
+
|
142
|
+
*fugitive-:Gvdiff*
|
143
|
+
:Gvdiff [revision] Identical to |:Gdiff|. For symmetry with |:Gsdiff|.
|
144
|
+
|
145
|
+
*fugitive-:Gmove*
|
146
|
+
:Gmove {destination} Wrapper around git-mv that renames the buffer
|
147
|
+
afterward. The destination is relative to the current
|
148
|
+
directory except when started with a /, in which case
|
149
|
+
it is relative to the work tree. Add a ! to pass -f.
|
150
|
+
|
151
|
+
*fugitive-:Gremove*
|
152
|
+
:Gremove Wrapper around git-rm that deletes the buffer
|
153
|
+
afterward. When invoked in an index file, --cached is
|
154
|
+
passed. Add a ! to pass -f and forcefully discard the
|
155
|
+
buffer.
|
156
|
+
|
157
|
+
*fugitive-:Gblame*
|
158
|
+
:Gblame [flags] Run git-blame on the file and open the results in a
|
159
|
+
scroll bound vertical split. Press enter on a line to
|
160
|
+
reblame the file as it was in that commit. You can
|
161
|
+
give any of ltwfsMC as flags and they will be passed
|
162
|
+
along to git-blame.
|
163
|
+
|
164
|
+
:[range]Gblame [flags] Run git-blame on the given range.
|
165
|
+
|
166
|
+
*fugitive-:Gbrowse*
|
167
|
+
:[range]Gbrowse If the remote for the current branch is on GitHub,
|
168
|
+
open the current file, blob, tree, commit, or tag
|
169
|
+
(with git-web--browse) on GitHub. Otherwise, open the
|
170
|
+
current file, blob, tree, commit, or tag in
|
171
|
+
git-instaweb (if you have issues, verify you can run
|
172
|
+
"git instaweb" from a terminal). If a range is given,
|
173
|
+
it is appropriately appended to the URL as an anchor.
|
174
|
+
|
175
|
+
:[range]Gbrowse! Like :Gbrowse, but put the URL on the clipboard rather
|
176
|
+
than opening it.
|
177
|
+
|
178
|
+
:[range]Gbrowse {revision}
|
179
|
+
Like :Gbrowse, but for a given |fugitive-revision|. A
|
180
|
+
useful value here is -, which ties the URL to the
|
181
|
+
latest commit rather than a volatile branch.
|
182
|
+
|
183
|
+
:[range]Gbrowse [...]@{remote}
|
184
|
+
Force using the given remote rather than the remote
|
185
|
+
for the current branch. The remote is used to
|
186
|
+
determine which GitHub repository to link to.
|
187
|
+
|
188
|
+
MAPPINGS *fugitive-mappings*
|
189
|
+
|
190
|
+
These maps are available in Git objects.
|
191
|
+
|
192
|
+
*fugitive-<CR>*
|
193
|
+
<CR> Jump to the revision under the cursor.
|
194
|
+
|
195
|
+
*fugitive-o*
|
196
|
+
o Jump to the revision under the cursor in a new split.
|
197
|
+
|
198
|
+
*fugitive-O*
|
199
|
+
O Jump to the revision under the cursor in a new tab.
|
200
|
+
|
201
|
+
*fugitive-~*
|
202
|
+
~ Go to the current file in the [count]th first
|
203
|
+
ancestor.
|
204
|
+
|
205
|
+
*fugitive-P*
|
206
|
+
P Go to the current file in the [count]th parent.
|
207
|
+
|
208
|
+
*fugitive-C*
|
209
|
+
C Go to the commit containing the current file.
|
210
|
+
|
211
|
+
*fugitive-a*
|
212
|
+
a Show the current tag, commit, or tree in an alternate
|
213
|
+
format.
|
214
|
+
|
215
|
+
SPECIFYING REVISIONS *fugitive-revision*
|
216
|
+
|
217
|
+
Fugitive revisions are similar to Git revisions as defined in the "SPECIFYING
|
218
|
+
REVISIONS" section in the git-rev-parse man page. For commands that accept an
|
219
|
+
optional revision, the default is the file in the index for work tree files
|
220
|
+
and the work tree file for everything else. Example revisions follow.
|
221
|
+
|
222
|
+
Revision Meaning ~
|
223
|
+
HEAD .git/HEAD
|
224
|
+
master .git/refs/heads/master
|
225
|
+
HEAD^{} The commit referenced by HEAD
|
226
|
+
HEAD^ The parent of the commit referenced by HEAD
|
227
|
+
HEAD: The tree referenced by HEAD
|
228
|
+
/HEAD The file named HEAD in the work tree
|
229
|
+
Makefile The file named Makefile in the work tree
|
230
|
+
HEAD^:Makefile The file named Makefile in the parent of HEAD
|
231
|
+
:Makefile The file named Makefile in the index (writable)
|
232
|
+
- The current file in HEAD
|
233
|
+
^ The current file in the previous commit
|
234
|
+
~3 The current file 3 commits ago
|
235
|
+
: .git/index (Same as |:Gstatus|)
|
236
|
+
:0 The current file in the index
|
237
|
+
:1 The current file's common ancestor during a conflict
|
238
|
+
:2 The current file in the target branch during a conflict
|
239
|
+
:3 The current file in the merged branch during a conflict
|
240
|
+
:/foo The most recent commit with "foo" in the message
|
241
|
+
|
242
|
+
STATUSLINE *fugitive-statusline*
|
243
|
+
|
244
|
+
*fugitive#statusline()*
|
245
|
+
Add %{fugitive#statusline()} to your statusline to get an indicator including
|
246
|
+
the current branch and the currently edited file's commit. If you don't have
|
247
|
+
a statusline, this one matches the default when 'ruler' is set:
|
248
|
+
>
|
249
|
+
set statusline=%<%f\ %h%m%r%{fugitive#statusline()}%=%-14.(%l,%c%V%)\ %P
|
250
|
+
<
|
251
|
+
ABOUT *fugitive-about*
|
252
|
+
|
253
|
+
Grab the latest version or report a bug on GitHub:
|
254
|
+
|
255
|
+
http://github.com/tpope/vim-fugitive
|
256
|
+
|
257
|
+
vim:tw=78:et:ft=help:norl:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
" fugitive.vim - A Git wrapper so awesome, it should be illegal
|
2
2
|
" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
|
3
|
-
" Version: 1.
|
3
|
+
" Version: 1.2
|
4
4
|
" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim
|
5
5
|
|
6
6
|
if exists('g:loaded_fugitive') || &cp
|
@@ -108,7 +108,7 @@ function! s:ExtractGitDir(path) abort
|
|
108
108
|
let ofn = ""
|
109
109
|
let nfn = fn
|
110
110
|
while fn != ofn
|
111
|
-
if
|
111
|
+
if filereadable(fn . '/.git/HEAD')
|
112
112
|
return s:sub(simplify(fnamemodify(fn . '/.git',':p')),'\W$','')
|
113
113
|
elseif fn =~ '\.git$' && filereadable(fn . '/HEAD')
|
114
114
|
return s:sub(simplify(fnamemodify(fn,':p')),'\W$','')
|
@@ -132,19 +132,25 @@ function! s:Detect(path)
|
|
132
132
|
if exists('b:git_dir')
|
133
133
|
silent doautocmd User Fugitive
|
134
134
|
cnoremap <expr> <buffer> <C-R><C-G> fugitive#buffer().rev()
|
135
|
+
let buffer = fugitive#buffer()
|
135
136
|
if expand('%:p') =~# '//'
|
136
|
-
let buffer = fugitive#buffer()
|
137
137
|
call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)',''))
|
138
138
|
endif
|
139
|
+
if b:git_dir !~# ',' && stridx(buffer.getvar('&tags'),b:git_dir.'/tags') == -1
|
140
|
+
if &filetype != ''
|
141
|
+
call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/'.&filetype.'.tags')
|
142
|
+
endif
|
143
|
+
call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/tags')
|
144
|
+
endif
|
139
145
|
endif
|
140
146
|
endfunction
|
141
147
|
|
142
148
|
augroup fugitive
|
143
149
|
autocmd!
|
144
150
|
autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
|
145
|
-
autocmd FileType netrw call s:Detect(expand('<
|
151
|
+
autocmd FileType netrw call s:Detect(expand('<afile>:p'))
|
146
152
|
autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
|
147
|
-
autocmd BufWinLeave * execute
|
153
|
+
autocmd BufWinLeave * execute getwinvar(+winnr(), 'fugitive_restore')
|
148
154
|
augroup END
|
149
155
|
|
150
156
|
" }}}1
|
@@ -248,8 +254,8 @@ endfunction
|
|
248
254
|
|
249
255
|
function! s:repo_rev_parse(rev) dict abort
|
250
256
|
let hash = self.git_chomp('rev-parse','--verify',a:rev)
|
251
|
-
if hash =~ '
|
252
|
-
return hash
|
257
|
+
if hash =~ '\<\x\{40\}$'
|
258
|
+
return matchstr(hash,'\<\x\{40\}$')
|
253
259
|
endif
|
254
260
|
call s:throw('rev-parse '.a:rev.': '.hash)
|
255
261
|
endfunction
|
@@ -351,7 +357,7 @@ endfunction
|
|
351
357
|
function! s:buffer_type(...) dict abort
|
352
358
|
if self.getvar('fugitive_type') != ''
|
353
359
|
let type = self.getvar('fugitive_type')
|
354
|
-
elseif fnamemodify(self.
|
360
|
+
elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$'
|
355
361
|
let type = 'head'
|
356
362
|
elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == ''
|
357
363
|
let type = 'tree'
|
@@ -359,11 +365,11 @@ function! s:buffer_type(...) dict abort
|
|
359
365
|
let type = 'tree'
|
360
366
|
elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t'
|
361
367
|
let type = 'index'
|
362
|
-
elseif isdirectory(self.
|
368
|
+
elseif isdirectory(self.spec())
|
363
369
|
let type = 'directory'
|
364
|
-
elseif self.
|
370
|
+
elseif self.spec() == ''
|
365
371
|
let type = 'null'
|
366
|
-
elseif filereadable(self.
|
372
|
+
elseif filereadable(self.spec())
|
367
373
|
let type = 'file'
|
368
374
|
else
|
369
375
|
let type = ''
|
@@ -375,42 +381,61 @@ function! s:buffer_type(...) dict abort
|
|
375
381
|
endif
|
376
382
|
endfunction
|
377
383
|
|
384
|
+
if has('win32')
|
385
|
+
|
386
|
+
function! s:buffer_spec() dict abort
|
387
|
+
let bufname = bufname(self['#'])
|
388
|
+
let retval = ''
|
389
|
+
for i in split(bufname,'[^:]\zs\\')
|
390
|
+
let retval = fnamemodify((retval==''?'':retval.'\').i,':.')
|
391
|
+
endfor
|
392
|
+
return s:shellslash(fnamemodify(retval,':p'))
|
393
|
+
endfunction
|
394
|
+
|
395
|
+
else
|
396
|
+
|
397
|
+
function! s:buffer_spec() dict abort
|
398
|
+
let bufname = bufname(self['#'])
|
399
|
+
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
400
|
+
endfunction
|
401
|
+
|
402
|
+
endif
|
403
|
+
|
378
404
|
function! s:buffer_name() dict abort
|
379
|
-
|
380
|
-
return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p'))
|
405
|
+
return self.spec()
|
381
406
|
endfunction
|
382
407
|
|
383
408
|
function! s:buffer_commit() dict abort
|
384
|
-
return matchstr(self.
|
409
|
+
return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
|
385
410
|
endfunction
|
386
411
|
|
387
412
|
function! s:buffer_path(...) dict abort
|
388
|
-
let rev = matchstr(self.
|
413
|
+
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
389
414
|
if rev != ''
|
390
415
|
let rev = s:sub(rev,'\w*','')
|
391
416
|
else
|
392
|
-
let rev = self.
|
417
|
+
let rev = self.spec()[strlen(self.repo().tree()) : -1]
|
393
418
|
endif
|
394
|
-
return s:sub(rev,'^/',a:0 ? a:1 : '')
|
419
|
+
return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
|
395
420
|
endfunction
|
396
421
|
|
397
422
|
function! s:buffer_rev() dict abort
|
398
|
-
let rev = matchstr(self.
|
423
|
+
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
399
424
|
if rev =~ '^\x/'
|
400
425
|
return ':'.rev[0].':'.rev[2:-1]
|
401
426
|
elseif rev =~ '.'
|
402
427
|
return s:sub(rev,'/',':')
|
403
|
-
elseif self.
|
428
|
+
elseif self.spec() =~ '\.git/index$'
|
404
429
|
return ':'
|
405
|
-
elseif self.
|
406
|
-
return self.
|
430
|
+
elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
431
|
+
return self.spec()[strlen(self.repo().dir())+1 : -1]
|
407
432
|
else
|
408
433
|
return self.path()
|
409
434
|
endif
|
410
435
|
endfunction
|
411
436
|
|
412
437
|
function! s:buffer_sha1() dict abort
|
413
|
-
if self.
|
438
|
+
if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
414
439
|
return self.repo().rev_parse(self.rev())
|
415
440
|
else
|
416
441
|
return ''
|
@@ -420,6 +445,8 @@ endfunction
|
|
420
445
|
function! s:buffer_expand(rev) dict abort
|
421
446
|
if a:rev =~# '^:[0-3]$'
|
422
447
|
let file = a:rev.self.path(':')
|
448
|
+
elseif a:rev =~# '^[-:]/$'
|
449
|
+
let file = '/'.self.path()
|
423
450
|
elseif a:rev =~# '^-'
|
424
451
|
let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
|
425
452
|
elseif a:rev =~# '^@{'
|
@@ -430,7 +457,7 @@ function! s:buffer_expand(rev) dict abort
|
|
430
457
|
else
|
431
458
|
let file = a:rev
|
432
459
|
endif
|
433
|
-
return s:sub(file,'\%$',self.path())
|
460
|
+
return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','')
|
434
461
|
endfunction
|
435
462
|
|
436
463
|
function! s:buffer_containing_commit() dict abort
|
@@ -443,7 +470,7 @@ function! s:buffer_containing_commit() dict abort
|
|
443
470
|
endif
|
444
471
|
endfunction
|
445
472
|
|
446
|
-
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','name','commit','path','rev','sha1','expand','containing_commit'])
|
473
|
+
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit'])
|
447
474
|
|
448
475
|
" }}}1
|
449
476
|
" Git {{{1
|
@@ -538,10 +565,11 @@ function! fugitive#reload_status() abort
|
|
538
565
|
endfor
|
539
566
|
endfunction
|
540
567
|
|
541
|
-
function! s:StageDiff() abort
|
568
|
+
function! s:StageDiff(...) abort
|
569
|
+
let cmd = a:0 ? a:1 : 'Gdiff'
|
542
570
|
let section = getline(search('^# .*:$','bnW'))
|
543
571
|
let line = getline('.')
|
544
|
-
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs
|
572
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
|
545
573
|
if filename ==# '' && section == '# Changes to be committed:'
|
546
574
|
return 'Git diff --cached'
|
547
575
|
elseif filename ==# ''
|
@@ -549,13 +577,13 @@ function! s:StageDiff() abort
|
|
549
577
|
elseif line =~# '^#\trenamed:' && filename =~ ' -> '
|
550
578
|
let [old, new] = split(filename,' -> ')
|
551
579
|
execute 'Gedit '.s:fnameescape(':0:'.new)
|
552
|
-
return '
|
580
|
+
return cmd.' HEAD:'.s:fnameescape(old)
|
553
581
|
elseif section == '# Changes to be committed:'
|
554
582
|
execute 'Gedit '.s:fnameescape(':0:'.filename)
|
555
|
-
return '
|
583
|
+
return cmd.' -'
|
556
584
|
else
|
557
585
|
execute 'Gedit '.s:fnameescape('/'.filename)
|
558
|
-
return
|
586
|
+
return cmd
|
559
587
|
endif
|
560
588
|
endfunction
|
561
589
|
|
@@ -564,10 +592,34 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
564
592
|
let output = ''
|
565
593
|
for lnum in range(a:lnum1,a:lnum2)
|
566
594
|
let line = getline(lnum)
|
567
|
-
|
568
|
-
|
595
|
+
let repo = s:repo()
|
596
|
+
if line ==# '# Changes to be committed:'
|
597
|
+
call repo.git_chomp_in_tree('reset','-q')
|
598
|
+
silent! edit!
|
599
|
+
1
|
600
|
+
if !search('^# Untracked files:$','W')
|
601
|
+
call search('^# Change','W')
|
602
|
+
endif
|
603
|
+
return ''
|
604
|
+
elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
|
605
|
+
call repo.git_chomp_in_tree('add','-u')
|
606
|
+
silent! edit!
|
607
|
+
1
|
608
|
+
if !search('^# Untracked files:$','W')
|
609
|
+
call search('^# Change','W')
|
610
|
+
endif
|
611
|
+
return ''
|
612
|
+
elseif line ==# '# Untracked files:'
|
613
|
+
" Work around Vim parser idiosyncrasy
|
614
|
+
call repo.git_chomp_in_tree('add','-N','.')
|
615
|
+
silent! edit!
|
616
|
+
1
|
617
|
+
if !search('^# Change\%(d but not updated\|s not staged for commit\):$','W')
|
618
|
+
call search('^# Change','W')
|
619
|
+
endif
|
620
|
+
return ''
|
569
621
|
endif
|
570
|
-
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs
|
622
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (\a\+ [[:alpha:], ]\+)\)\=$')
|
571
623
|
if filename ==# ''
|
572
624
|
continue
|
573
625
|
endif
|
@@ -586,7 +638,7 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
586
638
|
else
|
587
639
|
let cmd = ['add','--',filename]
|
588
640
|
endif
|
589
|
-
let output .= call(
|
641
|
+
let output .= call(repo.git_chomp_in_tree,cmd,s:repo())."\n"
|
590
642
|
endfor
|
591
643
|
if exists('first_filename')
|
592
644
|
let jump = first_filename
|
@@ -597,7 +649,7 @@ function! s:StageToggle(lnum1,lnum2) abort
|
|
597
649
|
silent! edit!
|
598
650
|
1
|
599
651
|
redraw
|
600
|
-
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'
|
652
|
+
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\%( (new commits)\)\=\$','W')
|
601
653
|
endif
|
602
654
|
echo s:sub(s:gsub(output,'\n+','\n'),'\n$','')
|
603
655
|
catch /^fugitive:/
|
@@ -612,12 +664,12 @@ function! s:StagePatch(lnum1,lnum2) abort
|
|
612
664
|
|
613
665
|
for lnum in range(a:lnum1,a:lnum2)
|
614
666
|
let line = getline(lnum)
|
615
|
-
if line
|
667
|
+
if line ==# '# Changes to be committed:'
|
616
668
|
return 'Git reset --patch'
|
617
|
-
elseif line
|
669
|
+
elseif line =~# '^# Change\%(d but not updated\|s not staged for commit\):$'
|
618
670
|
return 'Git add --patch'
|
619
671
|
endif
|
620
|
-
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs
|
672
|
+
let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$')
|
621
673
|
if filename ==# ''
|
622
674
|
continue
|
623
675
|
endif
|
@@ -645,7 +697,7 @@ function! s:StagePatch(lnum1,lnum2) abort
|
|
645
697
|
silent! edit!
|
646
698
|
1
|
647
699
|
redraw
|
648
|
-
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'
|
700
|
+
call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\%( (new commits)\)\=\$','W')
|
649
701
|
endif
|
650
702
|
catch /^fugitive:/
|
651
703
|
return 'echoerr v:errmsg'
|
@@ -667,16 +719,16 @@ function! s:Commit(args) abort
|
|
667
719
|
let errorfile = tempname()
|
668
720
|
try
|
669
721
|
execute cd.'`=s:repo().tree()`'
|
670
|
-
let command = ''
|
671
722
|
if &shell =~# 'cmd'
|
723
|
+
let command = ''
|
672
724
|
let old_editor = $GIT_EDITOR
|
673
725
|
let $GIT_EDITOR = 'false'
|
674
|
-
|
675
|
-
let command = 'GIT_EDITOR=false '
|
726
|
+
else
|
727
|
+
let command = 'env GIT_EDITOR=false '
|
676
728
|
endif
|
677
729
|
let command .= s:repo().git_command('commit').' '.a:args
|
678
730
|
if &shell =~# 'csh'
|
679
|
-
silent execute '!
|
731
|
+
silent execute '!('.command.' > '.outfile.') >& '.errorfile
|
680
732
|
elseif a:args =~# '\%(^\| \)--interactive\>'
|
681
733
|
execute '!'.command.' 2> '.errorfile
|
682
734
|
else
|
@@ -690,8 +742,9 @@ function! s:Commit(args) abort
|
|
690
742
|
endif
|
691
743
|
return ''
|
692
744
|
else
|
693
|
-
let
|
694
|
-
|
745
|
+
let errors = readfile(errorfile)
|
746
|
+
let error = get(errors,-2,get(errors,-1,'!'))
|
747
|
+
if error =~# '\<false''\=\.$'
|
695
748
|
let args = a:args
|
696
749
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[se]|--edit|--interactive)%($| )','')
|
697
750
|
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
|
@@ -700,13 +753,14 @@ function! s:Commit(args) abort
|
|
700
753
|
if args !~# '\%(^\| \)--cleanup\>'
|
701
754
|
let args = '--cleanup=strip '.args
|
702
755
|
endif
|
756
|
+
let old_nr = bufnr('')
|
703
757
|
if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod
|
704
758
|
edit `=msgfile`
|
705
759
|
else
|
706
|
-
split `=msgfile`
|
760
|
+
keepalt split `=msgfile`
|
707
761
|
endif
|
708
762
|
if old_type ==# 'index'
|
709
|
-
bdelete
|
763
|
+
execute 'bdelete '.old_nr
|
710
764
|
endif
|
711
765
|
let b:fugitive_commit_arguments = args
|
712
766
|
setlocal bufhidden=delete filetype=gitcommit
|
@@ -741,7 +795,6 @@ endfunction
|
|
741
795
|
|
742
796
|
function! s:FinishCommit()
|
743
797
|
let args = getbufvar(+expand('<abuf>'),'fugitive_commit_arguments')
|
744
|
-
let g:args = args
|
745
798
|
if !empty(args)
|
746
799
|
call setbufvar(+expand('<abuf>'),'fugitive_commit_arguments','')
|
747
800
|
return s:Commit(args)
|
@@ -849,11 +902,8 @@ function! s:Edit(cmd,...) abort
|
|
849
902
|
catch /^fugitive:/
|
850
903
|
return 'echoerr v:errmsg'
|
851
904
|
endtry
|
852
|
-
if a:cmd
|
853
|
-
|
854
|
-
call s:warn(':Gread! is deprecated. Use :Gread')
|
855
|
-
endif
|
856
|
-
return 'silent %delete|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
905
|
+
if a:cmd ==# 'read'
|
906
|
+
return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.')
|
857
907
|
else
|
858
908
|
if &previewwindow && getbufvar('','fugitive_type') ==# 'index'
|
859
909
|
wincmd p
|
@@ -875,9 +925,11 @@ call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit
|
|
875
925
|
call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((!<count> && <line1> ? '' : <count>).'read<bang>',<f-args>)")
|
876
926
|
|
877
927
|
" }}}1
|
878
|
-
" Gwrite {{{1
|
928
|
+
" Gwrite, Gwq {{{1
|
879
929
|
|
880
930
|
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(<bang>0,<f-args>)")
|
931
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gw :execute s:Write(<bang>0,<f-args>)")
|
932
|
+
call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwq :execute s:Wq(<bang>0,<f-args>)")
|
881
933
|
|
882
934
|
function! s:Write(force,...) abort
|
883
935
|
if exists('b:fugitive_commit_arguments')
|
@@ -941,7 +993,11 @@ function! s:Write(force,...) abort
|
|
941
993
|
execute 'write! '.s:fnameescape(s:repo().translate(path))
|
942
994
|
endif
|
943
995
|
|
944
|
-
|
996
|
+
if a:force
|
997
|
+
let error = s:repo().git_chomp_in_tree('add', '--force', file)
|
998
|
+
else
|
999
|
+
let error = s:repo().git_chomp_in_tree('add', file)
|
1000
|
+
endif
|
945
1001
|
if v:shell_error
|
946
1002
|
let v:errmsg = 'fugitive: '.error
|
947
1003
|
return 'echoerr v:errmsg'
|
@@ -993,16 +1049,57 @@ function! s:Write(force,...) abort
|
|
993
1049
|
return 'checktime'
|
994
1050
|
endfunction
|
995
1051
|
|
1052
|
+
function! s:Wq(force,...) abort
|
1053
|
+
let bang = a:force ? '!' : ''
|
1054
|
+
if exists('b:fugitive_commit_arguments')
|
1055
|
+
return 'wq'.bang
|
1056
|
+
endif
|
1057
|
+
let result = call(s:function('s:Write'),[a:force]+a:000)
|
1058
|
+
if result =~# '^\%(write\|wq\|echoerr\)'
|
1059
|
+
return s:sub(result,'^write','wq')
|
1060
|
+
else
|
1061
|
+
return result.'|quit'.bang
|
1062
|
+
endif
|
1063
|
+
endfunction
|
1064
|
+
|
996
1065
|
" }}}1
|
997
1066
|
" Gdiff {{{1
|
998
1067
|
|
999
|
-
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<f-args>)")
|
1068
|
+
call s:command("-bang -bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(<bang>0,<f-args>)")
|
1069
|
+
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gvdiff :execute s:Diff(0,<f-args>)")
|
1070
|
+
call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gsdiff :execute s:Diff(1,<f-args>)")
|
1000
1071
|
|
1001
1072
|
augroup fugitive_diff
|
1002
|
-
autocmd
|
1003
|
-
autocmd
|
1073
|
+
autocmd!
|
1074
|
+
autocmd BufWinLeave * if s:diff_window_count() == 2 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | call s:diff_off_all(getbufvar(+expand('<abuf>'), 'git_dir')) | endif
|
1075
|
+
autocmd BufWinEnter * if s:diff_window_count() == 1 && &diff && getbufvar(+expand('<abuf>'), 'git_dir') !=# '' | diffoff | endif
|
1004
1076
|
augroup END
|
1005
1077
|
|
1078
|
+
function! s:diff_window_count()
|
1079
|
+
let c = 0
|
1080
|
+
for nr in range(1,winnr('$'))
|
1081
|
+
let c += getwinvar(nr,'&diff')
|
1082
|
+
endfor
|
1083
|
+
return c
|
1084
|
+
endfunction
|
1085
|
+
|
1086
|
+
function! s:diff_off_all(dir)
|
1087
|
+
for nr in range(1,winnr('$'))
|
1088
|
+
if getwinvar(nr,'&diff')
|
1089
|
+
if nr != winnr()
|
1090
|
+
execute nr.'wincmd w'
|
1091
|
+
let restorewinnr = 1
|
1092
|
+
endif
|
1093
|
+
if exists('b:git_dir') && b:git_dir ==# a:dir
|
1094
|
+
diffoff
|
1095
|
+
endif
|
1096
|
+
if exists('restorewinnr')
|
1097
|
+
wincmd p
|
1098
|
+
endif
|
1099
|
+
endif
|
1100
|
+
endfor
|
1101
|
+
endfunction
|
1102
|
+
|
1006
1103
|
function! s:buffer_compare_age(commit) dict abort
|
1007
1104
|
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
1008
1105
|
let my_score = get(scores,':'.self.commit(),0)
|
@@ -1025,18 +1122,22 @@ endfunction
|
|
1025
1122
|
|
1026
1123
|
call s:add_methods('buffer',['compare_age'])
|
1027
1124
|
|
1028
|
-
function! s:Diff(
|
1125
|
+
function! s:Diff(bang,...) abort
|
1126
|
+
let split = a:bang ? 'split' : 'vsplit'
|
1029
1127
|
if exists(':DiffGitCached')
|
1030
1128
|
return 'DiffGitCached'
|
1031
1129
|
elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1130
|
+
let nr = bufnr('')
|
1131
|
+
execute 'leftabove '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`'
|
1132
|
+
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
1133
|
+
diffthis
|
1134
|
+
wincmd p
|
1135
|
+
execute 'rightbelow '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`'
|
1136
|
+
execute 'nnoremap <buffer> <silent> dp :diffput '.nr.'<Bar>diffupdate<CR>'
|
1137
|
+
diffthis
|
1138
|
+
wincmd p
|
1139
|
+
diffthis
|
1140
|
+
return ''
|
1040
1141
|
elseif a:0
|
1041
1142
|
if a:1 ==# ''
|
1042
1143
|
return ''
|
@@ -1044,7 +1145,7 @@ function! s:Diff(...) abort
|
|
1044
1145
|
let file = s:buffer().path('/')
|
1045
1146
|
elseif a:1 ==# ':'
|
1046
1147
|
let file = s:buffer().path(':0:')
|
1047
|
-
elseif a:1 =~# '
|
1148
|
+
elseif a:1 =~# '^:/.'
|
1048
1149
|
try
|
1049
1150
|
let file = s:repo().rev_parse(a:1).s:buffer().path(':')
|
1050
1151
|
catch /^fugitive:/
|
@@ -1063,9 +1164,9 @@ function! s:Diff(...) abort
|
|
1063
1164
|
let spec = s:repo().translate(file)
|
1064
1165
|
let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
|
1065
1166
|
if s:buffer().compare_age(commit) < 0
|
1066
|
-
rightbelow
|
1167
|
+
execute 'rightbelow '.split.' `=spec`'
|
1067
1168
|
else
|
1068
|
-
leftabove
|
1169
|
+
execute 'leftabove '.split.' `=spec`'
|
1069
1170
|
endif
|
1070
1171
|
diffthis
|
1071
1172
|
wincmd p
|
@@ -1088,6 +1189,10 @@ function! s:Move(force,destination)
|
|
1088
1189
|
let destination = destination[strlen(s:repo().tree('')):-1]
|
1089
1190
|
endif
|
1090
1191
|
endif
|
1192
|
+
if isdirectory(s:buffer().name())
|
1193
|
+
" Work around Vim parser idiosyncrasy
|
1194
|
+
let discarded = s:buffer().setvar('&swapfile',0)
|
1195
|
+
endif
|
1091
1196
|
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
|
1092
1197
|
if v:shell_error
|
1093
1198
|
let v:errmsg = 'fugitive: '.message
|
@@ -1099,7 +1204,11 @@ function! s:Move(force,destination)
|
|
1099
1204
|
endif
|
1100
1205
|
call fugitive#reload_status()
|
1101
1206
|
if s:buffer().commit() == ''
|
1102
|
-
|
1207
|
+
if isdirectory(destination)
|
1208
|
+
return 'edit '.s:fnameescape(destination)
|
1209
|
+
else
|
1210
|
+
return 'saveas! '.s:fnameescape(destination)
|
1211
|
+
endif
|
1103
1212
|
else
|
1104
1213
|
return 'file '.s:fnameescape(s:repo().translate(':0:'.destination)
|
1105
1214
|
endif
|
@@ -1184,17 +1293,25 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|
1184
1293
|
else
|
1185
1294
|
let error = tempname()
|
1186
1295
|
let temp = error.'.fugitiveblame'
|
1187
|
-
|
1296
|
+
if &shell =~# 'csh'
|
1297
|
+
silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
|
1298
|
+
else
|
1299
|
+
silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
|
1300
|
+
endif
|
1301
|
+
if exists('l:dir')
|
1302
|
+
execute cd.'`=dir`'
|
1303
|
+
unlet dir
|
1304
|
+
endif
|
1188
1305
|
if v:shell_error
|
1189
1306
|
call s:throw(join(readfile(error),"\n"))
|
1190
1307
|
endif
|
1191
1308
|
let bufnr = bufnr('')
|
1192
|
-
let restore = 'call
|
1309
|
+
let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
|
1193
1310
|
if &l:wrap
|
1194
|
-
let restore .= '|call
|
1311
|
+
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
|
1195
1312
|
endif
|
1196
1313
|
if &l:foldenable
|
1197
|
-
let restore .= '|call
|
1314
|
+
let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
|
1198
1315
|
endif
|
1199
1316
|
let winnr = winnr()
|
1200
1317
|
windo set noscrollbind
|
@@ -1206,7 +1323,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
|
1206
1323
|
let b:git_dir = git_dir
|
1207
1324
|
let b:fugitive_type = 'blame'
|
1208
1325
|
let b:fugitive_blamed_bufnr = bufnr
|
1209
|
-
let
|
1326
|
+
let w:fugitive_restore = restore
|
1210
1327
|
let b:fugitive_blame_arguments = join(a:args,' ')
|
1211
1328
|
call s:Detect(expand('%:p'))
|
1212
1329
|
execute top
|
@@ -1292,6 +1409,200 @@ function! s:BlameSyntax() abort
|
|
1292
1409
|
hi def link FugitiveblameNotCommittedYet Comment
|
1293
1410
|
endfunction
|
1294
1411
|
|
1412
|
+
" }}}1
|
1413
|
+
" Gbrowse {{{1
|
1414
|
+
|
1415
|
+
call s:command("-bar -bang -count=0 -nargs=? -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(<bang>0,<line1>,<count>,<f-args>)")
|
1416
|
+
|
1417
|
+
function! s:Browse(bang,line1,count,...) abort
|
1418
|
+
try
|
1419
|
+
let rev = a:0 ? substitute(a:1,'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : ''
|
1420
|
+
if rev ==# ''
|
1421
|
+
let expanded = s:buffer().rev()
|
1422
|
+
elseif rev ==# ':'
|
1423
|
+
let expanded = s:buffer().path('/')
|
1424
|
+
else
|
1425
|
+
let expanded = s:buffer().expand(rev)
|
1426
|
+
endif
|
1427
|
+
let full = s:repo().translate(expanded)
|
1428
|
+
let commit = ''
|
1429
|
+
if full =~# '^fugitive://'
|
1430
|
+
let commit = matchstr(full,'://.*//\zs\w\+')
|
1431
|
+
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
1432
|
+
if commit =~ '..'
|
1433
|
+
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
1434
|
+
else
|
1435
|
+
let type = 'blob'
|
1436
|
+
endif
|
1437
|
+
let path = path[1:-1]
|
1438
|
+
elseif s:repo().bare()
|
1439
|
+
let path = '.git/' . full[strlen(s:repo().dir())+1:-1]
|
1440
|
+
let type = ''
|
1441
|
+
else
|
1442
|
+
let path = full[strlen(s:repo().tree())+1:-1]
|
1443
|
+
if path =~# '^\.git/'
|
1444
|
+
let type = ''
|
1445
|
+
elseif isdirectory(full)
|
1446
|
+
let type = 'tree'
|
1447
|
+
else
|
1448
|
+
let type = 'blob'
|
1449
|
+
endif
|
1450
|
+
endif
|
1451
|
+
if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1]))
|
1452
|
+
let body = readfile(s:repo().dir(path[5:-1]))[0]
|
1453
|
+
if body =~# '^\x\{40\}$'
|
1454
|
+
let commit = body
|
1455
|
+
let type = 'commit'
|
1456
|
+
let path = ''
|
1457
|
+
elseif body =~# '^ref: refs/'
|
1458
|
+
let path = '.git/' . matchstr(body,'ref: \zs.*')
|
1459
|
+
endif
|
1460
|
+
endif
|
1461
|
+
|
1462
|
+
if a:0 && a:1 =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$'
|
1463
|
+
let remote = matchstr(a:1,'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$')
|
1464
|
+
elseif path =~# '^\.git/refs/remotes/.'
|
1465
|
+
let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+')
|
1466
|
+
else
|
1467
|
+
let remote = 'origin'
|
1468
|
+
let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]')
|
1469
|
+
if branch ==# '' && path =~# '^\.git/refs/\w\+/'
|
1470
|
+
let branch = s:sub(path,'^\.git/refs/\w+/','')
|
1471
|
+
endif
|
1472
|
+
if filereadable(s:repo().dir('refs/remotes/'.branch))
|
1473
|
+
let remote = matchstr(branch,'[^/]\+')
|
1474
|
+
let rev = rev[strlen(remote)+1:-1]
|
1475
|
+
else
|
1476
|
+
if branch ==# ''
|
1477
|
+
let branch = matchstr(s:repo().head_ref(),'\<refs/heads/\zs.*')
|
1478
|
+
endif
|
1479
|
+
if branch != ''
|
1480
|
+
let remote = s:repo().git_chomp('config','branch.'.branch.'.remote')
|
1481
|
+
if remote ==# ''
|
1482
|
+
let remote = 'origin'
|
1483
|
+
elseif rev[0:strlen(branch)-1] ==# branch && rev[strlen(branch)] =~# '[:^~@]'
|
1484
|
+
let rev = s:repo().git_chomp('config','branch.'.branch.'.merge')[11:-1] . rev[strlen(branch):-1]
|
1485
|
+
endif
|
1486
|
+
endif
|
1487
|
+
endif
|
1488
|
+
endif
|
1489
|
+
|
1490
|
+
let raw = s:repo().git_chomp('config','remote.'.remote.'.url')
|
1491
|
+
if raw ==# ''
|
1492
|
+
let raw = remote
|
1493
|
+
endif
|
1494
|
+
|
1495
|
+
let url = s:github_url(s:repo(),raw,rev,commit,path,type,a:line1,a:count)
|
1496
|
+
if url == ''
|
1497
|
+
let url = s:instaweb_url(s:repo(),rev,commit,path,type,a:count ? a:line1 : 0)
|
1498
|
+
endif
|
1499
|
+
|
1500
|
+
if url == ''
|
1501
|
+
call s:throw("Instaweb failed to start and '".remote."' is not a GitHub remote")
|
1502
|
+
endif
|
1503
|
+
|
1504
|
+
if a:bang
|
1505
|
+
let @* = url
|
1506
|
+
return 'echomsg '.string(url)
|
1507
|
+
else
|
1508
|
+
return 'echomsg '.string(url).'|silent Git web--browse '.shellescape(url,1)
|
1509
|
+
endif
|
1510
|
+
catch /^fugitive:/
|
1511
|
+
return 'echoerr v:errmsg'
|
1512
|
+
endtry
|
1513
|
+
endfunction
|
1514
|
+
|
1515
|
+
function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
|
1516
|
+
let path = a:path
|
1517
|
+
let repo_path = matchstr(a:url,'^\%(https\=://\|git://\|git@\)github\.com[/:]\zs.\{-\}\ze\%(\.git\)\=$')
|
1518
|
+
if repo_path ==# ''
|
1519
|
+
return ''
|
1520
|
+
endif
|
1521
|
+
let root = 'https://github.com/' . repo_path
|
1522
|
+
if path =~# '^\.git/refs/heads/'
|
1523
|
+
let branch = a:repo.git_chomp('config','branch.'.path[16:-1].'.merge')[11:-1]
|
1524
|
+
if branch ==# ''
|
1525
|
+
return root . '/commits/' . path[16:-1]
|
1526
|
+
else
|
1527
|
+
return root . '/commits/' . branch
|
1528
|
+
endif
|
1529
|
+
elseif path =~# '^\.git/refs/.'
|
1530
|
+
return root . '/commits/' . matchstr(path,'[^/]\+$')
|
1531
|
+
elseif path =~# '.git/\%(config$\|hooks\>\)'
|
1532
|
+
return root . '/admin'
|
1533
|
+
elseif path =~# '^\.git\>'
|
1534
|
+
return root
|
1535
|
+
endif
|
1536
|
+
if a:rev =~# '^[[:alnum:]._-]\+:'
|
1537
|
+
let commit = matchstr(a:rev,'^[^:]*')
|
1538
|
+
elseif a:commit =~# '^\d\=$'
|
1539
|
+
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*')
|
1540
|
+
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
|
1541
|
+
if commit ==# ''
|
1542
|
+
let commit = local
|
1543
|
+
endif
|
1544
|
+
else
|
1545
|
+
let commit = a:commit
|
1546
|
+
endif
|
1547
|
+
if a:type == 'tree'
|
1548
|
+
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
|
1549
|
+
elseif a:type == 'blob'
|
1550
|
+
let url = root . '/blob/' . commit . '/' . path
|
1551
|
+
if a:line2 && a:line1 == a:line2
|
1552
|
+
let url .= '#L' . a:line1
|
1553
|
+
elseif a:line2
|
1554
|
+
let url .= '#L' . a:line1 . '-' . a:line2
|
1555
|
+
endif
|
1556
|
+
elseif a:type == 'tag'
|
1557
|
+
let commit = matchstr(getline(3),'^tag \zs.*')
|
1558
|
+
let url = root . '/tree/' . commit
|
1559
|
+
else
|
1560
|
+
let url = root . '/commit/' . commit
|
1561
|
+
endif
|
1562
|
+
return url
|
1563
|
+
endfunction
|
1564
|
+
|
1565
|
+
function! s:instaweb_url(repo,rev,commit,path,type,...) abort
|
1566
|
+
let output = a:repo.git_chomp('instaweb','-b','unknown')
|
1567
|
+
if output =~# 'http://'
|
1568
|
+
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t')
|
1569
|
+
else
|
1570
|
+
return ''
|
1571
|
+
endif
|
1572
|
+
if a:path =~# '^\.git/refs/.'
|
1573
|
+
return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*')
|
1574
|
+
elseif a:path =~# '^\.git\>'
|
1575
|
+
return root
|
1576
|
+
endif
|
1577
|
+
let url = root
|
1578
|
+
if a:commit =~# '^\x\{40\}$'
|
1579
|
+
if a:type ==# 'commit'
|
1580
|
+
let url .= ';a=commit'
|
1581
|
+
endif
|
1582
|
+
let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path))
|
1583
|
+
else
|
1584
|
+
if a:type ==# 'blob'
|
1585
|
+
let tmp = tempname()
|
1586
|
+
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp
|
1587
|
+
let url .= ';h=' . readfile(tmp)[0]
|
1588
|
+
else
|
1589
|
+
try
|
1590
|
+
let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path)
|
1591
|
+
catch /^fugitive:/
|
1592
|
+
call s:throw('fugitive: cannot browse uncommitted file')
|
1593
|
+
endtry
|
1594
|
+
endif
|
1595
|
+
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$')
|
1596
|
+
endif
|
1597
|
+
if a:path !=# ''
|
1598
|
+
let url .= ';f=' . a:path
|
1599
|
+
endif
|
1600
|
+
if a:0 && a:1
|
1601
|
+
let url .= '#l' . a:1
|
1602
|
+
endif
|
1603
|
+
return url
|
1604
|
+
endfunction
|
1605
|
+
|
1295
1606
|
" }}}1
|
1296
1607
|
" File access {{{1
|
1297
1608
|
|
@@ -1305,10 +1616,8 @@ function! s:ReplaceCmd(cmd,...) abort
|
|
1305
1616
|
if &shell =~# 'cmd'
|
1306
1617
|
let old_index = $GIT_INDEX_FILE
|
1307
1618
|
let $GIT_INDEX_FILE = a:1
|
1308
|
-
elseif &shell =~# 'csh'
|
1309
|
-
let prefix = 'setenv GIT_INDEX_FILE '.s:shellesc(a:1).'; '
|
1310
1619
|
else
|
1311
|
-
let prefix = 'GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
1620
|
+
let prefix = 'env GIT_INDEX_FILE='.s:shellesc(a:1).' '
|
1312
1621
|
endif
|
1313
1622
|
endif
|
1314
1623
|
set noautowrite
|
@@ -1338,7 +1647,7 @@ function! s:BufReadIndex()
|
|
1338
1647
|
if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p')
|
1339
1648
|
let index = ''
|
1340
1649
|
else
|
1341
|
-
let index = expand('
|
1650
|
+
let index = expand('%:p')
|
1342
1651
|
endif
|
1343
1652
|
if b:fugitive_display_format
|
1344
1653
|
call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index)
|
@@ -1358,10 +1667,16 @@ function! s:BufReadIndex()
|
|
1358
1667
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
|
1359
1668
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
|
1360
1669
|
nnoremap <buffer> <silent> D :<C-U>execute <SID>StageDiff()<CR>
|
1670
|
+
nnoremap <buffer> <silent> dd :<C-U>execute <SID>StageDiff()<CR>
|
1671
|
+
nnoremap <buffer> <silent> dh :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
1672
|
+
nnoremap <buffer> <silent> ds :<C-U>execute <SID>StageDiff('Gsdiff')<CR>
|
1673
|
+
nnoremap <buffer> <silent> dv :<C-U>execute <SID>StageDiff()<CR>
|
1361
1674
|
nnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
1362
1675
|
xnoremap <buffer> <silent> - :<C-U>execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
1363
1676
|
nnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line('.'),line('.')+v:count1-1)<CR>
|
1364
1677
|
xnoremap <buffer> <silent> p :<C-U>execute <SID>StagePatch(line("'<"),line("'>"))<CR>
|
1678
|
+
nnoremap <buffer> <silent> <C-N> :call search('^#\t.*','W')<Bar>.<CR>
|
1679
|
+
nnoremap <buffer> <silent> <C-P> :call search('^#\t.*','Wbe')<Bar>.<CR>
|
1365
1680
|
call s:JumpInit()
|
1366
1681
|
nunmap <buffer> P
|
1367
1682
|
nunmap <buffer> ~
|
@@ -1415,7 +1730,11 @@ function! s:BufWriteIndexFile()
|
|
1415
1730
|
endif
|
1416
1731
|
let info = old_mode.' '.sha1.' '.stage."\t".path
|
1417
1732
|
call writefile([info],tmp)
|
1418
|
-
|
1733
|
+
if has('win32')
|
1734
|
+
let error = system('type '.tmp.'|'.s:repo().git_command('update-index','--index-info'))
|
1735
|
+
else
|
1736
|
+
let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp)
|
1737
|
+
endif
|
1419
1738
|
if v:shell_error == 0
|
1420
1739
|
setlocal nomodified
|
1421
1740
|
silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p'))
|
@@ -1539,9 +1858,9 @@ function! s:GF(mode) abort
|
|
1539
1858
|
if showtree && line('.') == 1
|
1540
1859
|
return ""
|
1541
1860
|
elseif showtree && line('.') > 2
|
1542
|
-
return s:Edit(a:mode,buffer.commit().':'.(buffer.path()
|
1861
|
+
return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$',''))
|
1543
1862
|
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
1544
|
-
return s:Edit(a:mode,buffer.commit().':'.(buffer.path()
|
1863
|
+
return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$',''))
|
1545
1864
|
endif
|
1546
1865
|
|
1547
1866
|
elseif buffer.type('blob')
|
@@ -1566,7 +1885,7 @@ function! s:GF(mode) abort
|
|
1566
1885
|
let file = '/'.matchstr(getline('.'),' -> \zs.*')
|
1567
1886
|
return s:Edit(a:mode,file)
|
1568
1887
|
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.'
|
1569
|
-
let file = '/'.matchstr(getline('.'),': *\zs
|
1888
|
+
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( (new commits)\)\=$')
|
1570
1889
|
return s:Edit(a:mode,file)
|
1571
1890
|
elseif getline('.') =~# '^#\t.'
|
1572
1891
|
let file = '/'.matchstr(getline('.'),'#\t\zs.*')
|
@@ -1629,6 +1948,13 @@ function! s:GF(mode) abort
|
|
1629
1948
|
elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
1630
1949
|
let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
1631
1950
|
let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
1951
|
+
let dcmd = 'Gdiff'
|
1952
|
+
|
1953
|
+
elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)'
|
1954
|
+
let line = getline(line('.')-1)
|
1955
|
+
let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)')
|
1956
|
+
let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)')
|
1957
|
+
let dcmd = 'Gdiff!'
|
1632
1958
|
|
1633
1959
|
elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$'
|
1634
1960
|
let ref = getline('.')
|
@@ -1656,7 +1982,7 @@ function! s:GF(mode) abort
|
|
1656
1982
|
endif
|
1657
1983
|
|
1658
1984
|
if exists('dref')
|
1659
|
-
return s:Edit(a:mode,ref) . '|
|
1985
|
+
return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref)
|
1660
1986
|
elseif ref != ""
|
1661
1987
|
return s:Edit(a:mode,ref)
|
1662
1988
|
endif
|
@@ -1698,6 +2024,18 @@ function! fugitive#statusline(...)
|
|
1698
2024
|
endif
|
1699
2025
|
endfunction
|
1700
2026
|
|
2027
|
+
function! s:repo_config(conf) dict abort
|
2028
|
+
return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*")
|
2029
|
+
endfun
|
2030
|
+
|
2031
|
+
function! s:repo_user() dict abort
|
2032
|
+
let username = s:repo().config('user.name')
|
2033
|
+
let useremail = s:repo().config('user.email')
|
2034
|
+
return username.' <'.useremail.'>'
|
2035
|
+
endfun
|
2036
|
+
|
2037
|
+
call s:add_methods('repo',['config', 'user'])
|
2038
|
+
|
1701
2039
|
" }}}1
|
1702
2040
|
|
1703
2041
|
" vim:set ft=vim ts=8 sw=2 sts=2:
|