When pushing branch foo, we don't want to delete other tracking
branches. In particular, a full push needs all the tracking branches.
This commit is contained in:
Joey Hess 2024-05-14 16:17:27 -04:00
parent 169e673ad4
commit 2dfffa0621
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 11 additions and 24 deletions

View file

@ -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)

View file

@ -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