Avoid leaving repo with a detached head when there is a failure checking out an updated adjusted branch

I don't know of scenarios where that can happen (besides the bug
fixed by the parent commit), but there probably are some.

Sponsored-by: Boyd Stephen Smith Jr. on Patreon
This commit is contained in:
Joey Hess 2023-03-23 16:36:43 -04:00
parent cb4d9f7b1f
commit 038a2600f4
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 26 additions and 8 deletions

View file

@ -248,26 +248,42 @@ checkoutAdjustedBranch (AdjBranch b) quietcheckout = do
updateAdjustedBranch :: Adjustment -> AdjBranch -> OrigBranch -> Annex Bool updateAdjustedBranch :: Adjustment -> AdjBranch -> OrigBranch -> Annex Bool
updateAdjustedBranch adj (AdjBranch currbranch) origbranch updateAdjustedBranch adj (AdjBranch currbranch) origbranch
| not (adjustmentIsStable adj) = do | not (adjustmentIsStable adj) = do
b <- preventCommits $ \commitlck -> do (b, origheadfile, newheadfile) <- preventCommits $ \commitlck -> do
-- Avoid losing any commits that the adjusted branch -- Avoid losing any commits that the adjusted branch
-- has that have not yet been propigated back to the -- has that have not yet been propigated back to the
-- origbranch. -- origbranch.
_ <- propigateAdjustedCommits' origbranch adj commitlck _ <- propigateAdjustedCommits' origbranch adj commitlck
origheadfile <- inRepo $ readFile . Git.Ref.headFile
-- Git normally won't do anything when asked to check -- Git normally won't do anything when asked to check
-- out the currently checked out branch, even when its -- out the currently checked out branch, even when its
-- ref has changed. Work around this by writing a raw -- ref has changed. Work around this by writing a raw
-- sha to .git/HEAD. -- sha to .git/HEAD.
inRepo (Git.Ref.sha currbranch) >>= \case newheadfile <- inRepo (Git.Ref.sha currbranch) >>= \case
Just headsha -> inRepo $ \r -> Just headsha -> do
writeFile (Git.Ref.headFile r) (fromRef headsha) inRepo $ \r -> do
_ -> noop let newheadfile = fromRef headsha
writeFile (Git.Ref.headFile r) newheadfile
return (Just newheadfile)
_ -> return Nothing
adjustBranch adj origbranch b <- adjustBranch adj origbranch
return (b, origheadfile, newheadfile)
-- Make git checkout quiet to avoid warnings about -- Make git checkout quiet to avoid warnings about
-- disconnected branch tips being lost. -- disconnected branch tips being lost.
checkoutAdjustedBranch b True ok <- checkoutAdjustedBranch b True
-- Avoid leaving repo with detached head.
unless ok $ case newheadfile of
Nothing -> noop
Just v -> preventCommits $ \_commitlck -> inRepo $ \r -> do
v' <- readFile (Git.Ref.headFile r)
when (v == v') $
writeFile (Git.Ref.headFile r) origheadfile
return ok
| otherwise = preventCommits $ \commitlck -> do | otherwise = preventCommits $ \commitlck -> do
-- Done for consistency. -- Done for consistency.
_ <- propigateAdjustedCommits' origbranch adj commitlck _ <- propigateAdjustedCommits' origbranch adj commitlck

View file

@ -3,6 +3,8 @@ git-annex (10.20230322) UNRELEASED; urgency=medium
* sync: Fix parsing of gcrypt::rsync:// urls that use a relative path. * sync: Fix parsing of gcrypt::rsync:// urls that use a relative path.
* Avoid failure to update adjusted branch --unlock-present after git-annex * Avoid failure to update adjusted branch --unlock-present after git-annex
drop when annex.adjustedbranchrefresh=1 drop when annex.adjustedbranchrefresh=1
* Avoid leaving repo with a detached head when there is a failure
checking out an updated adjusted branch.
-- Joey Hess <id@joeyh.name> Thu, 23 Mar 2023 15:04:41 -0400 -- Joey Hess <id@joeyh.name> Thu, 23 Mar 2023 15:04:41 -0400

View file

@ -53,4 +53,4 @@ local repository version: 8
git-annex is too good. It so rarely causes problems that one does not develop the "git-annex troubleshooting muscle". :) git-annex is too good. It so rarely causes problems that one does not develop the "git-annex troubleshooting muscle". :)
> [[fixed|done]] --[[Joey]]