Skip to content

Commit 894494b

Browse files
committed
feat: implement stash view
1 parent 5b2ea2e commit 894494b

18 files changed

Lines changed: 3579 additions & 302 deletions

lua/vgit.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ controller.execute_command = event.async(function(args)
214214
status = true,
215215
branch = true,
216216
debug = true,
217+
stash = true,
217218
}
218219

219220
if porcelain_commands[cmd] then

lua/vgit/cli/commands/stash.lua

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
local lazy = require('vgit.core.lazy')
2+
local event = lazy('vgit.core.event')
3+
local console = lazy('vgit.core.console')
4+
local git_stash = lazy('vgit.git.git_stash')
5+
local repository = lazy('vgit.git.repository')
6+
local scene_setting = lazy('vgit.settings.scene')
7+
local display_service = lazy('vgit.ui.display_service')
8+
9+
local stash_command = {}
10+
11+
local function parse_args(args)
12+
local opts = { action = 'screen', index = nil }
13+
if not args or #args == 0 then return opts end
14+
15+
local first = args[1]
16+
17+
if first == 'add' then
18+
opts.action = 'add'
19+
elseif first == 'pop' then
20+
opts.action = 'pop'
21+
opts.index = args[2] and tonumber(args[2]) or 0
22+
elseif first == 'apply' then
23+
opts.action = 'apply'
24+
opts.index = args[2] and tonumber(args[2]) or 0
25+
elseif first == 'drop' then
26+
opts.action = 'drop'
27+
opts.index = args[2] and tonumber(args[2]) or 0
28+
elseif first == 'clear' then
29+
opts.action = 'clear'
30+
end
31+
32+
return opts
33+
end
34+
35+
stash_command.execute = event.async(function(args)
36+
args = args or {}
37+
local opts = parse_args(args)
38+
39+
event.await()
40+
41+
local repo, repo_err = repository.current()
42+
if repo_err then
43+
console.error(repo_err)
44+
return
45+
end
46+
47+
local repo_path = repo:get_path()
48+
49+
if opts.action == 'add' then
50+
local _, err = git_stash.add(repo_path)
51+
if err then
52+
console.error(err[1] or tostring(err))
53+
return
54+
end
55+
console.info('Changes stashed')
56+
return
57+
end
58+
59+
if opts.action == 'pop' then
60+
local stash_ref = string.format('stash@{%d}', opts.index)
61+
local _, err = git_stash.pop(repo_path, stash_ref)
62+
if err then
63+
console.error(err[1] or tostring(err))
64+
return
65+
end
66+
console.info('Stash popped: ' .. stash_ref)
67+
return
68+
end
69+
70+
if opts.action == 'apply' then
71+
local stash_ref = string.format('stash@{%d}', opts.index)
72+
local _, err = git_stash.apply(repo_path, stash_ref)
73+
if err then
74+
console.error(err[1] or tostring(err))
75+
return
76+
end
77+
console.info('Stash applied: ' .. stash_ref)
78+
return
79+
end
80+
81+
if opts.action == 'drop' then
82+
local stash_ref = string.format('stash@{%d}', opts.index)
83+
local _, err = git_stash.drop(repo_path, stash_ref)
84+
if err then
85+
console.error(err[1] or tostring(err))
86+
return
87+
end
88+
console.info('Stash dropped: ' .. stash_ref)
89+
return
90+
end
91+
92+
if opts.action == 'clear' then
93+
local _, err = git_stash.clear(repo_path)
94+
if err then
95+
console.error(err[1] or tostring(err))
96+
return
97+
end
98+
console.info('All stashes cleared')
99+
return
100+
end
101+
102+
-- Default: show stash screen
103+
local stashes, list_err = git_stash.list(repo_path)
104+
if list_err then
105+
console.error(list_err[1] or tostring(list_err))
106+
return
107+
end
108+
109+
if not stashes or #stashes == 0 then
110+
console.info('No stashes found')
111+
return
112+
end
113+
114+
display_service.show_stash({
115+
stashes = stashes,
116+
repo = repo,
117+
layout_type = scene_setting:get('diff_preference') or 'unified',
118+
})
119+
end)
120+
121+
return stash_command

0 commit comments

Comments
 (0)