utils 0.0.55 → 0.0.56
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|