avoid sync pushing view branches to remotes, and better view branch names
authorJoey Hess <joeyh@joeyh.name>
Wed, 8 Feb 2023 17:55:55 +0000 (13:55 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 8 Feb 2023 17:57:48 +0000 (13:57 -0400)
* sync: Avoid pushing view branches to remotes.
* Changed the name of view branches to include the parent branch.
  Existing view branches checked out using an old name will still work.

It does not seem useful for sync to push view branches around, because
the information in a view branch can entirely be derived from other
information in git. And sync doesn't push adjusted branches around either.

The better view branch names make it more in line with adjusted branch
names, but were also needed to make fromViewBranch be able to return the
original branch name.

Kept the old view branch names still working. But, when those branches
exist in a repo, sync will still try to push them as before. Avoiding
that would need more complicated and/or expensive changes to sync.

Sponsored-By: Boyd Stephen Smith Jr. on Patreon
CHANGELOG
Command/Sync.hs
Logs/View.hs

index a85f79d35af333441d7bcc7303a5f93c0bc59406..5917aeb4e83454cfb2fc31674c35f2f3167c1c95 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,9 @@ git-annex (10.20230127) UNRELEASED; urgency=medium
     in the view for files that do not have the specified metadata set.
   * Added annex.viewunsetdirectory git config to change the name of the
     "_" directory in a view.
+  * Changed the name of view branches to include the parent branch.
+    Existing view branches checked out using an old name will still work.
+  * sync: Avoid pushing view branches to remotes.
 
  -- Joey Hess <id@joeyh.name>  Mon, 06 Feb 2023 13:39:18 -0400
 
index 0334c29b84df1bd92c86baf90f167296cbfbef42..2348f2ea14dbc2f381075e7b3a50f1135dfaa976 100644 (file)
@@ -21,7 +21,6 @@ module Command.Sync (
        commitMsg,
        pushBranch,
        updateBranch,
-       syncBranch,
        updateBranches,
        seekExportContent,
        parseUnrelatedHistoriesOption,
@@ -60,6 +59,7 @@ import Annex.UUID
 import Logs.UUID
 import Logs.Export
 import Logs.PreferredContent
+import Logs.View (fromViewBranch)
 import Annex.AutoMerge
 import Annex.AdjustedBranch
 import Annex.AdjustedBranch.Merge
@@ -310,7 +310,10 @@ merge currbranch mergeconfig o commitmode tomerge = do
                (b, _) -> autoMergeFrom tomerge b mergeconfig commitmode canresolvemerge
 
 syncBranch :: Git.Branch -> Git.Branch
-syncBranch = Git.Ref.underBase "refs/heads/synced" . fromAdjustedBranch
+syncBranch = Git.Ref.underBase "refs/heads/synced" . origBranch
+
+origBranch :: Git.Branch -> Git.Branch
+origBranch = fromViewBranch . fromAdjustedBranch
 
 remoteBranch :: Remote -> Git.Ref -> Git.Ref
 remoteBranch remote = Git.Ref.underBase $ "refs/remotes/" ++ Remote.name remote
@@ -565,7 +568,7 @@ mergeRemote remote currbranch mergeconfig o = ifM isBareRepo
                (mapM (merge currbranch mergeconfig o Git.Branch.ManualCommit . remoteBranch remote) =<< getlist)
        tomerge = filterM (changed remote)
        branchlist Nothing = []
-       branchlist (Just branch) = [fromAdjustedBranch branch, syncBranch branch]
+       branchlist (Just branch) = [origBranch branch, syncBranch branch]
 
 pushRemote :: SyncOptions -> Remote -> CurrBranch -> CommandStart
 pushRemote _o _remote (Nothing, _) = stop
@@ -654,7 +657,7 @@ pushBranch :: Remote -> Maybe Git.Branch -> MessageState -> Git.Repo -> IO Bool
 pushBranch remote mbranch ms g = directpush `after` annexpush `after` syncpush
   where
        syncpush = flip Git.Command.runBool g $ pushparams $ catMaybes
-               [ (refspec . fromAdjustedBranch) <$> mbranch
+               [ (refspec . origBranch) <$> mbranch
                , Just $ Git.Branch.forcePush $ refspec Annex.Branch.name
                ]
        annexpush = void $ tryIO $ flip Git.Command.runQuiet g $ pushparams
@@ -673,7 +676,7 @@ pushBranch remote mbranch ms g = directpush `after` annexpush `after` syncpush
                -- will want to see that one.
                Just branch -> do
                        let p = flip Git.Command.gitCreateProcess g $ pushparams
-                               [ Git.fromRef $ Git.Ref.base $ fromAdjustedBranch branch ]
+                               [ Git.fromRef $ Git.Ref.base $ origBranch branch ]
                        (transcript, ok) <- processTranscript' p Nothing
                        when (not ok && not ("denyCurrentBranch" `isInfixOf` transcript)) $
                                hPutStr stderr transcript
index cde01b1d9bb110f3b6cb137de878acd3c49bb202..b75a0c7b2cd4dfe728b1d536bfb6cc8d9685d500 100644 (file)
@@ -4,7 +4,7 @@
  -
  - This file is stored locally in .git/annex/, not in the git-annex branch.
  -
- - Copyright 2014 Joey Hess <id@joeyh.name>
+ - Copyright 2014-2023 Joey Hess <id@joeyh.name>
  -
  - Licensed under the GNU AGPL version 3 or higher.
  -}
@@ -17,6 +17,7 @@ module Logs.View (
        removeView,
        recentViews,
        branchView,
+       fromViewBranch,
        is_branchView,
        prop_branchView_legal,
 ) where
@@ -58,7 +59,8 @@ currentView :: Annex (Maybe View)
 currentView = go =<< inRepo Git.Branch.current
   where
        go (Just b) | branchViewPrefix `B.isPrefixOf` fromRef' b =
-               headMaybe . filter (\v -> branchView v == b) <$> recentViews
+               headMaybe . filter (\v -> branchView v == b || branchViewOld v == b) 
+                       <$> recentViews
        go _ = return Nothing
 
 branchViewPrefix :: B.ByteString
@@ -67,17 +69,28 @@ branchViewPrefix = "refs/heads/views"
 {- Generates a git branch name for a View.
  - 
  - There is no guarantee that each view gets a unique branch name,
- - but the branch name is used to express the view as well as possible.
+ - but the branch name is used to express the view as well as possible
+ - given the constraints on git branch names. It includes the name of the
+ - parent branch, and what metadata is used.
  -}
 branchView :: View -> Git.Branch
-branchView view
-       | B.null name = Git.Ref branchViewPrefix
-       | otherwise = Git.Ref $ branchViewPrefix <> "/" <> name
+branchView view = Git.Ref $ 
+       branchViewPrefix <> "/" <> basebranch
+               <> "(" <> branchViewDesc view False <> ")"
+  where
+       basebranch = fromRef' (Git.Ref.base (viewParentBranch view))
+
+{- Old name used for a view did not include the name of the parent branch. -}
+branchViewOld :: View -> Git.Branch
+branchViewOld view = Git.Ref $
+        branchViewPrefix <> "/" <> branchViewDesc view True
+
+branchViewDesc :: View -> Bool -> B.ByteString
+branchViewDesc view pareninvisibles = encodeBS $
+       intercalate ";" $ map branchcomp (viewComponents view)
   where
-       name = encodeBS $
-               intercalate ";" $ map branchcomp (viewComponents view)
        branchcomp c
-               | viewVisible c = branchcomp' c
+               | viewVisible c || not pareninvisibles = branchcomp' c
                | otherwise = "(" ++ branchcomp' c ++ ")"
        branchcomp' (ViewComponent metafield viewfilter _) = concat
                [ forcelegal (T.unpack (fromMetaField metafield))
@@ -96,9 +109,22 @@ branchView view
                | otherwise = map (\c -> if isAlphaNum c then c else '_') s
 
 is_branchView :: Git.Branch -> Bool
-is_branchView (Ref b)
-       | b == branchViewPrefix = True
-       | otherwise = (branchViewPrefix <> "/") `B.isPrefixOf` b
+is_branchView (Ref b) = (branchViewPrefix <> "/") `B.isPrefixOf` b
+
+{- Converts a view branch as generated by branchView (but not by
+ - branchViewOld) back to the parent branch.
+ - Has no effect on other branches. -}
+fromViewBranch :: Git.Branch -> Git.Branch
+fromViewBranch b = 
+       let bs = fromRef' b
+       in if (branchViewPrefix <> "/") `B.isPrefixOf` bs
+               then 
+                       let (branch, _desc) = separate' (== openparen) (B.drop prefixlen bs)
+                       in Ref branch
+               else b
+  where
+       prefixlen = B.length branchViewPrefix + 1
+       openparen = fromIntegral (ord '(')
 
 prop_branchView_legal :: View -> Bool
 prop_branchView_legal = Git.Ref.legal False . fromRef . branchView