sync, assistant: Force push of the git-annex branch.
Necessary to ensure it gets pushed to remotes after being rewritten by forget. See inline rationalles for why I think this is safe!
This commit is contained in:
parent
c181efe437
commit
6cdac3a003
4 changed files with 48 additions and 18 deletions
|
@ -13,6 +13,7 @@ import qualified Annex.Branch
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import qualified Git.Ref
|
import qualified Git.Ref
|
||||||
import qualified Git.Command
|
import qualified Git.Command
|
||||||
|
import qualified Git.Branch
|
||||||
import Utility.Base64
|
import Utility.Base64
|
||||||
|
|
||||||
{- Converts a git branch into a branch that is tagged with a UUID, typically
|
{- Converts a git branch into a branch that is tagged with a UUID, typically
|
||||||
|
@ -49,12 +50,11 @@ fromTaggedBranch b = case split "/" $ show b of
|
||||||
taggedPush :: UUID -> Maybe String -> Git.Ref -> Remote -> Git.Repo -> IO Bool
|
taggedPush :: UUID -> Maybe String -> Git.Ref -> Remote -> Git.Repo -> IO Bool
|
||||||
taggedPush u info branch remote = Git.Command.runBool
|
taggedPush u info branch remote = Git.Command.runBool
|
||||||
[ Param "push"
|
[ Param "push"
|
||||||
-- This is safe because we "own" the tagged branch we're pushing;
|
|
||||||
-- it has no other writers. Ensures it is pushed even if it has
|
|
||||||
-- been rewritten by a transition.
|
|
||||||
, Param "--force"
|
|
||||||
, Param $ Remote.name remote
|
, Param $ Remote.name remote
|
||||||
, Param $ refspec Annex.Branch.name
|
{- Using forcePush here is safe because we "own" the tagged branch
|
||||||
|
- we're pushing; it has no other writers. Ensures it is pushed
|
||||||
|
- even if it has been rewritten by a transition. -}
|
||||||
|
, Param $ Git.Branch.forcePush $ refspec Annex.Branch.name
|
||||||
, Param $ refspec branch
|
, Param $ refspec branch
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
|
|
|
@ -167,29 +167,45 @@ pushRemote remote branch = go =<< needpush
|
||||||
showOutput
|
showOutput
|
||||||
inRepo $ pushBranch remote branch
|
inRepo $ pushBranch remote branch
|
||||||
|
|
||||||
{- If the remote is a bare git repository, it's best to push the branch
|
{- Pushes a regular branch like master to a remote. Also pushes the git-annex
|
||||||
- directly to it. On the other hand, if it's not bare, pushing to the
|
- branch.
|
||||||
- checked out branch will fail, and this is why we use the syncBranch.
|
-
|
||||||
|
- If the remote is a bare git repository, it's best to push the regular
|
||||||
|
- branch directly to it, so that cloning/pulling will get it.
|
||||||
|
- On the other hand, if it's not bare, pushing to the checked out branch
|
||||||
|
- will fail, and this is why we push to its syncBranch.
|
||||||
-
|
-
|
||||||
- Git offers no way to tell if a remote is bare or not, so both methods
|
- Git offers no way to tell if a remote is bare or not, so both methods
|
||||||
- are tried.
|
- are tried.
|
||||||
-
|
-
|
||||||
- The direct push is likely to spew an ugly error message, so stderr is
|
- The direct push is likely to spew an ugly error message, so stderr is
|
||||||
- elided. Since progress is output to stderr too, the sync push is done
|
- elided. Since git progress display goes to stderr too, the sync push
|
||||||
- first, and actually sends the data. Then the direct push is tried,
|
- is done first, and actually sends the data. Then the direct push is
|
||||||
- with stderr discarded, to update the branch ref on the remote.
|
- tried, with stderr discarded, to update the branch ref on the remote.
|
||||||
|
-
|
||||||
|
- The sync push forces the update of the remote synced/git-annex branch.
|
||||||
|
- This is necessary if a transition has rewritten the git-annex branch.
|
||||||
|
- Normally any changes to the git-annex branch get pulled and merged before
|
||||||
|
- this push, so this forcing is unlikely to overwrite new data pushed
|
||||||
|
- in from another repository that is also syncing.
|
||||||
|
-
|
||||||
|
- But overwriting of data on synced/git-annex can happen, in a race.
|
||||||
|
- The only difference caused by using a forced push in that case is that
|
||||||
|
- the last repository to push wins the race, rather than the first to push.
|
||||||
-}
|
-}
|
||||||
pushBranch :: Remote -> Git.Ref -> Git.Repo -> IO Bool
|
pushBranch :: Remote -> Git.Ref -> Git.Repo -> IO Bool
|
||||||
pushBranch remote branch g = tryIO directpush `after` syncpush
|
pushBranch remote branch g = tryIO (directpush g) `after` syncpush g
|
||||||
where
|
where
|
||||||
syncpush = Git.Command.runBool (pushparams (refspec branch)) g
|
syncpush = Git.Command.runBool $ pushparams
|
||||||
directpush = Git.Command.runQuiet (pushparams (show $ Git.Ref.base branch)) g
|
[ Git.Branch.forcePush $ refspec Annex.Branch.name
|
||||||
pushparams b =
|
, refspec branch
|
||||||
|
]
|
||||||
|
directpush = Git.Command.runQuiet $ pushparams
|
||||||
|
[show $ Git.Ref.base branch]
|
||||||
|
pushparams branches =
|
||||||
[ Param "push"
|
[ Param "push"
|
||||||
, Param $ Remote.name remote
|
, Param $ Remote.name remote
|
||||||
, Param $ refspec Annex.Branch.name
|
] ++ map Param branches
|
||||||
, Param b
|
|
||||||
]
|
|
||||||
refspec b = concat
|
refspec b = concat
|
||||||
[ show $ Git.Ref.base b
|
[ show $ Git.Ref.base b
|
||||||
, ":"
|
, ":"
|
||||||
|
|
|
@ -101,3 +101,7 @@ commit message branch parentrefs repo = do
|
||||||
return sha
|
return sha
|
||||||
where
|
where
|
||||||
ps = concatMap (\r -> ["-p", show r]) parentrefs
|
ps = concatMap (\r -> ["-p", show r]) parentrefs
|
||||||
|
|
||||||
|
{- A leading + makes git-push force pushing a branch. -}
|
||||||
|
forcePush :: String -> String
|
||||||
|
forcePush b = "+" ++ b
|
||||||
|
|
10
debian/changelog
vendored
10
debian/changelog
vendored
|
@ -1,3 +1,13 @@
|
||||||
|
git-annex (4.20130828) UNRELEASED; urgency=low
|
||||||
|
|
||||||
|
* forget: New command, causes git-annex branch history to be forgotten
|
||||||
|
in a way that will spread to other clones of the repository.
|
||||||
|
(As long as they're running this version or newer of git-annex.)
|
||||||
|
* sync, assistant: Force push of the git-annex branch. Necessary
|
||||||
|
to ensure it gets pushed to remotes after being rewritten by forget.
|
||||||
|
|
||||||
|
-- Joey Hess <joeyh@debian.org> Tue, 27 Aug 2013 11:03:00 -0400
|
||||||
|
|
||||||
git-annex (4.20130827) unstable; urgency=low
|
git-annex (4.20130827) unstable; urgency=low
|
||||||
|
|
||||||
* Youtube support! (And 53 other video hosts). When quvi is installed,
|
* Youtube support! (And 53 other video hosts). When quvi is installed,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue