summaryrefslogtreecommitdiff
path: root/Command
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-06-12 14:54:23 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-06-12 14:54:23 -0400
commit4a3569a6e87620f855aa95deca63bf3c00c028de (patch)
tree39144e545cabbe6c420f53d6e99c0e687462e547 /Command
parent21a95babe51e906223590a540ac26a666426cd37 (diff)
sync: Better support for bare git remotes. Now pushes directly to the master branch on such a remote, instead of to synced/master. This makes it easier to clone from a bare git remote that has been populated with git annex sync or by the assistant.
Diffstat (limited to 'Command')
-rw-r--r--Command/Sync.hs27
1 files changed, 21 insertions, 6 deletions
diff --git a/Command/Sync.hs b/Command/Sync.hs
index 091431bda..a6ae610f8 100644
--- a/Command/Sync.hs
+++ b/Command/Sync.hs
@@ -138,7 +138,8 @@ pullRemote remote branch = do
{- The remote probably has both a master and a synced/master branch.
- Which to merge from? Well, the master has whatever latest changes
- - were committed, while the synced/master may have changes that some
+ - were committed (or pushed changes, if this is a bare remote),
+ - while the synced/master may have changes that some
- other remote synced to this remote. So, merge them both. -}
mergeRemote :: Remote -> (Maybe Git.Ref) -> CommandCleanup
mergeRemote remote b = case b of
@@ -163,15 +164,29 @@ pushRemote remote branch = go =<< needpush
showOutput
inRepo $ pushBranch remote branch
+{- If the remote is a bare git repository, it's best to push the branch
+ - directly to it. On the other hand, if it's not bare, pushing to the
+ - checked out branch will fail, and this is why we use the syncBranch.
+ -
+ - Git offers no way to tell if a remote is bare or not, so both methods
+ - are tried.
+ -
+ - 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
+ - first, and actually sends the data. Then the direct push is tried,
+ - with stderr discarded, to update the branch ref on the remote.
+ -}
pushBranch :: Remote -> Git.Ref -> Git.Repo -> IO Bool
-pushBranch remote branch g =
- Git.Command.runBool
+pushBranch remote branch g = tryIO directpush `after` syncpush
+ where
+ syncpush = Git.Command.runBool (pushparams (refspec branch)) g
+ directpush = Git.Command.runQuiet (pushparams (show $ Git.Ref.base branch)) g
+ pushparams b =
[ Param "push"
, Param $ Remote.name remote
, Param $ refspec Annex.Branch.name
- , Param $ refspec branch
- ] g
- where
+ , Param b
+ ]
refspec b = concat
[ show $ Git.Ref.base b
, ":"