From 2dfffa062111847d7a6a4a3daf85121e53535236 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 14 May 2024 16:17:27 -0400 Subject: [PATCH] bugfix When pushing branch foo, we don't want to delete other tracking branches. In particular, a full push needs all the tracking branches. --- CmdLine/GitRemoteAnnex.hs | 18 ++++++++++-------- doc/todo/git-remote-annex.mdwn | 17 +---------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/CmdLine/GitRemoteAnnex.hs b/CmdLine/GitRemoteAnnex.hs index 6bc802401c..0af908c5b7 100644 --- a/CmdLine/GitRemoteAnnex.hs +++ b/CmdLine/GitRemoteAnnex.hs @@ -144,7 +144,7 @@ list st rmt forpush = do -- was listed. This is necessary in order for a full repush to know -- what to push. when forpush $ - updateTrackingRefs rmt trackingrefmap + updateTrackingRefs True rmt trackingrefmap -- Respond to git with a list of refs. liftIO $ do @@ -198,7 +198,7 @@ push :: State -> Remote -> [String] -> Annex ([String], State) push st rmt ls = do let (refspecs, ls') = collectRefSpecs ls (responses, trackingrefs) <- calc refspecs ([], trackingRefs st) - updateTrackingRefs rmt trackingrefs + updateTrackingRefs False rmt trackingrefs (ok, st') <- if M.null trackingrefs then pushEmpty st rmt else if any forcedPush refspecs @@ -211,7 +211,7 @@ push st rmt ls = do return (ls', st' { trackingRefs = trackingrefs }) else do -- Restore the old tracking refs - updateTrackingRefs rmt (trackingRefs st) + updateTrackingRefs True rmt (trackingRefs st) sendresponses $ map (const "error push failed") refspecs return (ls', st') @@ -835,15 +835,17 @@ toTrackingRef rmt (Ref r) = Ref $ trackingRefPrefix rmt <> r fromTrackingRef :: Remote -> Ref -> Ref fromTrackingRef rmt = Git.Ref.removeBase (decodeBS (trackingRefPrefix rmt)) --- Update the tracking refs to be those in the map, and no others. -updateTrackingRefs :: Remote -> M.Map Ref Sha -> Annex () -updateTrackingRefs rmt new = do +-- Update the tracking refs to be those in the map. +-- When deleteold is set, any other tracking refs are deleted. +updateTrackingRefs :: Bool -> Remote -> M.Map Ref Sha -> Annex () +updateTrackingRefs deleteold rmt new = do old <- inRepo $ Git.Ref.forEachRef [Param (decodeBS (trackingRefPrefix rmt))] -- Delete all tracking refs that are not in the map. - forM_ (filter (\p -> M.notMember (fst p) new) old) $ \(s, r) -> - inRepo $ Git.Ref.delete s r + when deleteold $ + forM_ (filter (\p -> M.notMember (fst p) new) old) $ \(s, r) -> + inRepo $ Git.Ref.delete s r -- Update all changed tracking refs. let oldmap = M.fromList (map (\(s, r) -> (r, s)) old) diff --git a/doc/todo/git-remote-annex.mdwn b/doc/todo/git-remote-annex.mdwn index 3d1bb8e75a..9e69bcdb2c 100644 --- a/doc/todo/git-remote-annex.mdwn +++ b/doc/todo/git-remote-annex.mdwn @@ -10,22 +10,7 @@ will be available to users who don't use datalad. This is implememented and working. Remaining todo list for it: -* Bug: Problem with forced push: - - joey@darkstar:~/tmp/bench5/a#ook>git push d ook --force - fatal: bad revision 'refs/namespaces/git-remote-annex/d5a263c6-1c28-432a-a161-914476ae5390/refs/heads/git-annex' - Push failed (user error (git ["--git-dir=.git","--work-tree=.","--literal-pathspecs","bundle","create","--quiet","/home/joey/tmp/GITBUNDLE2690124-1","--stdin"] exited 128)) - warning: helper reported unexpected status of push - Everything up-to-date - - This was preceeded by pushing the git-annex branch and master, - then making 3 commits and pushing each of them in turn. - Then reset back one commit, try to push (which fails as - non-fast-forward), and force push as shown then fails. - - So the problem is not the forced push itself, which works - if a non-forced push is not tried before it, but something - with that specific situation. +* Test incremental push edge cases involving checkprereq. * Cloning from an annex:: url with importtree=yes doesn't work (with or without exporttree=yes). This is because the ContentIdentifier