FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
gitlab.nvim/lua/gitlab/git.lua at develop · harrisoncramer/gitlab.nvim · GitHub
harrisoncramer
gitlab.nvim
Repository navigation
Code
Issues
12
(12)
Pull requests
5
(5)
Discussions
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
gitlab.nvim
/
lua
/
gitlab
/
git.lua
Copy path
More file actions
More file actions
Latest commit
History
History
History
271 lines (241 loc) · 9.48 KB
Breadcrumbs
gitlab.nvim
/
lua
/
gitlab
/
git.lua
Copy path
File metadata and controls
271 lines (241 loc) · 9.48 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
local
List
=
require
(
"
gitlab.utils.list
"
)
local
M
=
{}
---
Run a system command, capture the output (if it exists) and handle errors.
---
TODO: Rewrite using vim.system instead of vim.fn.system.
---
@param
command
string[]
---
@return
string
?
result The result of the command as a string. Nil if the command failed
---
@return
string
?
error The error the command failed with. Nil if the command succeeded
local
run_system
=
function
(
command
)
local
result
=
vim
.
fn
.
trim
(
vim
.
fn
.
system
(
command
),
"
\r\n
"
)
if
vim
.
v
.
shell_error
~=
0
then
require
(
"
gitlab.utils
"
).
notify
(
result
,
vim
.
log
.
levels
.
ERROR
)
return
nil
,
result
end
return
result
,
nil
end
---
Return all branches for the current repository.
---
@param
args
?
string[] Extra arguments for
`
git branch
`
---
@return
string
?,
string
?
M
.
branches
=
function
(
args
)
local
u
=
require
(
"
gitlab.utils
"
)
return
run_system
(
u
.
combine
({
"
git
"
,
"
branch
"
},
args
or
{}))
end
---
Return true if the working tree hasn't got any changes that haven't been committed.
---
@return
boolean
,
string
?
M
.
has_clean_tree
=
function
()
local
changes
,
err
=
run_system
({
"
git
"
,
"
status
"
,
"
--short
"
,
"
--untracked-files=no
"
})
return
changes
==
"
"
,
err
end
---
Return true if the `file` has got any uncommitted changes.
---
@param
file
string File to check for changes
---
@return
boolean
,
string
?
M
.
has_changes
=
function
(
file
)
local
changes
,
err
=
run_system
({
"
git
"
,
"
status
"
,
"
--short
"
,
"
--untracked-files=no
"
,
"
--
"
,
file
})
return
changes
~=
"
"
,
err
end
---
Return the base directory of the current project and possible error from git.
---
@return
string
?,
string
?
M
.
base_dir
=
function
()
return
run_system
({
"
git
"
,
"
rev-parse
"
,
"
--show-toplevel
"
})
end
---
Switch the current project to the given branch.
---
@param
branch
string The branch to switch to
---
@return
string
?,
string
?
M
.
switch_branch
=
function
(
branch
)
return
run_system
({
"
git
"
,
"
checkout
"
,
"
-q
"
,
branch
})
end
---
Return the name of the upstream branch for the current branch or nil if it can't be found.
---
TODO: This should really be called "get_upstream_branch", and the use of "remote
---
branch" should be revised throughout this module.
---
@return
string
?
M
.
get_remote_branch
=
function
()
local
remote_branch
,
err
=
run_system
({
"
git
"
,
"
rev-parse
"
,
"
--abbrev-ref
"
,
"
--symbolic-full-name
"
,
"
@{u}
"
})
if
err
or
remote_branch
==
"
"
then
require
(
"
gitlab.utils
"
).
notify
(
"
Could not get remote branch:
"
..
err
,
vim
.
log
.
levels
.
ERROR
)
return
nil
end
return
remote_branch
end
---
Fetch the remote branch.
---
@param
remote_branch
string The name of the repo and branch to fetch
(
e.g.
,
"
origin/some_branch
"
)
---
@return
boolean fetch_successful False if an error occurred while fetching
,
true otherwise
M
.
fetch_remote_branch
=
function
(
remote_branch
)
local
remote
,
branch
=
string.match
(
remote_branch
,
"
([^/]+)/(.+)
"
)
if
not
remote
or
not
branch
then
require
(
"
gitlab.utils
"
).
notify
(
"
Invalid remote branch format:
"
..
remote_branch
,
vim
.
log
.
levels
.
ERROR
)
return
false
end
local
_
,
fetch_err
=
run_system
({
"
git
"
,
"
fetch
"
,
remote
,
branch
})
if
fetch_err
~=
nil
then
require
(
"
gitlab.utils
"
).
notify
(
"
Error fetching remote-tracking branch:
"
..
fetch_err
,
vim
.
log
.
levels
.
ERROR
)
return
false
end
return
true
end
---
Return the number of commits the local branch is ahead of and behind the upstream or
---
nil values in case of errors.
---
@param
current_branch
?
string The name of the local branch
---
@param
remote_branch
?
string The name of the remote branch
---
@return
integer
?
ahead The number of commits local is ahead of upstream
---
@return
integer
?
behind The number of commits local is behind upstream
M
.
get_ahead_behind
=
function
(
current_branch
,
remote_branch
)
if
current_branch
==
nil
or
remote_branch
==
nil
then
return
nil
,
nil
end
if
not
M
.
fetch_remote_branch
(
remote_branch
)
then
return
nil
,
nil
end
local
u
=
require
(
"
gitlab.utils
"
)
local
result
,
err
=
run_system
({
"
git
"
,
"
rev-list
"
,
"
--left-right
"
,
"
--count
"
,
current_branch
..
"
...
"
..
remote_branch
})
if
err
~=
nil
or
result
==
nil
then
u
.
notify
(
"
Could not determine if branch is up-to-date:
"
..
err
,
vim
.
log
.
levels
.
ERROR
)
return
nil
,
nil
end
local
ahead
,
behind
=
result
:
match
(
"
(%d+)%s+(%d+)
"
)
if
ahead
==
nil
or
behind
==
nil
then
u
.
notify
(
"
Error parsing ahead/behind information
"
,
vim
.
log
.
levels
.
ERROR
)
return
nil
,
nil
end
return
tonumber
(
ahead
),
tonumber
(
behind
)
end
---
Return the name of the current branch, or nil (detached HEAD or git failure).
---
@return
string
?
M
.
get_current_branch
=
function
()
local
current_branch
,
err
=
run_system
({
"
git
"
,
"
branch
"
,
"
--show-current
"
})
if
err
then
require
(
"
gitlab.utils
"
).
notify
(
"
Could not get current branch:
"
..
err
,
vim
.
log
.
levels
.
ERROR
)
return
nil
end
if
current_branch
==
"
"
then
--
detached HEAD: `git branch --show-current` returns empty + exit 0
return
nil
end
return
current_branch
end
---
Return the list of possible merge targets.
---
@return
table
?
M
.
get_all_merge_targets
=
function
()
local
current_branch
=
M
.
get_current_branch
()
if
current_branch
==
nil
then
return
end
return
List
.
new
(
M
.
get_all_remote_branches
()):
filter
(
function
(
branch
)
return
branch
~=
current_branch
end
)
end
---
Return the list of names of all remote-tracking branches or an empty list.
---
@return
string[] result List of branch names
---
@return
string
?
error The error when listing branches fails
M
.
get_all_remote_branches
=
function
()
local
state
=
require
(
"
gitlab.state
"
)
local
all_branches
,
err
=
M
.
branches
({
"
--remotes
"
})
if
err
~=
nil
then
return
{},
err
end
if
all_branches
==
nil
then
return
{},
"
Something went wrong getting branches for this repository
"
end
local
u
=
require
(
"
gitlab.utils
"
)
local
lines
=
u
.
lines_into_table
(
all_branches
)
return
List
.
new
(
lines
)
:
map
(
function
(
line
)
--
Trim the remote name from the branch name
return
line
:
match
(
state
.
settings
.
connection_settings
.
remote
..
"
/(%S+)
"
)
end
)
:
filter
(
function
(
branch
)
--
Don't include the HEAD pointer
return
not
branch
:
match
(
"
^HEAD$
"
)
end
)
end
---
Return whether something
---
TODO: Remove - unused.
---
@param
current_branch
string
---
@return
string
?,
string
?
M
.
contains_branch
=
function
(
current_branch
)
return
run_system
({
"
git
"
,
"
branch
"
,
"
-r
"
,
"
--contains
"
,
current_branch
})
end
---
Return true if local is up-to-date with remote, otherwise false and notify user.
---
@param
ahead
?
integer The number of commits the current branch is ahead of remote
---
@param
behind
?
integer The number of commits the current branch is behind remote
---
@param
remote_branch
?
string The remote branch
,
e.g.
,
origin
/
feature-branch
---
@param
log_level
vim.log.levels
---
@return
boolean
M
.
evaluate_ahead_behind
=
function
(
ahead
,
behind
,
remote_branch
,
log_level
)
if
ahead
==
nil
or
behind
==
nil
then
return
false
end
local
u
=
require
(
"
gitlab.utils
"
)
if
ahead
>
0
and
behind
==
0
then
u
.
notify
(
string.format
(
"
There are local changes that haven't been pushed to %s yet
"
,
remote_branch
),
log_level
)
return
false
end
if
behind
>
0
and
ahead
==
0
then
u
.
notify
(
string.format
(
"
There are remote changes on %s that haven't been pulled yet
"
,
remote_branch
),
log_level
)
return
false
end
if
ahead
>
0
and
behind
>
0
then
u
.
notify
(
string.format
(
"
Your branch and the remote %s have diverged. You need to pull, possibly rebase, and then push.
"
,
remote_branch
),
log_level
)
return
false
end
return
true
--
Checks passed, local is up-to-date
end
---
Return true if local is up-to-date with remote, otherwise false and notify user.
---
This is a blocking function. For a non-blocking version use
---
gitlab.git_async.check_current_branch_up_to_date_on_remote.
---
@param
log_level
vim.log.levels The log level with which user will be notified
---
@return
boolean
M
.
check_current_branch_up_to_date_on_remote
=
function
(
log_level
)
local
current_branch
=
M
.
get_current_branch
()
local
remote_branch
=
M
.
get_remote_branch
()
local
ahead
,
behind
=
M
.
get_ahead_behind
(
current_branch
,
remote_branch
)
require
(
"
gitlab.state
"
).
ahead_behind
=
{
ahead
,
behind
}
return
M
.
evaluate_ahead_behind
(
ahead
,
behind
,
remote_branch
,
log_level
)
end
---
Warn user if the current MR is in a bad state (closed, has conflicts, merged).
M
.
check_mr_in_good_condition
=
function
()
local
state
=
require
(
"
gitlab.state
"
)
local
u
=
require
(
"
gitlab.utils
"
)
if
state
.
INFO
.
has_conflicts
then
u
.
notify
(
"
This merge request has conflicts!
"
,
vim
.
log
.
levels
.
WARN
)
end
if
state
.
INFO
.
state
==
"
closed
"
then
u
.
notify
(
string.format
(
"
This MR was closed %s
"
,
u
.
time_since
(
state
.
INFO
.
closed_at
)),
vim
.
log
.
levels
.
WARN
)
end
if
state
.
INFO
.
state
==
"
merged
"
then
u
.
notify
(
string.format
(
"
This MR was merged %s
"
,
u
.
time_since
(
state
.
INFO
.
merged_at
)),
vim
.
log
.
levels
.
WARN
)
end
end
---
Return the diff between two commits for the given file(s).
---
Diffs the two commit trees directly rather than against the working tree, so it's
---
correct regardless of what's currently checked out.
---
@param
old_sha
string SHA to diff from
---
@param
new_sha
string SHA to diff to
---
@param
old_path
?
string Old file name
---
@param
new_path
?
string New file name - relevant for renamed files
,
ignored if same as old_path
---
@return
string
?
diff
,
string
?
err
M
.
diff_files
=
function
(
old_sha
,
new_sha
,
old_path
,
new_path
)
return
run_system
({
"
git
"
,
"
-c
"
,
"
diff.suppressBlankEmpty=false
"
,
"
diff
"
,
"
--minimal
"
,
"
--find-renames=30%
"
,
"
--unified=3
"
,
"
--no-color
"
,
"
--no-ext-diff
"
,
old_sha
,
new_sha
,
"
--
"
,
old_path
,
new_path
,
})
end
return
M
Back
|
FazBrowse Home
|
New Git URL