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 adj (AdjBranch currbranch) origbranch
| not (adjustmentIsStable adj) = do
b <- preventCommits $ \commitlck -> do
(b, origheadfile, newheadfile) <- preventCommits $ \commitlck -> do
-- Avoid losing any commits that the adjusted branch
-- has that have not yet been propigated back to the
-- origbranch.
_ <- propigateAdjustedCommits' origbranch adj commitlck
origheadfile <- inRepo $ readFile . Git.Ref.headFile
-- Git normally won't do anything when asked to check
-- out the currently checked out branch, even when its
-- ref has changed. Work around this by writing a raw
-- sha to .git/HEAD.
inRepo (Git.Ref.sha currbranch) >>= \case
Just headsha -> inRepo $ \r ->
writeFile (Git.Ref.headFile r) (fromRef headsha)
_ -> noop
newheadfile <- inRepo (Git.Ref.sha currbranch) >>= \case
Just headsha -> do
inRepo $ \r -> do
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
-- 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
-- Done for consistency.
_ <- 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.
* Avoid failure to update adjusted branch --unlock-present after git-annex
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

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". :)
> [[fixed|done]] --[[Joey]]