Fix two git operation bugs
- gitCommitAll: abort commit when staging (git add -A) fails, e.g. due to a stale .git/index.lock. Previously the failure was ignored and commit proceeded on an empty or partial index. - gitPull: remove explicit branch argument from git pull --rebase. Passing both remote and branch can conflict with the branch's configured tracking ref, causing 'Cannot rebase onto multiple branches'. Now uses just --rebase <remote>, letting git resolve the tracking branch from config. - Test: index.lock scenario verifies commit is aborted on staging failure.
This commit is contained in:
+10
-7
@@ -321,17 +321,20 @@ syncRepo opts logger repo = do
|
|||||||
-- | Stage all changes and commit with an auto-generated message.
|
-- | Stage all changes and commit with an auto-generated message.
|
||||||
gitCommitAll :: Logger -> FilePath -> IO (ExitCode, Text, Text)
|
gitCommitAll :: Logger -> FilePath -> IO (ExitCode, Text, Text)
|
||||||
gitCommitAll logger repoPath = do
|
gitCommitAll logger repoPath = do
|
||||||
(_, _, stageErr) <- loggedGit logger repoPath ["add", "-A"]
|
addResult@(addCode, _, addErr) <- loggedGit logger repoPath ["add", "-A"]
|
||||||
unless (T.null stageErr) $
|
unless (T.null addErr) $
|
||||||
logInfo logger ("git add stderr: " <> stageErr)
|
logInfo logger ("git add stderr: " <> addErr)
|
||||||
hostname <- init <$> readProcess "hostname" [] ""
|
if addCode /= ExitSuccess
|
||||||
loggedGit logger repoPath ["commit", "-m", "converge: auto-commit from " <> hostname]
|
then pure addResult
|
||||||
|
else do
|
||||||
|
hostname <- init <$> readProcess "hostname" [] ""
|
||||||
|
loggedGit logger repoPath ["commit", "-m", "converge: auto-commit from " <> hostname]
|
||||||
|
|
||||||
-- | Pull from the configured remote and branch.
|
-- | Pull from the configured remote, rebasing onto the tracked upstream branch.
|
||||||
gitPull :: Logger -> RepoConfig -> IO (ExitCode, Text, Text)
|
gitPull :: Logger -> RepoConfig -> IO (ExitCode, Text, Text)
|
||||||
gitPull logger repo =
|
gitPull logger repo =
|
||||||
loggedGit logger (rcPath repo)
|
loggedGit logger (rcPath repo)
|
||||||
["pull", "--rebase", T.unpack (rcRemote repo), T.unpack (rcBranch repo)]
|
["pull", "--rebase", T.unpack (rcRemote repo)]
|
||||||
|
|
||||||
-- | Push to the configured remote and branch.
|
-- | Push to the configured remote and branch.
|
||||||
gitPush :: Logger -> RepoConfig -> IO (ExitCode, Text, Text)
|
gitPush :: Logger -> RepoConfig -> IO (ExitCode, Text, Text)
|
||||||
|
|||||||
@@ -54,6 +54,19 @@ spec = do
|
|||||||
countAfter2 <- commitCount repo
|
countAfter2 <- commitCount repo
|
||||||
countAfter2 `shouldBe` countBefore2
|
countAfter2 `shouldBe` countBefore2
|
||||||
|
|
||||||
|
it "aborts commit when staging fails (e.g. index.lock exists)" $ do
|
||||||
|
logger <- testLogger
|
||||||
|
withTempGitRepo $ \repo -> do
|
||||||
|
-- Create a lock file to make git add -A fail
|
||||||
|
writeFile (repo </> ".git" </> "index.lock") "locked"
|
||||||
|
writeFile (repo </> "new.txt") "new file"
|
||||||
|
countBefore <- commitCount repo
|
||||||
|
(code, _, err) <- gitCommitAll logger repo
|
||||||
|
-- Staging fails, so commit should not happen
|
||||||
|
code `shouldSatisfy` (/= ExitSuccess)
|
||||||
|
err `shouldSatisfy` ("index.lock" `T.isInfixOf`)
|
||||||
|
commitCount repo `shouldReturn` countBefore
|
||||||
|
|
||||||
describe "startup sync" $ do
|
describe "startup sync" $ do
|
||||||
it "commits and pushes uncommitted changes on startup" $ do
|
it "commits and pushes uncommitted changes on startup" $ do
|
||||||
logger <- testLogger
|
logger <- testLogger
|
||||||
|
|||||||
Reference in New Issue
Block a user