packages feed

git-annex 6.20170519 → 6.20170520

raw patch · 34 files changed

+334/−136 lines, 34 files

Files

Annex/AdjustedBranch.hs view
@@ -318,8 +318,8 @@ {- Update the currently checked out adjusted branch, merging the provided  - branch into it. Note that the provided branch should be a non-adjusted  - branch. -}-updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool-updateAdjustedBranch tomerge (origbranch, adj) mergeconfig commitmode = catchBoolIO $+updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> [Git.Merge.MergeConfig] -> Annex Bool -> Git.Branch.CommitMode -> Annex Bool+updateAdjustedBranch tomerge (origbranch, adj) mergeconfig canresolvemerge commitmode = catchBoolIO $ 	join $ preventCommits go   where 	adjbranch@(AdjBranch currbranch) = originalToAdjusted origbranch adj@@ -417,7 +417,7 @@ 		-- this commit will be a fast-forward. 		adjmergecommitff <- commitAdjustedTree' adjtree (BasisBranch mergecommit) [currbranch] 		showAction "Merging into adjusted branch"-		ifM (autoMergeFrom adjmergecommitff (Just currbranch) mergeconfig commitmode)+		ifM (autoMergeFrom adjmergecommitff (Just currbranch) mergeconfig canresolvemerge commitmode) 			( reparent adjtree adjmergecommit =<< getcurrentcommit 			, return False 			)
Annex/AutoMerge.hs view
@@ -43,18 +43,18 @@  - Callers should use Git.Branch.changed first, to make sure that  - there are changes from the current branch to the branch being merged in.  -}-autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool-autoMergeFrom branch currbranch mergeconfig commitmode = do+autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> [Git.Merge.MergeConfig] -> Annex Bool -> Git.Branch.CommitMode -> Annex Bool+autoMergeFrom branch currbranch mergeconfig canresolvemerge commitmode = do 	showOutput 	case currbranch of 		Nothing -> go Nothing 		Just b -> go =<< inRepo (Git.Ref.sha b)   where 	go old = ifM isDirect-		( mergeDirect currbranch old branch (resolveMerge old branch False) mergeconfig commitmode+		( mergeDirect currbranch old branch resolvemerge mergeconfig commitmode 		, do 			r <- inRepo (Git.Merge.merge branch mergeconfig commitmode)-				<||> (resolveMerge old branch False <&&> commitResolvedMerge commitmode)+				<||> (resolvemerge <&&> commitResolvedMerge commitmode) 			-- Merging can cause new associated files to appear 			-- and the smudge filter will add them to the database. 			-- To ensure that this process sees those changes,@@ -62,6 +62,11 @@ 			Database.Keys.closeDb 			return r 		)+	  where+		resolvemerge = ifM canresolvemerge+			( resolveMerge old branch False+			, return False +			)  {- Resolves a conflicted merge. It's important that any conflicts be  - resolved in a way that itself avoids later merge conflicts, since
Annex/Ssh.hs view
@@ -193,8 +193,10 @@  	c <- Annex.getState Annex.concurrency 	case c of-		Concurrent {} -> makeconnection socketlock-		NonConcurrent -> return ()+		Concurrent {}+			| annexUUID (remoteGitConfig gc) /= NoUUID ->+				makeconnection socketlock+		_ -> return () 	 	lockFileCached socketlock   where@@ -207,11 +209,15 @@ 			-- When we can start the connection in batch mode, 			-- ssh won't prompt to the console. 			(_, connected) <- liftIO $ processTranscript "ssh"-				(["-o", "BatchMode=true"] ++ toCommand startps)+				(["-o", "BatchMode=true"]+				++ toCommand startps) 				Nothing-			unless connected $ -				prompt $ void $ liftIO $+			unless connected $ do+				ok <- prompt $ liftIO $ 					boolSystem "ssh" startps+				unless ok $+					warning $ "Unable to run git-annex-shell on remote " +++						Git.repoDescribe (gitConfigRepo (remoteGitConfig gc))  -- Parameters to get ssh connected to the remote host, -- by asking it to run a no-op command.
Annex/Transfer.hs view
@@ -118,7 +118,9 @@ 					void $ liftIO $ tryIO $ 						writeTransferInfoFile info tfile 					return (Just lockhandle, False)-				, return (Nothing, True)+				, do+					liftIO $ dropLock lockhandle+					return (Nothing, True) 				) #else 	prep tfile _mode info = catchPermissionDenied (const prepfailed) $ do
Assistant/Sync.hs view
@@ -211,7 +211,8 @@ 		else return Nothing 	haddiverged <- liftAnnex Annex.Branch.forceUpdate 	forM_ normalremotes $ \r ->-		liftAnnex $ Command.Sync.mergeRemote r currentbranch Command.Sync.mergeConfig+		liftAnnex $ Command.Sync.mergeRemote r+			currentbranch Command.Sync.mergeConfig def 	return (catMaybes failed, haddiverged)   where 	wantpull gc = remoteAnnexPull gc
Assistant/Threads/Merger.hs view
@@ -1,6 +1,6 @@ {- git-annex assistant git merge thread  -- - Copyright 2012 Joey Hess <id@joeyh.name>+ - Copyright 2012-2017 Joey Hess <id@joeyh.name>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -15,6 +15,7 @@ import qualified Annex.Branch import qualified Git import qualified Git.Branch+import qualified Git.Ref import qualified Command.Sync  {- This thread watches for changes to .git/refs/, and handles incoming@@ -63,14 +64,14 @@ 		diverged <- liftAnnex Annex.Branch.forceUpdate 		when diverged $ 			queueDeferredDownloads "retrying deferred download" Later-	| "/synced/" `isInfixOf` file =-		mergecurrent =<< liftAnnex (join Command.Sync.getCurrBranch)-	| otherwise = noop+	| otherwise = mergecurrent   where 	changedbranch = fileToBranch file -	mergecurrent currbranch@(Just b, _)-		| equivBranches changedbranch b =+	mergecurrent =+		mergecurrent' =<< liftAnnex (join Command.Sync.getCurrBranch)+	mergecurrent' currbranch@(Just b, _)+		| changedbranch `isRelatedTo` b = 			whenM (liftAnnex $ inRepo $ Git.Branch.changed b changedbranch) $ do 				debug 					[ "merging", Git.fromRef changedbranch@@ -78,14 +79,22 @@ 					] 				void $ liftAnnex $ Command.Sync.merge 					currbranch Command.Sync.mergeConfig+					def 					Git.Branch.AutomaticCommit 					changedbranch-	mergecurrent _ = noop+	mergecurrent' _ = noop -equivBranches :: Git.Ref -> Git.Ref -> Bool-equivBranches x y = base x == base y+{- Is the first branch a synced branch or remote tracking branch related+ - to the second branch, which should be merged into it? -}+isRelatedTo :: Git.Ref -> Git.Ref -> Bool+isRelatedTo x y+	| basex /= takeDirectory basex ++ "/" ++ basey = False+	| "/synced/" `isInfixOf` Git.fromRef x = True+	| "refs/remotes/" `isPrefixOf` Git.fromRef x = True+	| otherwise = False   where-	base = takeFileName . Git.fromRef+	basex = Git.fromRef $ Git.Ref.base x+	basey = Git.fromRef $ Git.Ref.base y  isAnnexBranch :: FilePath -> Bool isAnnexBranch f = n `isSuffixOf` f
Build/OSXMkLibs.hs view
@@ -25,6 +25,7 @@ import Utility.Exception import Utility.Env import Utility.Misc+import Utility.Split  import qualified Data.Map as M import qualified Data.Set as S
CHANGELOG view
@@ -1,3 +1,38 @@+git-annex (6.20170520) unstable; urgency=medium++  * move --to=here moves from all reachable remotes to the local repository.+  * initremote, enableremote: Support gpg subkeys suffixed with an+    exclamation mark, which forces gpg to use a specific subkey.+  * Improve progress display when watching file size, in cases where+    a transfer does not resume.+  * Fix transfer log file locking problem when running concurrent+    transfers.+  * Avoid concurrent git-config setting problem when running concurrent+    threads.+  * metadata: When setting metadata of a file that did not exist,+    no error message was displayed, unlike getting metadata and most other+    git-annex commands. Fixed this oversight.+  * Added annex.resolvemerge configuration, which can be set to false to +    disable the usual automatic merge conflict resolution done by git-annex+    sync and the assistant.+  * sync: Added --no-resolvemerge option.+  * Avoid error about git-annex-shell not being found when+    syncing with -J with a git remote where git-annex-shell is not+    installed.+  * Fix bug that prevented transfer locks from working when+    run on SMB or other filesystem that does not support fcntl locks+    and hard links.+  * assistant: Merge changes from refs/remotes/foo/master into master.+    Previously, only sync branches were merged. This makes regular git push+    into a repository watched by the assistant auto-merge.+  * Makefile: Install completions for the fish and zsh shells+    when git-annex is built with optparse-applicative-0.14.+  * assistant: Don't trust OSX FSEvents's eventFlagItemModified to be called+    when the last writer of a file closes it; apparently that sometimes+    does not happen, which prevented files from being quickly added.++ -- Joey Hess <id@joeyh.name>  Mon, 12 Jun 2017 13:37:16 -0400+ git-annex (6.20170519) unstable; urgency=medium    * Ssh password prompting improved when using -J for concurrency.
CmdLine/Action.hs view
@@ -16,6 +16,7 @@ import Types.Concurrency import Messages.Concurrent import Types.Messages+import Remote.List  import Control.Concurrent.Async import Control.Exception (throwIO)@@ -57,6 +58,12 @@ 		ws <- Annex.getState Annex.workers 		(st, ws') <- if null ws 			then do+				-- Generate the remote list now, to avoid+				-- each thread generating it, which would+				-- be more expensive and could cause+				-- threads to contend over eg, calls to+				-- setConfig.+				_ <- remoteList 				st <- dupState 				return (st, replicate (n-1) (Left st)) 			else do
CmdLine/GitAnnex/Options.hs view
@@ -1,6 +1,6 @@ {- git-annex command-line option parsing  -- - Copyright 2010-2015 Joey Hess <id@joeyh.name>+ - Copyright 2010-2017 Joey Hess <id@joeyh.name>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -97,6 +97,7 @@ cmdParams :: CmdParamsDesc -> Parser CmdParams cmdParams paramdesc = many $ argument str 	( metavar paramdesc+	<> action "file" 	)  parseAutoOption :: Parser Bool@@ -105,10 +106,10 @@ 	<> help "automatic mode" 	) -parseRemoteOption :: Parser RemoteName -> Parser (DeferredParse Remote)-parseRemoteOption p = DeferredParse +parseRemoteOption :: RemoteName -> DeferredParse Remote+parseRemoteOption = DeferredParse  	. (fromJust <$$> Remote.byNameWithUUID)-	. Just <$> p+	. Just  data FromToOptions 	= FromRemote (DeferredParse Remote)@@ -120,18 +121,18 @@  parseFromToOptions :: Parser FromToOptions parseFromToOptions = -	(FromRemote <$> parseFromOption) -	<|> (ToRemote <$> parseToOption)+	(FromRemote . parseRemoteOption <$> parseFromOption) +	<|> (ToRemote . parseRemoteOption <$> parseToOption) -parseFromOption :: Parser (DeferredParse Remote)-parseFromOption = parseRemoteOption $ strOption+parseFromOption :: Parser RemoteName+parseFromOption = strOption 	( long "from" <> short 'f' <> metavar paramRemote 	<> help "source remote" 	<> completeRemotes 	) -parseToOption :: Parser (DeferredParse Remote)-parseToOption = parseRemoteOption $ strOption+parseToOption :: Parser RemoteName+parseToOption = strOption 	( long "to" <> short 't' <> metavar paramRemote 	<> help "destination remote" 	<> completeRemotes
CmdLine/Seek.hs view
@@ -41,7 +41,9 @@ 	( withFilesInGit a params 	, if null params 		then giveup needforce-		else seekActions $ prepFiltered a (getfiles [] params)+		else do+			checkFileOrDirectoryExists params+			seekActions $ prepFiltered a (getfiles [] params) 	)   where 	getfiles c [] = return (reverse c)@@ -243,12 +245,15 @@  seekHelper :: ([FilePath] -> Git.Repo -> IO ([FilePath], IO Bool)) -> [FilePath] -> Annex [FilePath] seekHelper a params = do-	forM_ params $ \p ->-		unlessM (isJust <$> liftIO (catchMaybeIO $ getSymbolicLinkStatus p)) $ do-			toplevelWarning False (p ++ " not found")-			Annex.incError+	checkFileOrDirectoryExists params 	inRepo $ \g -> concat . concat <$> forM (segmentXargsOrdered params) 		(runSegmentPaths (\fs -> Git.Command.leaveZombie <$> a fs g))++checkFileOrDirectoryExists :: [FilePath] -> Annex ()+checkFileOrDirectoryExists ps = forM_ ps $ \p ->+	unlessM (isJust <$> liftIO (catchMaybeIO $ getSymbolicLinkStatus p)) $ do+		toplevelWarning False (p ++ " not found")+		Annex.incError  notSymlink :: FilePath -> IO Bool notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
Command/Copy.hs view
@@ -52,7 +52,10 @@ 		| autoMode o = want <||> numCopiesCheck file key (<) 		| otherwise = return True 	want = case Command.Move.fromToOptions (moveOptions o) of-		ToRemote dest -> (Remote.uuid <$> getParsed dest) >>=-			wantSend False (Just key) (AssociatedFile (Just file))-		FromRemote _ ->-			wantGet False (Just key) (AssociatedFile (Just file))+		Right (ToRemote dest) ->+			(Remote.uuid <$> getParsed dest) >>= checkwantsend+		Right (FromRemote _) -> checkwantget+		Left Command.Move.ToHere -> checkwantget+			+	checkwantsend = wantSend False (Just key) (AssociatedFile (Just file))+	checkwantget = wantGet False (Just key) (AssociatedFile (Just file))
Command/Drop.hs view
@@ -45,7 +45,7 @@ 	<*> parseBatchOption  parseDropFromOption :: Parser (DeferredParse Remote)-parseDropFromOption = parseRemoteOption $ strOption+parseDropFromOption = parseRemoteOption <$> strOption 	( long "from" <> short 'f' <> metavar paramRemote 	<> help "drop content from a remote" 	<> completeRemotes
Command/Fsck.hs view
@@ -62,7 +62,7 @@ optParser :: CmdParamsDesc -> Parser FsckOptions optParser desc = FsckOptions 	<$> cmdParams desc-	<*> optional (parseRemoteOption $ strOption +	<*> optional (parseRemoteOption <$> strOption  		( long "from" <> short 'f' <> metavar paramRemote  		<> help "check remote" 		<> completeRemotes
Command/Get.hs view
@@ -32,7 +32,7 @@ optParser :: CmdParamsDesc -> Parser GetOptions optParser desc = GetOptions 	<$> cmdParams desc-	<*> optional parseFromOption+	<*> optional (parseRemoteOption <$> parseFromOption) 	<*> parseAutoOption 	<*> optional (parseIncompleteOption <|> parseKeyOptions <|> parseFailedTransfersOption) 	<*> parseBatchOption
Command/Merge.hs view
@@ -33,4 +33,4 @@ mergeSynced :: CommandStart mergeSynced = do 	prepMerge-	mergeLocal mergeConfig =<< join getCurrBranch+	mergeLocal mergeConfig def =<< join getCurrBranch
Command/Move.hs view
@@ -1,6 +1,6 @@ {- git-annex command  -- - Copyright 2010-2015 Joey Hess <id@joeyh.name>+ - Copyright 2010-2017 Joey Hess <id@joeyh.name>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -27,20 +27,29 @@  data MoveOptions = MoveOptions 	{ moveFiles :: CmdParams-	, fromToOptions :: FromToOptions+	, fromToOptions :: Either ToHere FromToOptions 	, keyOptions :: Maybe KeyOptions 	} +data ToHere = ToHere+ optParser :: CmdParamsDesc -> Parser MoveOptions optParser desc = MoveOptions 	<$> cmdParams desc-	<*> parseFromToOptions+	<*> (parsefrom <|> parseto) 	<*> optional (parseKeyOptions <|> parseFailedTransfersOption)+  where+	parsefrom = Right . FromRemote . parseRemoteOption <$> parseFromOption+	parseto = herespecialcase <$> parseToOption+	  where+		herespecialcase "here" = Left ToHere+		herespecialcase "." = Left ToHere+		herespecialcase n = Right $ ToRemote $ parseRemoteOption n  instance DeferredParseClass MoveOptions where 	finishParse v = MoveOptions 		<$> pure (moveFiles v)-		<*> finishParse (fromToOptions v)+		<*> either (pure . Left) (Right <$$> finishParse) (fromToOptions v) 		<*> pure (keyOptions v)  seek :: MoveOptions -> CommandSeek@@ -61,10 +70,15 @@ start' :: MoveOptions -> Bool -> AssociatedFile -> Key -> ActionItem -> CommandStart start' o move afile key ai =  	case fromToOptions o of-		FromRemote src -> checkFailedTransferDirection ai Download $-			fromStart move afile key ai =<< getParsed src-		ToRemote dest -> checkFailedTransferDirection ai Upload $-			toStart move afile key ai =<< getParsed dest+		Right (FromRemote src) ->+			checkFailedTransferDirection ai Download $+				fromStart move afile key ai =<< getParsed src+		Right (ToRemote dest) ->+			checkFailedTransferDirection ai Upload $+				toStart move afile key ai =<< getParsed dest+		Left ToHere ->+			checkFailedTransferDirection ai Download $+				toHereStart move afile key ai  showMoveAction :: Bool -> Key -> ActionItem -> Annex () showMoveAction move = showStart' (if move then "move" else "copy")@@ -171,14 +185,15 @@ 		return $ u /= Remote.uuid src && elem src remotes  fromPerform :: Remote -> Bool -> Key -> AssociatedFile -> CommandPerform-fromPerform src move key afile = ifM (inAnnex key)-	( dispatch move True-	, dispatch move =<< go-	)+fromPerform src move key afile = do+	showAction $ "from " ++ Remote.name src+	ifM (inAnnex key)+		( dispatch move True+		, dispatch move =<< go+		)   where 	go = notifyTransfer Download afile $ -		download (Remote.uuid src) key afile forwardRetry $ \p -> do-			showAction $ "from " ++ Remote.name src+		download (Remote.uuid src) key afile forwardRetry $ \p -> 			getViaTmp (RemoteVerify src) key $ \t -> 				Remote.retrieveKeyFile src key afile t p 	dispatch _ False = stop -- failed@@ -198,3 +213,20 @@ 		ok <- Remote.removeKey src key 		next $ Command.Drop.cleanupRemote key src ok 	faileddropremote = giveup "Unable to drop from remote."++{- Moves (or copies) the content of an annexed file from reachable remotes+ - to the current repository.+ -+ - When moving, the content is removed from all the reachable remotes. -}+toHereStart ::  Bool -> AssociatedFile -> Key -> ActionItem -> CommandStart+toHereStart move afile key ai+	| move = go+	| otherwise = stopUnless (not <$> inAnnex key) go+  where+	go = do+		rs <- Remote.keyPossibilities key+		forM_ rs $ \r ->+			includeCommandAction $ do+				showMoveAction move key ai+				next $ fromPerform r move key afile+		stop
Command/PostReceive.hs view
@@ -48,4 +48,4 @@ updateInsteadEmulation :: CommandStart updateInsteadEmulation = do 	prepMerge-	mergeLocal mergeConfig =<< join getCurrBranch+	mergeLocal mergeConfig def =<< join getCurrBranch
Command/Sync.hs view
@@ -76,8 +76,14 @@ 	, noContentOption :: Bool 	, contentOfOption :: [FilePath] 	, keyOptions :: Maybe KeyOptions+	, resolveMergeOverride :: ResolveMergeOverride 	} +newtype ResolveMergeOverride = ResolveMergeOverride Bool++instance Default ResolveMergeOverride where+	def = ResolveMergeOverride False+ optParser :: CmdParamsDesc -> Parser SyncOptions optParser desc = SyncOptions 	<$> (many $ argument str@@ -117,6 +123,9 @@ 		<> metavar paramPath 		)) 	<*> optional parseAllOption+	<*> (ResolveMergeOverride <$> invertableSwitch "resolvemerge" True+		( help "do not automatically resolve merge conflicts"+		))  -- Since prepMerge changes the working directory, FilePath options -- have to be adjusted.@@ -132,6 +141,7 @@ 		<*> pure (noContentOption v) 		<*> liftIO (mapM absPath (contentOfOption v)) 		<*> pure (keyOptions v)+		<*> pure (resolveMergeOverride v)  seek :: SyncOptions -> CommandSeek seek o = allowConcurrentOutput $ do@@ -150,7 +160,7 @@ 	-- These actions cannot be run concurrently. 	mapM_ includeCommandAction $ concat 		[ [ commit o ]-		, [ withbranch (mergeLocal mergeConfig) ]+		, [ withbranch (mergeLocal mergeConfig (resolveMergeOverride o)) ] 		, map (withbranch . pullRemote o mergeConfig) gitremotes 		,  [ mergeAnnex ] 		]@@ -219,11 +229,14 @@ 	, Git.Merge.MergeUnrelatedHistories 	] -merge :: CurrBranch -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool-merge (Just b, Just adj) mergeconfig commitmode tomerge =-	updateAdjustedBranch tomerge (b, adj) mergeconfig commitmode-merge (b, _) mergeconfig commitmode tomerge =-	autoMergeFrom tomerge b mergeconfig commitmode+merge :: CurrBranch -> [Git.Merge.MergeConfig] -> ResolveMergeOverride -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool+merge currbranch mergeconfig resolvemergeoverride commitmode tomerge = case currbranch of+	(Just b, Just adj) -> updateAdjustedBranch tomerge (b, adj) mergeconfig canresolvemerge commitmode+	(b, _) -> autoMergeFrom tomerge b mergeconfig canresolvemerge commitmode+  where+	canresolvemerge = case resolvemergeoverride of+		ResolveMergeOverride True -> getGitConfigVal annexResolveMerge+		ResolveMergeOverride False -> return False  syncBranch :: Git.Branch -> Git.Branch syncBranch = Git.Ref.underBase "refs/heads/synced" . fromDirectBranch . fromAdjustedBranch@@ -296,15 +309,15 @@ 	void $ inRepo $ Git.Branch.commit commitmode False commitmessage branch parents 	return True -mergeLocal :: [Git.Merge.MergeConfig] -> CurrBranch -> CommandStart-mergeLocal mergeconfig currbranch@(Just _, _) =+mergeLocal :: [Git.Merge.MergeConfig] -> ResolveMergeOverride -> CurrBranch -> CommandStart+mergeLocal mergeconfig resolvemergeoverride currbranch@(Just _, _) = 	go =<< needMerge currbranch   where 	go Nothing = stop 	go (Just syncbranch) = do 		showStart "merge" $ Git.Ref.describe syncbranch-		next $ next $ merge currbranch mergeconfig Git.Branch.ManualCommit syncbranch-mergeLocal _ (Nothing, madj) = do+		next $ next $ merge currbranch mergeconfig resolvemergeoverride Git.Branch.ManualCommit syncbranch+mergeLocal _ _ (Nothing, madj) = do 	b <- inRepo Git.Branch.currentUnsafe 	ifM (isJust <$> needMerge (b, madj)) 		( do@@ -365,7 +378,7 @@ 	next $ do 		showOutput 		stopUnless fetch $-			next $ mergeRemote remote branch mergeconfig+			next $ mergeRemote remote branch mergeconfig (resolveMergeOverride o)   where 	fetch = inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $ 		Git.Command.runBool@@ -377,8 +390,8 @@  - 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 -> CurrBranch -> [Git.Merge.MergeConfig] -> CommandCleanup-mergeRemote remote currbranch mergeconfig = ifM isBareRepo+mergeRemote :: Remote -> CurrBranch -> [Git.Merge.MergeConfig] -> ResolveMergeOverride -> CommandCleanup+mergeRemote remote currbranch mergeconfig resolvemergeoverride = ifM isBareRepo 	( return True 	, case currbranch of 		(Nothing, _) -> do@@ -390,7 +403,7 @@ 	)   where 	mergelisted getlist = and <$> -		(mapM (merge currbranch mergeconfig Git.Branch.ManualCommit . remoteBranch remote) =<< getlist)+		(mapM (merge currbranch mergeconfig resolvemergeoverride Git.Branch.ManualCommit . remoteBranch remote) =<< getlist) 	tomerge = filterM (changed remote) 	branchlist Nothing = [] 	branchlist (Just branch) = [branch, syncBranch branch]
Types/GitConfig.hs view
@@ -58,6 +58,7 @@ 	, annexHttpHeaders :: [String] 	, annexHttpHeadersCommand :: Maybe String 	, annexAutoCommit :: Configurable Bool+	, annexResolveMerge :: Configurable Bool 	, annexSyncContent :: Configurable Bool 	, annexDebug :: Bool 	, annexWebOptions :: [String]@@ -115,6 +116,8 @@ 	, annexHttpHeadersCommand = getmaybe (annex "http-headers-command") 	, annexAutoCommit = configurable True $  		getmaybebool (annex "autocommit")+	, annexResolveMerge = configurable True $ +		getmaybebool (annex "resolvemerge") 	, annexSyncContent = configurable False $  		getmaybebool (annex "synccontent") 	, annexDebug = getbool (annex "debug") False
Utility/DirWatcher.hs view
@@ -64,18 +64,18 @@ {- With inotify, file closing is tracked to some extent, so an add event  - will always be received for a file once its writer closes it, and  - (typically) not before. This may mean multiple add events for the same file.- - - - fsevents behaves similarly, although different event types are used for- - creating and modification of the file.  -  - OTOH, with kqueue, add events will often be received while a file is  - still being written to, and then no add event will be received once the- - writer closes it. -}+ - writer closes it.+ - + - fsevents sometimes behaves similarly, but has sometimes been + - seen to behave like kqueue. -} closingTracked :: Bool-#if (WITH_INOTIFY || WITH_FSEVENTS || WITH_WIN32NOTIFY)+#if (WITH_INOTIFY || WITH_WIN32NOTIFY) closingTracked = True #else-#if WITH_KQUEUE+#if (WITH_KQUEUE || WITH_FSEVENTS) closingTracked = False #else closingTracked = error "closingTracked not defined"
Utility/Gpg.hs view
@@ -22,6 +22,7 @@ import Control.Concurrent import Control.Monad.IO.Class import qualified Data.Map as M+import Data.Char  type KeyId = String @@ -157,12 +158,20 @@  - a key id, or a name; See the section 'HOW TO SPECIFY A USER ID' of  - GnuPG's manpage.) -} findPubKeys :: GpgCmd -> String -> IO KeyIds-findPubKeys cmd for = KeyIds . parse . lines <$> readStrict cmd params+findPubKeys cmd for+	-- pass forced subkey through as-is rather than+	-- looking up the master key.+	| isForcedSubKey for = return $ KeyIds [for]+	| otherwise = KeyIds . parse . lines <$> readStrict cmd params   where 	params = [Param "--with-colons", Param "--list-public-keys", Param for] 	parse = mapMaybe (keyIdField . splitc ':') 	keyIdField ("pub":_:_:_:f:_) = Just f 	keyIdField _ = Nothing++{- "subkey!" tells gpg to force use of a specific subkey -}+isForcedSubKey :: String -> Bool+isForcedSubKey s = "!" `isSuffixOf` s && all isHexDigit (drop 1 s)  type UserId = String 
Utility/LockFile/PidLock.hs view
@@ -122,18 +122,22 @@ 	setFileMode tmp (combineModes readModes) 	hPutStr h . show =<< mkPidLock 	hClose h-	st <- getFileStatus tmp-	let failedlock = do+	let failedlock st = do 		dropLock $ LockHandle tmp st sidelock+		nukeFile tmp 		return Nothing-	let tooklock = return $ Just $ LockHandle lockfile' st sidelock+	let tooklock st = return $ Just $ LockHandle lockfile' st sidelock 	ifM (linkToLock sidelock tmp lockfile') 		( do 			nukeFile tmp-			tooklock+			-- May not have made a hard link, so stat+			-- the lockfile+			lckst <- getFileStatus lockfile'+			tooklock lckst 		, do 			v <- readPidLock lockfile' 			hn <- getHostName+			tmpst <- getFileStatus tmp 			case v of 				Just pl | isJust sidelock && hn == lockingHost pl -> do 					-- Since we have the sidelock,@@ -142,8 +146,8 @@ 					-- we know that the pidlock is 					-- stale, and can take it over. 					rename tmp lockfile'-					tooklock-				_ -> failedlock+					tooklock tmpst+				_ -> failedlock tmpst 		)  -- Linux's open(2) man page recommends linking a pid lock into place,
Utility/LockPool/STM.hs view
@@ -49,9 +49,9 @@  -- A shared global variable for the lockPool. Avoids callers needing to -- maintain state for this implementation detail.+{-# NOINLINE lockPool #-} lockPool :: LockPool lockPool = unsafePerformIO (newTMVarIO M.empty)-{-# NOINLINE lockPool #-}  -- Updates the LockPool, blocking as necessary if another thread is holding -- a conflicting lock.@@ -62,23 +62,23 @@ -- Keeping the whole Map in a TMVar accomplishes this, at the expense of -- sometimes retrying after unrelated changes in the map. waitTakeLock :: LockPool -> LockFile -> LockMode -> STM LockHandle-waitTakeLock pool file mode = do-	m <- takeTMVar pool-	v <- case M.lookup file m of-		Just (LockStatus mode' n closelockfile)-			| mode == LockShared && mode' == LockShared ->-				return $ LockStatus mode (succ n) closelockfile-			| n > 0 -> retry -- wait for lock-		_ -> return $ LockStatus mode 1 noop-	putTMVar pool (M.insert file v m)-	newTMVar (pool, file)+waitTakeLock pool file mode = maybe retry return =<< tryTakeLock pool file mode  -- Avoids blocking if another thread is holding a conflicting lock. tryTakeLock :: LockPool -> LockFile -> LockMode -> STM (Maybe LockHandle)-tryTakeLock pool file mode =-	(Just <$> waitTakeLock pool file mode)-		`orElse`-	return Nothing+tryTakeLock pool file mode = do+	m <- takeTMVar pool+	let success v = do+		putTMVar pool (M.insert file v m)+		Just <$> newTMVar (pool, file)+	case M.lookup file m of+		Just (LockStatus mode' n closelockfile)+			| mode == LockShared && mode' == LockShared ->+				success $ LockStatus mode (succ n) closelockfile+			| n > 0 -> do+				putTMVar pool m+				return Nothing+		_ -> success $ LockStatus mode 1 noop  -- Call after waitTakeLock or tryTakeLock, to register a CloseLockFile -- action to run when releasing the lock.
Utility/Metered.hs view
@@ -171,22 +171,27 @@ 	k = 1024 	chunkOverhead = 2 * sizeOf (1 :: Int) -- GHC specific -{- Runs an action, watching a file as it grows and updating the meter. -}+{- Runs an action, watching a file as it grows and updating the meter.+ -+ - The file may already exist, and the action could throw the original file+ - away and start over. To avoid reporting the original file size followed+ - by a smaller size in that case, wait until the file starts growing+ - before updating the meter for the first time.+ -} watchFileSize :: (MonadIO m, MonadMask m) => FilePath -> MeterUpdate -> m a -> m a watchFileSize f p a = bracket -	(liftIO $ forkIO $ watcher zeroBytesProcessed)+	(liftIO $ forkIO $ watcher =<< getsz) 	(liftIO . void . tryIO . killThread) 	(const a)   where 	watcher oldsz = do-		v <- catchMaybeIO $ toBytesProcessed <$> getFileSize f-		newsz <- case v of-			Just sz | sz /= oldsz -> do-				p sz-				return sz-			_ -> return oldsz 		threadDelay 500000 -- 0.5 seconds-		watcher newsz+		sz <- getsz+		when (sz > oldsz) $+			p sz+		watcher sz+	getsz = catchDefaultIO zeroBytesProcessed $+		toBytesProcessed <$> getFileSize f  data OutputHandler = OutputHandler 	{ quietMode :: Bool
doc/git-annex-adjust.mdwn view
@@ -4,7 +4,7 @@  # SYNOPSIS -`git annex adjust --unlock|--fix`+git annex adjust `--unlock|--fix`  # DESCRIPTION 
doc/git-annex-copy.mdwn view
@@ -14,14 +14,14 @@  * `--from=remote` -  Use this option to copy the content of files from the specified+  Copy the content of files from the specified   remote to the local repository.      Any files that are not available on the remote will be silently skipped.  * `--to=remote` -  Use this option to copy the content of files from the local repository+  Copy the content of files from the local repository   to the specified remote.  * `--jobs=N` `-JN`@@ -37,12 +37,15 @@  * `--fast` -  Avoid contacting the remote to check if it has every file when copying-  --to it.+  When copying content to a remote, avoid a round trip to check if the remote+  already has content. This can be faster, but might skip copying content+  to the remote in some cases.  * `--force` -  Force checking the remote for every file when copying --from it.+  When copying content from a remote, ignore location tracking information+  and always check if the remote has content. Can be useful if the location+  tracking information is out of date.  * `--all` 
doc/git-annex-group.mdwn view
@@ -4,7 +4,7 @@  # SYNOPSIS -git annex group `repository groupname`+git annex group `repository [groupname]`  # DESCRIPTION 
doc/git-annex-merge.mdwn view
@@ -12,6 +12,9 @@ that is done by the sync command, but without pushing or pulling any data. +When annex.resolvemerge is set to false, merge conflict resolution+will not be done.+ # SEE ALSO  [[git-annex]](1)
doc/git-annex-move.mdwn view
@@ -4,7 +4,7 @@  # SYNOPSIS -git annex move `[path ...] [--from=remote|--to=remote]`+git annex move `[path ...] [--from=remote|--to=remote|--to=here]`  # DESCRIPTION @@ -14,14 +14,17 @@  * `--from=remote` -  Use this option to move the content of files from the specified-  remote to the local repository.+  Move the content of files from the specified remote to the local repository.  * `--to=remote` -  Use this option to move the content of files from the local repository-  to the specified remote.+  Move the content of files from the local repository to the specified remote. +* `--to=here`++  Move the content of files from all reachable remotes to the local+  repository.+ * `--jobs=N` `-JN`    Enables parallel transfers with up to the specified number of jobs@@ -49,6 +52,18 @@ * `--key=keyname`    Use this option to move a specified key.++* `--fast`++  When moving content to a remote, avoid a round trip to check if the remote+  already has content. This can be faster, but might skip moving content+  to the remote in some cases.++* `--force`++  When moving content from a remote, ignore location tracking information+  and always check if the remote has content. Can be useful if the location+  tracking information is out of date.  * file matching options 
doc/git-annex-resolvemerge.mdwn view
@@ -12,9 +12,28 @@ file to the tree, using variants of their filename. This is done automatically when using `git annex sync` or `git annex merge`. -Note that only merge conflicts that involve an annexed file are resolved.-Merge conflicts between two files that are not annexed will not be-automatically resolved.+Note that only merge conflicts that involve one or more annexed files+are resolved. Merge conflicts between two files that are not annexed+will not be automatically resolved.++# EXAMPLE++Suppose Alice commits a change to annexed file `foo`, and Bob commits+a different change to the same file `foo`. ++Merging between them will then fail, and git will present the+merge conflict as a file `foo` pointing to one version of the+git-annex symlink, with `git status` indicating that `foo` has an+unresolved conflict.++Running `git annex resolvemerge` in this situation will resolve the merge+conflict, by replacing the file `foo` with files named like+`foo.variant-c696` and `foo.variant-f16a`. One of the files has the content+that Alice committed, and the other has the content that Bob committed.++The user can then examine the two variants of the file, and either merge+the two changes into a single file, or rename one of them back to `foo`+and delete the other.  # SEE ALSO 
doc/git-annex-sync.mdwn view
@@ -21,13 +21,9 @@ The content of annexed objects is not synced by default, but the --content option (see below) can make that also be synchronized. -Merge conflicts are automatically handled by sync. When two conflicting-versions of a file have been committed, both will be added to the tree,-under different filenames. For example, file "foo" would be replaced-with "foo.somekey" and "foo.otherkey".--Note that syncing with a remote will not update the remote's working-tree with changes made to the local repository. However, those changes+Note that syncing with a remote will not normally update the remote's working+tree with changes made to the local repository. (Unless it's configured+with receive.denyCurrentBranch=updateInstead.) However, those changes are pushed to the remote, so they can be merged into its working tree by running "git annex sync" on the remote. @@ -112,6 +108,18 @@   parallel. Pulls are not done in parallel because that tends to be   less efficient. When --content is synced, the files are processed   in parallel as well.++* `--resolvemerge`, `--no-resolvemerge`++  By default, merge conflicts are automatically handled by sync. When two+  conflicting versions of a file have been committed, both will be added +  to the tree, under different filenames. For example, file "foo" +  would be replaced with "foo.variant-A" and "foo.variant-B". (See+  [[git-annex-resolvemerge]](1) for details.)++  Use `--no-resolvemerge` to disable this automatic merge conflict+  resolution. It can also be disabled by setting annex.resolvemerge+  to false.  # SEE ALSO 
doc/git-annex.mdwn view
@@ -1040,6 +1040,15 @@   To configure the behavior in all clones of the repository,   this can be set in [[git-annex-config]]. +* `annex.resolvemerge`++  Set to false to prevent merge conflicts being automatically resolved+  by the git-annex assitant, git-annex sync, git-annex merge,+  and the git-annex post-receive hook.++  To configure the behavior in all clones of the repository,+  this can be set in [[git-annex-config]].+ * `annex.synccontent`    Set to true to make git-annex sync default to syncing content.
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 6.20170519+Version: 6.20170520 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <id@joeyh.name>