Skip to content

Commit edc01bb

Browse files
authored
fix: Staging fails when cwd differs from repo root (#432)
When `GitFile(filename)` was created with a relative path, `git_repo.discover()` resolved it relative to the current working directory. If the user `:cd`'d to a subdirectory, paths got resolved incorrectly and staging operations silently failed. - DiffScreen: Use `self.git_file` instead of creating new GitFile - ProjectDiffScreen: Construct absolute paths using stored reponame - Remove redundant `filename` params from Model methods - Remove redundant `git_repo.discover()` calls (use stored reponame) - Fix extra unused arg in `git_file:unstage(filename)`
1 parent f68af40 commit edc01bb

3 files changed

Lines changed: 34 additions & 38 deletions

File tree

lua/vgit/features/screens/DiffScreen/Model.lua

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -112,37 +112,33 @@ function Model:get_filetype()
112112
return self.git_file:get_filetype()
113113
end
114114

115-
function Model:stage_hunk(filename, hunk)
116-
local git_file = GitFile(filename)
117-
if not git_file:is_tracked() then return git_file:stage() end
115+
function Model:stage_hunk(hunk)
116+
if not self.git_file:is_tracked() then return self.git_file:stage() end
118117

119-
return git_file:stage_hunk(hunk)
118+
return self.git_file:stage_hunk(hunk)
120119
end
121120

122-
function Model:unstage_hunk(filename, hunk)
123-
local git_file = GitFile(filename)
124-
if not git_file:is_tracked() then return git_file:unstage() end
121+
function Model:unstage_hunk(hunk)
122+
if not self.git_file:is_tracked() then return self.git_file:unstage() end
125123

126-
return git_file:unstage_hunk(hunk)
124+
return self.git_file:unstage_hunk(hunk)
127125
end
128126

129-
function Model:reset_hunk(filename, hunk)
130-
local git_file = GitFile(filename)
131-
return git_file:reset_hunk(hunk)
127+
function Model:reset_hunk(hunk)
128+
return self.git_file:reset_hunk(hunk)
132129
end
133130

134-
function Model:stage_file(filename)
135-
local reponame = git_repo.discover()
136-
return git_stager.stage(reponame, filename)
131+
function Model:stage_file()
132+
return self.git_file:stage()
137133
end
138134

139-
function Model:unstage_file(filename)
140-
local reponame = git_repo.discover()
141-
return git_stager.unstage(reponame, filename)
135+
function Model:unstage_file()
136+
return self.git_file:unstage()
142137
end
143138

144-
function Model:reset_file(filename)
145-
local reponame = git_repo.discover()
139+
function Model:reset_file()
140+
local reponame = self.git_file.reponame
141+
local filename = self.git_file.filename
146142
if git_repo.has(reponame, filename) then return git_repo.reset(reponame, filename) end
147143

148144
return git_repo.clean(reponame, filename)

lua/vgit/features/screens/DiffScreen/init.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function DiffScreen:reset(buffer)
143143
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
144144

145145
loop.free_textlock()
146-
self.model:reset_file(filename)
146+
self.model:reset_file()
147147

148148
loop.free_textlock()
149149
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())
@@ -193,7 +193,7 @@ function DiffScreen:stage_hunk(buffer)
193193
local git_buffer_store = require('vgit.git.git_buffer_store')
194194
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
195195

196-
self.model:stage_hunk(filename, hunk)
196+
self.model:stage_hunk(hunk)
197197

198198
loop.free_textlock()
199199
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())
@@ -225,7 +225,7 @@ function DiffScreen:unstage_hunk(buffer)
225225
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
226226

227227
loop.free_textlock()
228-
self.model:unstage_hunk(filename, hunk)
228+
self.model:unstage_hunk(hunk)
229229

230230
loop.free_textlock()
231231
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())
@@ -264,7 +264,7 @@ function DiffScreen:reset_hunk(buffer)
264264
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
265265

266266
loop.free_textlock()
267-
self.model:reset_hunk(filename, hunk)
267+
self.model:reset_hunk(hunk)
268268

269269
loop.free_textlock()
270270
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())
@@ -292,7 +292,7 @@ function DiffScreen:stage(buffer)
292292
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
293293

294294
loop.free_textlock()
295-
self.model:stage_file(filename)
295+
self.model:stage_file()
296296

297297
loop.free_textlock()
298298
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())
@@ -317,7 +317,7 @@ function DiffScreen:unstage(buffer)
317317
git_buffer_store.suppress_sync_and_refresh(buffer, 200)
318318

319319
loop.free_textlock()
320-
self.model:unstage_file(filename)
320+
self.model:unstage_file()
321321

322322
loop.free_textlock()
323323
local _, refetch_err = self.model:refresh_hunks(buffer:get_name())

lua/vgit/features/screens/ProjectDiffScreen/Model.lua

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ function Model:get_diff()
219219
end
220220

221221
function Model:stage_hunk(filename, hunk)
222-
local git_file = GitFile(filename)
222+
-- Use absolute path to avoid issues when cwd differs from repo root
223+
local filepath = self.state.reponame .. '/' .. filename
224+
local git_file = GitFile(filepath)
223225
if not git_file:is_tracked() then return git_file:stage() end
224226

225227
local file, err = git_file:status()
@@ -230,45 +232,43 @@ function Model:stage_hunk(filename, hunk)
230232
end
231233

232234
function Model:unstage_hunk(filename, hunk)
233-
local git_file = GitFile(filename)
235+
-- Use absolute path to avoid issues when cwd differs from repo root
236+
local filepath = self.state.reponame .. '/' .. filename
237+
local git_file = GitFile(filepath)
234238
if not git_file:is_tracked() then return git_file:unstage() end
235239

236240
local file, err = git_file:status()
237241
if err then return nil, err end
238242

239-
if file:has('D ') or file:has(' D') then return git_file:unstage(filename) end
243+
if file:has('D ') or file:has(' D') then return git_file:unstage() end
240244
return git_file:unstage_hunk(hunk)
241245
end
242246

243247
function Model:stage_file(filename)
244-
local reponame = git_repo.discover()
245-
return git_stager.stage(reponame, filename)
248+
return git_stager.stage(self.state.reponame, filename)
246249
end
247250

248251
function Model:unstage_file(filename)
249-
local reponame = git_repo.discover()
250-
return git_stager.unstage(reponame, filename)
252+
return git_stager.unstage(self.state.reponame, filename)
251253
end
252254

253255
function Model:reset_file(filename)
254-
local reponame = git_repo.discover()
256+
local reponame = self.state.reponame
255257
if git_repo.has(reponame, filename) then return git_repo.reset(reponame, filename) end
256258

257259
return git_repo.clean(reponame, filename)
258260
end
259261

260262
function Model:stage_all()
261-
local reponame = git_repo.discover()
262-
return git_stager.stage(reponame)
263+
return git_stager.stage(self.state.reponame)
263264
end
264265

265266
function Model:unstage_all()
266-
local reponame = git_repo.discover()
267-
return git_stager.unstage(reponame)
267+
return git_stager.unstage(self.state.reponame)
268268
end
269269

270270
function Model:reset_all()
271-
local reponame = git_repo.discover()
271+
local reponame = self.state.reponame
272272
local _, reset_err = git_repo.reset(reponame)
273273
if reset_err then return nil, reset_err end
274274

0 commit comments

Comments
 (0)